【问题标题】:How to stop background loop after pushing button?按下按钮后如何停止后台循环?
【发布时间】:2014-04-07 15:54:58
【问题描述】:

在我的程序中,我打开一个窗口并运行一个大循环。我在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);

或者,我应该将线程连接到QTimerstart() 函数吗?

connect(thread, SIGNAL(started()), timer, &QTimer::start());

或者两者都不是......但是,如何?

【问题讨论】:

  • 为什么不用线程来做繁重的工作?

标签: c++ qt qtcore qt-signals qtimer


【解决方案1】:

使用 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();
}

【讨论】:

  • 看起来就是这样。但是是否可以将该示例与线程一起使用?查看我的编辑...谢谢
【解决方案2】:

您可以做的一件事是减少“块状”,即使用QThread 在工作线程中完成您的工作。那么,在你仍然可以优雅地终止工作的情况下,减速将不再是一个大问题。

我还会重新考虑这个大量迭代以支持QTimer。然后,基本上取消按钮或计时器的超时将触发工作循环中断。在这种情况下,迭代的 while 条件将是 m_stop 守卫。

【讨论】:

    猜你喜欢
    • 2015-07-19
    • 2012-07-14
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多