我正在用Qt(C++)编写一个应用程序,我有一个while循环,依赖于某个布尔变量,该变量在开始时被设置为true,当主部件析构函数被调用时,它被设置为false,以便在主部件关闭时中断循环。
下面是重现上述情况的示例代码。
//testwidget.h
#include <QWidget>
#include <QPushButton>
#include <QApplication>
#include <QLayout>
class testWidget : public QWidget
{
Q_OBJECT
public:
testWidget(QWidget* parent = nullptr);
~testWidget();
QPushButton* button;
QApplication* application;
QHBoxLayout* layout;
bool run;
public slots:
void start();
};
。
#include "testwidget.h"
testWidget::testWidget(QWidget* parent) : QWidget(parent)
{
run = true;
application = static_cast<QApplication*>(QApplication::instance());
button = new QPushButton("BUTTON");
layout = new QHBoxLayout(this);
layout->addWidget(button);
connect(button, SIGNAL(clicked()), this, SLOT(start()));
}
void testWidget::start()
{
while(run)
{
application->processEvents();
}
}
testWidget::~testWidget()
{
run = false;
}
。
#include <QApplication>
#include "testwidget.h"
int main(int argc, char *argv[ ])
{
QApplication app(argc, argv);
testWidget w;
w.show();
return app.exec();
}
所以当我点击按钮时,循环就开始了。但是如果我关闭小部件(点击“X”关闭按钮),程序就会继续运行(即使小部件消失了)。
因此,如果循环没有开始,程序正常关闭。
因此,如果循环正在运行,则不调用析构函数。
这可能取决于processEvents()方法跳过了析构函数的调用,但如何以干净的方式修复它呢?
目前我已经使用this->setAttribute(Qt::WA_DeleteOnClose);
“解决”了它,但这是一种强迫。
1条答案
按热度按时间yjghlzjz1#
通过对槽使用无限阻塞函数
你基本上阻塞了由
app.exec();
启动的事件循环,然后你解决了对application->processEvents();
的恶意调用。processEvents
确实会处理其他信号(小部件几何形状,点击X等),但是由于QPushButton::clicked
触发的插槽永远不会返回,app.exec();
也不会,这导致了你的小部件永远不会被破坏的情况。将事件处理逻辑留给Qt,如果你想启动一些异步操作,比如帧捕获,在一个单独的线程中完成,然后立即从你的Slot返回。
注意在你的异步函数中你不应该接触任何GUI元素。如果你想显示一个帧,发送信号让你的小部件知道它准备好了,并在主线程中显示它(连接的插槽将被主事件循环触发)。