Qt - GUI freezing
Qt - GUI freezing
我用C++为8拼图游戏编写了一个求解器,现在我正试图使用Qt为它提供一个GUI。
基本上,我有一个类型为"Board"的底层对象,它表示谜题的板,并且我将GUI组织为QPushButton的网格。然后我有一个方法updateUI,它根据Board将正确的文本关联到每个按钮。类似的东西
for(int i=0; i<Board::MATRIX_DIM * Board::MATRIX_DIM; i++)
{
m_buttons[i]->setText(m_values[i]);
}
在另一种方法(solveGUI)中,我有
void MainWindow::solveGUI()
{
m_game->solve();
int solutionDepth = m_game->getSolutionDepth();
Move *solutionMoves = m_game->getSolutionMoves();
for(int i=0; i<solutionDepth; i++)
{
Move m = solutionMoves[i];
m_board.performMove(m); /* perform the move on the Board object */
updateUI(); /* should update the GUI so that it represents the Board */
Sleep(1000);
}
}
其中第一行(m_game->solve)需要一些时间。然后,我获得了解决方案moves中执行的动作列表,我想做的是在棋盘上显示这些动作,在一个动作和下一个动作之间有一些延迟。这个方法是由我的main调用的,看起来像这样:
QApplication app(argc, argv);
MainWindow w;
w.show();
w.solveGUI();
return app.exec();
结果是GUI挂起,一段时间后,它只显示解决方案,完全跳过移动。
我错过了什么?非常感谢。
附言:我认为解算器不需要其他线程,因为我希望解算器在显示解决方案之前运行。对吗?
实际上是app.exec()
运行处理所有事件(包括显示GUI)的主循环。如果您想在此之前调用solve()
,这是可以的,但如果您想在exec()
之前实际显示和更新GUI,这是错误的。我不确定这是否完全不可能,但这绝对不是正确的方法。
有两种方法。更规范的方法是使用QTimer
重新设计程序。然后一切都会很顺利,反应灵敏。但这有时会很乏味。不过,在你的情况下,这应该很容易。只需将结果保存在某个地方,并每1000秒使用QTimer
对象调用一个插槽——它将具有与Sleep()
相同的效果,但会使所有内容都保持响应。
另一种解决方案是在exec()
启动其作业后调用solveGUI()
方法。例如,可以使用QTimer::singleShot()
:
QTimer::singleShot(0, &w, SLOT(showGUI()));
return app.exec();
然后,在每次Sleep()
之前,您应该调用QApplication::processEvents()
,这基本上允许您临时进行屈服控制,处理所有挂起的事件,包括GUI更新。这种方法稍微简单一些,但由于GUI仍然在每个Sleep()
处冻结,因此它的性能较差。例如,如果用户想要退出应用程序,或者需要重新绘制窗口,这将导致不舒服的GUI滞后。
您正在暂停主线程(它还负责事件处理),并使其无法响应键盘/鼠标/窗口消息。
您应该使用异步计时器操作而不是睡眠功能:使用QTimer来延迟显示下一个解决方案,并避免消息长时间未得到答复。
有一篇很好的方法文章可以让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);
...
}
...
尚未测试-但应该可以工作(可能有一些cpu负载)!
- C++GTKMM gui循环依赖关系
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 在哪里放置我的函数?进入我的母语 Gui 还是进入我的演示者?
- 如何在带有 gdb GUI 前端的 ARM gdbserver 的 PC 上执行远程 gdb 会话?
- 在 Gui Win32 中创建子窗口C++
- 如何防止 std::thread 在 QT 中冻结 GUI?
- Qt - QQuickWidget setSource without freezing UI
- 调试控制台 ChessEngine.exe "used"在另一个应用程序(国际象棋 GUI)中
- 更改 Windows GUI 中静态文本框的字体大小
- 我不知道如何使用代码块win32 gui
- Qt GUI使用Qfiledialogbox和qlabel显示视频,这是我的代码
- QtConcurrent - 在发布到 UI 线程的数千个结果中保持 GUI 响应
- 德尔福在回调中出现 GUI 问题
- 从 GUI 文件资源管理器执行程序,并且不生成终端
- 线程和 GUI 处理
- C++ WinAPI[GDI].自定义 gui 正确重绘
- Qt,操作缓慢时不要冻结GUI输入元素
- GCP 或 AWS 是否支持 C++ 和 GUI 应用程序开发?
- Qt - GUI freezing