当运行long-for循环的小部件(QDialog)在没有多线程的情况下关闭时,我如何停止它
How can I stop a long for loop when the widget (QDialog) running it is closed without multithreading?
我在QDialog中有一个相当长的foreach循环。基本上看起来是这样的:
foreach (xxx, xxx) {
... doSomeStuff ...
QApplication::processEvents();
if (m_cancelMapLoading) {
break;
}
}
通过单击"取消"按钮将m_cancelMapLoading设置为true。QApplication::processEvents();使这成为可能。
这可以很好地工作,但如果只要foreach循环仍在运行,对话框就会关闭,它就会继续运行。我试图在关闭对话框的每个函数中将m_cancelMapLoading设置为true,但这无济于事。
我还尝试测试m_cancelMapLoading是否为true,以及isVisible()是否为true。这实际上停止了对话框,但它在没有GUI元素的情况下立即重新打开对话框
不幸的是,QtConcurrent::run等不能用于该函数,因为foreach循环操作的数据结构不是线程安全的。
有什么方便的方法可以解决这个问题吗?
您可以在此处使用QTimer和Qt的父子结构。超时值为零的QTimer在Qt 中具有特殊意义
作为一种特殊情况,超时为0的QTimer将尽快超时因为窗口系统的事件队列中的所有事件已处理。这可以用来做繁重的工作,同时提供快速用户界面:
所以你可以做一些类似的事情
void Dialog::beginDoingStuff()
{
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(processData());
m_timer->start(0);
}
void Dialog::processData()
{
// Perform one cycle of your process here
}
这将在与对话框其余部分相同的线程中执行processData()函数,当对话框因关闭而被破坏时,计时器将被删除(因为它的父级是对话框),这意味着处理将停止。
从繁重的处理中卸载GUI的一个好而简单的方法是将其分配给另一个线程或QtConcurrent。
然后,您可以轮询"should-I-terminate-yet?"变量,或者在不再需要时手动终止线程。
我强烈建议并行处理,因为它提供了更好的控制,而不是像"DoEvents"那样清空队列。
我们实际上通过将对话框的完成信号连接到取消按钮的点击槽来解决了这个问题。这实际上在所有情况下都会停止循环。
我们还引入了通过QTimer启动函数(为了更好地实现,不阻塞函数启动的地方),但这并不能停止循环(也许是因为我们不会在对话框关闭时破坏它)。
感谢所有帮助:-)
- 给定使用 C++ 或 C,我如何测量在 linux 下进行线程切换需要多长时间?可能吗?
- C++ POCO - 如何在不使用 run() 方法的情况下启动线程池上的线程?
- Visual Studio 发布模式阻止在调试模式下执行的代码.使用 WinHTTP 和多线程
- Vulkan默认情况下已经有多线程了吗
- 多线程程序卡在优化模式下,但在 -O0 中正常运行
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 如何在不同步的情况下创建线程本地内存
- C++ 今天的多线程,C++ 11 的不稳定情况 - 书籍建议
- 使用多线程来模拟这种情况的好方法是什么
- 如何在没有条件变量的情况下阻止线程中的操作,并在Linux中根据信号恢复操作
- 如何在不将类数据成员作为参数传递的情况下访问线程中的类数据成员
- 如何改进此代码以便在多线程环境下运行
- 如何在不使用的情况下在 <mutex>C++11 中实现多线程安全单例
- 矢量自动调整大小在多线程代码中是否是一种危险情况
- 多线程服务器在不等待客户端连接的情况下退出
- 当运行long-for循环的小部件(QDialog)在没有多线程的情况下关闭时,我如何停止它
- 在各种情况下的线程清理
- 在发生异常的情况下关闭线程
- 如果已知访问顺序是安全的,如何在没有互斥锁的情况下同步线程/CPU
- 在不使用条件变量的情况下唤醒线程的最快方法