我正在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
任何帮助将不胜感激!
答案 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()
函数。
您的新班级可以有一个发出当前进度值的信号。然后,您可以将此信号连接到进度条的插槽。