QDialog не может быть закрыт на Windows, но не на MacOS / - PullRequest
0 голосов
/ 06 января 2020

У меня есть диалог в Qt5 (C ++). Вы можете видеть, что диалоговое окно просто создает некоторые виджеты (VisGLWidget из QOpenGLWidget) и продолжает обновлять его.

#include "visualizationdlg.h"
#include "ui_visualizationdlg.h"

VisualizationDlg::VisualizationDlg(QWidget *parent, NewtonSpace *data) :
    QDialog(parent),
    ui(new Ui::VisualizationDlg)
{
    ui->setupUi(this);
    this->setFixedSize(600,600);

    this->data = data;
    this->visualizationGL = new VisGLWidget(this, this->data);
    this->visualizationGL->setObjectName(QString::fromUtf8("visualizationGL"));
    this->visualizationGL->setGeometry(QRect(10, 50, 581, 541));
    this->visualizationGL->repaint();

    this->rePaintTimer = startTimer(1);
}

VisualizationDlg::~VisualizationDlg()
{
    delete ui;
}

void VisualizationDlg::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == this->rePaintTimer) {
        this->data->update(ui->GInput->value(), ui->updateSpdInput->value());
        this->visualizationGL->repaint();

        this->rePaintTimer = startTimer(1);
    }
}

Вопрос в том, что я могу выйти из этого диалогового окна, нажав крестик на MacOS, но не в Windows. Что с ним не так?

PS: Исходный код можно найти здесь .

1 Ответ

0 голосов
/ 06 января 2020

В вашем конструкторе VisualizationDlg у вас есть ...

this->rePaintTimer = startTimer(1);

Это приведет к отправке QTimerEvent в ваш экземпляр VisualizationDlg раз в миллисекунду (потенциально).

Теперь рассмотрим код, который обрабатывает события таймера ...

void VisualizationDlg::timerEvent (QTimerEvent *event)
{
    if(event->timerId() == this->rePaintTimer) {
        this->data->update(ui->GInput->value(), ui->updateSpdInput->value());
        this->visualizationGL->repaint();

        this->rePaintTimer = startTimer(1);
    }
}

При первом вызове этого идентификатора, связанного с событием таймера, будет совпадать rePaintTimer. Следовательно, repaint будет называться. Но затем вы запускаете новый таймер и присваиваете его идентификатор rePaintTimer без остановки исходного таймера. Теперь у вас есть два таймера, каждый из которых генерирует события с частотой 1 кГц, но ваш обработчик событий воздействует только на события из самого последнего созданного таймера.

Теперь подумайте, чем это станет через несколько секунд. У вас могут быть тысячи таймеров, каждый из которых генерирует события с частотой 1 кГц.

Удалите строку ...

this->rePaintTimer = startTimer(1);

из обработчика событий, чтобы сделать его ...

void VisualizationDlg::timerEvent (QTimerEvent *event)
{
    if(event->timerId() == this->rePaintTimer) {
        this->data->update(ui->GInput->value(), ui->updateSpdInput->value());
        this->visualizationGL->repaint();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...