Qt5:如何在进行大计算时重新绘制

时间:2014-01-21 08:29:34

标签: c++ qt widget exec qt5

我正在Qt5编写一个数学模拟器,当我点击一个按钮时,需要进行一些繁重的计算。在此期间,我想显示一个Please, wait窗口,最终显示一个进度条。最好不要使用线程。

问题是,在计算过程中应用程序挂起,事件未被处理,please, wait窗口应该只是一个没有任何内容的窗口框架(看起来是透明的)。

PC: AMD X2 L325, 2GB RAM, Radeon E4690
OS: Debian 6 (Squeeze, Old stable)
gcc 4.4.5, Qt 5.2.0

任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:2)

虽然你可以调用QApplication :: processEvents,但这不是最好的方法。 如果你因为对你不熟悉而避开线程,那么一旦你完成它,我相信你会发现它更容易。 Qt让事情变得简单。

您需要做的就是创建一个派生自QObject的类来进行计算。接下来,创建一个线程并调用该对象的moveToThread函数。然后用一些信号和插槽控制线程。这就是它的全部内容。

我建议您阅读this article,而不是重复此处的内容,它会详细解释并提供简洁明了的示例代码。

从处理计算的新对象中,它可以向主线程上的插槽发出信号,这将更新“请等待”窗口的进度。

请注意,小部件和所有渲染必须在主线程上完成。

答案 1 :(得分:0)

我更喜欢使用Qt Concurrent。它没有很好的文档记录,但非常方便,比直接使用QThread要好得多。

我通常做的事情就是我有单独的QObject for logic,在那里有一些调用繁重计算的插槽(参见run documentation):

void MyCalculationClass::startCalculating() {
    QtConcurent::run(this, &MyCalculationClass::doHeavyCalculation);
}

方法doHeavyCalculation发出带有进度和计算结果的信号 通常,此方法对其自己的数据进行操作,而不是由其他线程/方法修改,因此如果需要同步,则这是微不足道的。 Signal-Slot机制正在处理大多数多线程问题(请注意,默认连接检测到信号是从其他线程发出的,并在适当的线程中对插槽进行排队,默认情况下会自动完成)。

答案 2 :(得分:0)

我有这样的问题,我这样解决它,我在另一个线程中进行计算(我使用QThread的std :: thread instad)在我开始计算之前我只是启动计时器

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(repaint()));
timer->start(1);

然后

std::thread t(&Widget::calcBackgound, this);
t.detach();

答案 3 :(得分:0)

您可以将代码中繁重且耗时的部分放在继承自run()的另一个类的QThread成员函数中。之后,创建一个新类的实例,并简单地调用它的start()函数。 您的新班级可以有一个发出当前进度值的信号。然后,您可以将此信号连接到进度条的插槽。