0

我有一个设计问题一直困扰着我很长一段时间。本质上,我有一个需要很长时间才能执行的功能和一个需要响应和最新的 gui。当用户点击开始按钮时,long 函数开始在 while 循环中执行,并且在每次执行后需要更新 gui。

我在想最好的方法是让 QThread 在 while 循环中运行,如果用户按下开始按钮,long 函数将开始执行。类似于以下内容:

class Application : public QThread
{
    void run (void)
    {
        while (!mExiting)
        {
            if (StartPressed)
                LongFunction();

            // Need to update gui before
            // running long function again
        }
    }
}

我尝试使用 BlockingQueuedConnection 执行 QMetaObject::Invoke 但是,当 gui 应用程序退出时,线程被卡住并且永远不会退出。我也尝试使用 QMutex,但是,gui 将被锁定,等待被锁定并由 long 函数使用的互斥锁。

我在想,当应用程序想要退出时,是否有任何方法可以取消 BlockingQueuedConnection,或者是否有其他方法可以实现这一点。

4

1 回答 1

1

你很接近,但你不需要继承自QThread. 反而:

  1. 将您的计算放入QObject.

  2. 将设置退出标志的代码放入另一个插槽(例如Q_SLOT void finish();

  3. 创建对象的实例。创建一个QThread. 打电话myObject->moveToThread(myThread)

  4. 启动线程。

  5. 将 gui 信号连接到计算对象中的插槽,类似地连接计算对象中指示数据准备好的信号。

  6. 要结束处理并完成线程,假设gui发送一个stop()信号,设置以下连接:

    1. connect(gui, SIGNAL(stop()), myObject, SLOT(finish())- 停止你的计算

    2. connect(gui, SIGNAL(stop()), myObject->thread(), SLOT(quit()))- 结束线程中的事件循环

    3. connect(myObject->thread(), SIGNAL(finished()), myObject->thread(), SLOT(deleteLater())run()- 当方法返回时删除线程

    myObject当您完成从中获取结果时,或者至少在您的应用程序退出之前,您仍然需要删除。

警告delete myObject:如果您从 gui 线程执行此操作并且不为零,则这是一个错误myObject->thread():您不能删除具有与当前线程不同的线程亲和性的对象。零线程亲和性意味着没有线程声明对象 - 在我们的例子中,当对象的线程被破坏时。然后任何线程都可以删除它。

出于同样的原因,您不能moveToThread创建具有父对象的对象。您移动的对象可以有子对象,但它本身不能有父对象。

于 2013-10-13T00:50:02.860 回答