不调用QApplication::exec(),是否可能创建本地事件循环?

9

我想基于 QTcpServerQTcpSocket 创建一个库,以供那些在其 main 函数中没有事件循环的程序使用(因为Qt事件循环是阻塞的,并且不能提供足够的时间分辨率来执行实时操作)。

我希望通过在类内部创建本地事件循环来解决这个问题,但是除非我首先在主函数中调用了 app->exec(),否则它们似乎不起作用。是否有一种方法可以创建本地事件循环,并允许在线程内进行信号/槽通信,而不需要应用级别的事件循环?

我已经查看了是否有一种方法可以在不使用QApplication :: exec()的情况下使用Qt? 但该答案并没有帮助,因为它似乎添加了一个本地事件循环,但没有删除应用程序循环。


创建一个新线程,其中包含QApplication::exec()并将其保持为“主线程”? - ratchet freak
我会试一试。唯一的缺点是,即使它能够正常工作,它可能会阻止我在将来的实际Qt应用程序中使用该库,因为你肯定不能有两个对QApplication :: exec的调用。 - Nicolas Holthaus
1个回答

11

你可以在库中的新线程中创建QCoreApplication实例。你应该检查只创建一个实例,因为每个Qt应用程序应该只包含一个QCoreApplication

class Q_DECL_EXPORT SharedLibrary :public QObject    
{
Q_OBJECT
public:
    SharedLibrary();

private slots:

    void onStarted();

private:
    static int argc = 1;
    static char * argv[] = {"SharedLibrary", NULL};
    static QCoreApplication * app = NULL;
    static QThread * thread = NULL;
};


SharedLibrary::SharedLibrary()
{
    if (thread == NULL)
    {
        thread = new QThread();
        connect(thread, SIGNAL(started()), this, SLOT(onStarted()), Qt::DirectConnection);
        thread->start();
    }
}
SharedLibrary::onStarted()
{
   if (QCoreApplication::instance() == NULL)
   {
       app = new QCoreApplication(argc, argv);
       app->exec();
   }
}  

这样你就可以在非Qt应用程序中使用你的Qt共享库。


1
可能需要在检查和启动循环时进行同步。 - ratchet freak
3
这句话的意思是“对于检查 QCoreApplication::instance() 的操作,这值得再加一个 +1(即表示非常赞赏)”。 - Nicolas Holthaus
QCoreApplication应该在主线程上创建。请参见https://dev59.com/kobca4cB1Zd3GeqPcO5t。 - Alex Wade
2
@AlexWade你提到的帖子并没有说明QCoreApplication应该在主线程上创建。要解决警告问题,需要让SharedLibrary不再继承自QObject,并在构造函数中创建QCoreApplication实例即可。 - Nejat
@Nejat 没错。在实例化 QCoreApplication 之前不应该创建其他 QObjects。可以使用 std::thread 来创建主线程,而不是使用 QThread。 - Alex Wade
如果有人能在PyQt中实现相同的事情,我会很高兴在这里得到回复:https://stackoverflow.com/questions/73913518/start-pyqt-application-without-blocking-main-thread - Simon Fischer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接