在我的程序中,我打开一个窗口并运行一个大循环。我在QTextEdit
中显示进度。我添加了一个取消按钮来停止大循环。
所以在窗口构造函数中我运行一个看起来像
的方法void start()
{
for (size_t i=0, i<10000000; ++i)
{
// do some computing
QApplication::processEvents(); // Else clicking the stop button has no effect until the end of the loop
if (m_stop) break; // member m_stop set to false at start.
}
}
因此,当我点击停止按钮时,它会运行插槽
void stopLoop()
{
m_stop = true;
}
该方法的问题在于processEvents()
会稍微减慢执行时间..但也许这是不可避免的..
我想尝试使用信号和插槽,但我似乎无法想到如何将推送的停止按钮与循环连接。
或者,信号和插槽与否,也许某人有更好的方法来实现这一目标?
修改
遵循此线程建议,我现在有一个工作者/线程方案。所以我有一个窗口构造函数
Worker *worker;
QThread *thread ;
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(work()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
这似乎工作得很好。但是我怎么能现在引入QTimer
?
我应该将QTimer
连接到主题的start()
功能
connect(timer, &QTimer::timeout, thread, &QThread::start);
或者,我应该将线程连接到QTimer
的{{1}}功能吗?
start()
或者不是......但是,那怎么样?
答案 0 :(得分:2)
使用QTimer
void start()
{
this->timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MyObject::work);
connect(stopbutton, &QButton::clicked, timer, &QTimer::stop);
connect(stopbutton, &QButton::clicked, timer, &QTimer::deleteLater);
connect(this, &MyObject::stopTimer, timer, &QTimer::deleteLater);
connect(this, &MyObject::stopTimer, timer, &QTimer::stop);
timer->setInterval(0);
timer->setSingleShot(false);
timer->start();
}
void work()
{
//do some work and return
if (done)emit stopTimer();
}
答案 1 :(得分:1)
你可以做的更少“块状”的事情是使用QThread
在工作线程中完成你的工作。然后,减速不再是一个大问题,而你仍然可以优雅地终止工作。
我还会重新考虑这个大量的迭代,转而支持QTimer
。然后,基本上取消按钮或计时器的超时将触发工作循环中断。在这种情况下,迭代的while条件将是m_stop
保护。