Qt-GUI冷冻 我用C++编写了8个益智游戏的解题器,现在我试着用Qt给它一个GUI。
基本上,我有一个类型为“Board”的底层对象,它代表拼图的棋盘,我将GUI组织为QPushButton的网格。然后我有一个方法updateUI,它根据电路板将正确的文本关联到每个按钮。差不多Qt-GUI冷冻 我用C++编写了8个益智游戏的解题器,现在我试着用Qt给它一个GUI。,c++,qt,user-interface,C++,Qt,User Interface,基本上,我有一个类型为“Board”的底层对象,它代表拼图的棋盘,我将GUI组织为QPushButton的网格。然后我有一个方法updateUI,它根据电路板将正确的文本关联到每个按钮。差不多 for(int i=0; i<Board::MATRIX_DIM * Board::MATRIX_DIM; i++) { m_buttons[i]->setText(m_values[i]); } 结果是GUI挂起,一段时间后,它只显示解决方案,完全跳
for(int i=0; i<Board::MATRIX_DIM * Board::MATRIX_DIM; i++)
{
m_buttons[i]->setText(m_values[i]);
}
结果是GUI挂起,一段时间后,它只显示解决方案,完全跳过移动
我错过了什么?谢谢大家!
另外,我认为我不需要为解算器设置不同的线程,因为我希望解算器在显示解算器之前运行。是否正确?您正在暂停主线程(它也执行事件处理)并使其无法响应键盘/鼠标/窗口消息 您应该使用异步计时器操作而不是睡眠功能:使用延迟来延迟显示下一个解决方案,并避免消息长时间未应答。实际上是
app.exec()
运行主循环,该循环处理所有事件,包括显示GUI。如果您想在此之前调用solve()
,这没关系,但如果您想在exec()
之前实际显示和更新GUI,这是错误的。我不确定这是否完全不可能,但这绝对不是正确的方法
有两种方法可以解决这个问题。更规范的方法是使用QTimer
重新设计程序。然后一切都会顺利进行,反应迅速。但这有时会很乏味。不过,对你来说,这应该很容易。只需将结果保存在某个地方,并每1000秒使用QTimer
对象调用一个插槽-它将与您的Sleep()
具有相同的效果,但将保持所有响应
另一种解决方案是在exec()
开始其作业后调用solveGUI()
方法。例如,可以使用QTimer::singleShot()
:
然后,在每次Sleep()
之前,您应该调用QApplication::processEvents()
,这基本上允许您临时屈服控制,处理所有挂起的事件,包括GUI更新。这种方法稍微容易一些,但它的性能较差,因为GUI仍然在每次Sleep()时冻结。例如,如果用户想要退出应用程序,或者如果需要重新绘制窗口,这将导致令人不舒服的GUI延迟。在处理循环过程中有一个很好的选择。如果我认为这不是一个复杂的情况,只需插入QCoreApplication::processEvents()代码>在长处理循环中 尝试以下操作:
void MainWindow::Wait(int interval ) {
QTime timer = new QTime;
timer.restart();
while(timer.elapsed() < interval) {
QApplication::processEvents();
}
}
...
for(...) {
//wait 1 second (1000 milliseconds) between each loop run at first
Wait(1000);
...
}
...
void主窗口::等待(整数间隔){
QTime定时器=新的QTime;
timer.restart();
while(timer.appeased()
尚未测试-但应该可以工作(可能有一些cpu负载) UI是基于事件的(这涉及到操作系统级别,不是Qt)。你需要重新设计你的求解函数,这样它就可以在求解后立即返回,而不是休眠;然后你可以设置一个计时器(它在UI线程上提供事件)来一次显示一个移动,而不占用UI线程。不知道我是否理解你关于重新设计我的求解函数所说的话。。。它所做的基本上是扩展搜索树的节点,直到它达到目标,并且它可以工作:平均只需要几毫秒。然后,在这之后,我想开始展示这些动作。我指的是您的solveGUI
方法,很抱歉造成混淆。好的,如果需要更多帮助,我会尝试发回。谢谢不要使用睡眠
。改用QTimer
。
QApplication app(argc, argv);
MainWindow w;
w.show();
w.solveGUI();
return app.exec();
QTimer::singleShot(0, &w, SLOT(showGUI()));
return app.exec();
void MainWindow::Wait(int interval ) {
QTime timer = new QTime;
timer.restart();
while(timer.elapsed() < interval) {
QApplication::processEvents();
}
}
...
for(...) {
//wait 1 second (1000 milliseconds) between each loop run at first
Wait(1000);
...
}
...