gpt4 book ai didi

c++ - 本地 QEventLoop 是如何工作的

转载 作者:行者123 更新时间:2023-11-30 01:37:03 25 4
gpt4 key购买 nike

我的问题很笼统,与 QT 中类 QEventLoop 的使用有关。我有两个主要问题。

问题 1) 它在 QT 内部如何工作(我主要关心的是为什么执行 QEventLoop 对象不会阻塞 QT 应用程序主循环 - [编辑 3] 最后一条评论不正确,请参阅下面的答案)。
详情请见下文。

问题 2) 除了阻塞之外还有其他目的吗?看来我只能遇到 QEventLoop 用于等待目的的示例。
它可以用于其他目的吗?就像我们可以想象将特定事件的处理从主应用程序循环委托(delegate)给本地 QEventLoop 吗? (不确定这个问题是否有意义)

问题 1 的发展):

我对 QT 主事件循环基本工作原理的理解如下。应用程序主事件循环 (QCoreApplication::exec()) 从队列中获取一个 QEvent “E”,并将其分派(dispatch)给 QObject “A”决定了事件的去向(例如,在按下鼠标左键的情况下,QWidget 的位置和 Z 值)。如果我们假设对象“A”正在使用事件“E”,则调用该对象的事件方法(还有其他方便的方法和事件过滤器,但我们假设事件方法在我们的例子中处理事件)——一些处理与对象“A”相关的发生在这里 - 并返回 true。然后,QT 主事件循环开始处理队列中的下一个事件,依此类推。

但是,IF 在对象“A”的事件方法的调用中有一些阻塞,我希望主应用程序循环被阻塞,因为它等待对象“A”的事件方法接收者(对象“A”)返回...
因此,例如,如果事件的处理最终调用了对象“A”的方法,我们在其中创建了一个我们永远不会退出的本地QEventLoop,我的期望是整个应用程序停止并且没有更多事件被处理,直到本地QEventLoop退出,对象“A”的事件方法返回。
否则,这不是真的,因为我可以看到本地 QEventLoop 没有阻塞应用程序主事件循环...
有人可以让我更深入地了解本地 QEventLoop 的工作原理吗?[EDIT 3] 查看下面的答案,本地事件循环处理事件

---- 编辑 1 ----

很抱歉,如果我不清楚,这实际上很难用语言解释,所以下面是一个小代码片段,可以更好地说明我的问题 1

主窗口.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

主窗口.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)到它们通常的位置。

您提供的代码无法结束循环。没有什么可以阻止您再次单击 button2,并在当前运行的两个循环(第一个 loop 和主 QApplication 循环)中有另一个 loop .

如果您将调试器附加到您的进程,您将看到每个正在运行的循环的堆栈帧

关于c++ - 本地 QEventLoop 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50450912/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com