英文:
A QDialog can't be exited on Windows, but not on MacOS/
问题
我在Qt5(C ++)中有一个对话框。您可以看到,该对话框只是创建了一些小部件(来自QOpenGLWidget的VisGLWidget),并不断更新它。
问题是,我可以在MacOS上点击交叉按钮退出此对话框,但在Windows上却不能。出了什么问题?
#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上却不能。有什么问题?
英文:
I have a dialog in Qt5(C++). You can see that the dialog just creates some widgets (VisGLWidget
from QOpenGLWidget
) and keeps updating it.
#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);
}
}
The question is, I can quit this dialog by clicking the cross on MacOS, but not on Windows. What's wrong with it?
答案1
得分: 0
在你的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);
}
}
第一次调用此函数时,与定时器事件关联的id将匹配rePaintTimer
。因此,repaint
将被调用。但是然后你启动了一个新的定时器并将其id分配给rePaintTimer
,而不停止原始定时器。现在你有两个定时器,每个都以1KHz生成事件,但你的事件处理程序只对最新创建的定时器生成的事件做出反应。
现在考虑一下这个问题在几秒钟后会变成什么样。你可能会有成千上万个定时器,每个都以1KHz生成事件。
从你的事件处理程序中移除以下代码:
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();
}
}
英文:
In your VisualizationDlg
constructor you have...
this->rePaintTimer = startTimer(1);
That will result in a QTimerEvent
being sent to your VisualizationDlg
instance once every millisecond (potentially).
Now consider the code that handles timer events...
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);
}
}
The first time this is invoked the id associated with the timer event will match rePaintTimer
. Hence repaint
will be called. But you then start a new timer and assign its id to rePaintTimer
without stopping the original timer. You now have two timers each generating events at 1KHz but your event handler only ever acts on events from the most recently created timer.
Now think what this will become after even a few seconds. You could potentially have thousands of timers each generating events at 1KHz.
Remove the line...
this->rePaintTimer = startTimer(1);
from your event handler to make it...
void VisualizationDlg::timerEvent (QTimerEvent *event)
{
if(event->timerId() == this->rePaintTimer) {
this->data->update(ui->GInput->value(), ui->updateSpdInput->value());
this->visualizationGL->repaint();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论