gpt4 book ai didi

c++ - QApplication::processEvents 在不同的线程上

转载 作者:行者123 更新时间:2023-11-27 23:45:23 27 4
gpt4 key购买 nike

我有几个问题。

  1. 是否可以在一个线程上初始化 QApplication 对象并在另一个线程上销毁它?

  2. 为什么 QApplication 必须在分配它的同一线程上运行?

  3. 是否可以在创建 QApplication 对象的不同线程上运行 QApplication::processEvents()?如果调用 processEvents 的线程是非 QT 线程,这会起作用吗?

最佳答案

  1. 这可能是可行的,但 Qt 尚未针对它进行测试。我想有可能破解它 - 你需要更改代码。它永远不会在 MacOS 上运行,除非您只考虑 QCoreApplication - QApp..QGuiApp.. 都不支持该平台上的其他线程,也可能在其他平台上(Windows 除外)。不过,我不知道你为什么要那样做。一旦 QApplication 事件循环在给定线程上运行,它可以根据命令终止并自动销毁应用程序实例。事实上,这很简单:

    int main(int argc, char *argv[]) {
    QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));
    QtConcurrent::run([]{
    // this runs in a worker thread, and causes the application
    // object to destroy itself and then the program to exit
    QThread::sleep(2);
    QCoreApplication::quit();
    });
    auto rc = app.exec();
    app.reset();
    // perhaps do some other processing here that doesn't need
    // a qApp instance
    return rc;
    }
  2. 为什么不呢? QApplication 根本不需要“运行”,所以谁在乎呢?您可以在任何线程上运行事件循环,而主线程中的事件循环根本不需要运行,除非您在主线程中有一些要将事件传递到的对象。主线程中的事件循环很特殊,因为这是唯一支持 QWidget 实例的事件循环。这是 Mac OS 的限制,所以如果你想编写可移植代码,你只能在主线程上实例化 QApplication(即调用时有 int main() 的东西)堆栈)。

  3. 是的,但需要注意的是,它并不像您认为的那样。 QCoreApplication::processEvents的含义是“清空当前线程的事件队列”。在 Qt 中,事件循环是每线程资源。您可以在任何线程上运行事件循环 - 事实上,QThread::run 正是这样做的:它的 run() 本质上是 QEventLoop()。执行()

    而且你只能清空你所在线程的事件循环,因为没有提供任何其他事件循环的访问权限——这是没有意义的:“清空”一个事件队列意味着在线程中调度事件在该队列上运行的事件循环,当你在任何给定线程中执行时,你根据定义不会在其他线程中执行代码,因此不能耗尽那里的事件队列。 QCoreApplication::processEvents等同于QAbstractEventDispatcher::instance()->processEvents(),其中instance()是事件分发器实例当前线程。

    现在您可能会说:但是嘿,如果我们可以获取属于某个其他线程的事件队列数据,并在另一个线程中调用所有这些 QObject::event 方法呢?这不仅不是为永远工作而设计的,您可能只是在内部 Qt 互斥体上陷入僵局,这就是它的结束。无论如何,这没有意义。在大多数平台上,您可以向任何线程发送等效的可中断 sleep 信号,并在该信号中注入(inject)要执行的代码 - 即 QCoreApplication::processEvents。在 Windows 上,您会为此使用 APC,在 Unix 上,它会是信号和其他智能代码的某种组合。可以通过进行堆栈检查来确定上下文是否安全,以及如果安全则执行不允许的操作,从而在一定程度上模拟 APC。

    没有所谓的“非 Qt”线程。根据定义,线程是一种平台资源。 QThread 不是“Qt”线程。它是平台线程资源的句柄。更好的是:它是一个在需要时自动创建的句柄,因此您始终可以引用当前线程,即使您的代码之前没有明确创建这样的句柄。

也许您需要告诉我们您正在尝试做什么。您的问题中缺少一些非常基本的东西。

关于c++ - QApplication::processEvents 在不同的线程上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51128131/

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