我的问题很笼统,并且与QT中使用类QEventLoop有关。我有两个主要问题。
问题1)在QT内部如何工作(我主要关心的是为什么QEventLoop对象的执行不会阻塞QT应用程序主循环- [EDIT 3]最后一条评论不正确,请参见下方的答案)。
有关详情,请参见下文。
问题2)除了阻止以外,还有其他目的吗?看来我只能遇到QEventLoop用于等待目的的示例。
可以用于其他目的吗?就像我们可以想象将特定事件的处理从主应用程序循环处理到本地QEventLoop一样吗? (不确定这个问题是否有意义)
问题1)的发展:
我对QT主事件循环基本如何工作的理解如下。应用程序主事件循环(QCoreApplication::exec())从队列中获取一个QEvent“E”,并将其分派(dispatch)给QObject“A”,它决定事件将到达(例如,位置和Z值)。如果是鼠标左键,则为QWidget)。如果我们假设对象“A”正在使用事件“E”,则调用该对象的事件方法(还有其他便捷方法和事件过滤器,但假设在我们的案例中事件方法处理事件)-进行了一些处理与对象“A”相关的事件在此处发生-并返回true。然后,QT主事件循环开始处理队列中的下一个事件,依此类推。
但是,如果在对象“A”的事件方法的调用中有某些阻塞,我希望主应用程序循环被阻塞,因为它等待接收方(对象“A”)的事件方法返回...
因此,例如,如果事件的处理最终调用了对象“A”的方法,我们在其中创建了一个我们永远不会退出的本地QEventLoop,那么我的期望是整个应用程序都将停止并且不再处理任何事件,直到退出本地QEventLoop,然后返回对象“A”的事件方法。
否则,这是不正确的,因为我可以看到本地QEventLoop不会阻止应用程序主事件循环...
有人可以给我更多有关本地QEventLoop如何工作的见解吗?
[编辑3]参见下面的答案,本地事件循环处理事件
----编辑1 ----
很抱歉,如果我不清楚,这实际上很难用单词来解释,因此下面是一个小代码段,可以更好地说明我的问题1 。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QPushButton>
#include <QEventLoop>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPushButton* button1 = new QPushButton(this);
button1->setText("button 1");
button1->setCheckable(true);
QPushButton* button2 = new QPushButton(this);
button2->setText("button 2");
button2->move(0,50);
connect(button1,&QPushButton::toggled,button1,[button1](bool toggled){
button1->setText(toggled ? "CHECKED" : "NOT CHECKED");
});
connect(button2,&QPushButton::clicked,button2,[](){
QEventLoop loop;
qInfo() << "Before loop exec";
loop.exec();
qInfo() << "After loop exec";
});
}
MainWindow::~MainWindow()
{
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
在上面的示例中,我有一个带有2个按钮的简单窗口,“按钮1”(显示其状态:选中或未选中)和“按钮2”(单击时触发本地QEventLoop)。
当我单击按钮2时,它在“loop.exec()”处阻塞,即从不输出第二条调试消息。然后,我希望主应用程序循环也将被阻止,但是,我不认为这是因为我仍然可以单击“按钮1”,该按钮显示其状态(选中或未选中),这意味着鼠标事件是仍由主应用程序事件循环处理。
最佳答案
否,事件不会由QApplication主循环处理。它们由loop
处理,并分派(dispatch)到通常的地方。
您提供的代码无法结束loop
。没有什么可以阻止您再次单击button2
,并在当前运行的两个应用程序(第一个loop
和主QApplication循环)中包含另一个loop
。
如果将调试器附加到进程,则将看到正在运行的每个循环的堆栈框架
关于c++ - 本地QEventLoop如何工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50450912/