2014-04-07 66 views
2

在我的程序中,我打开一个窗口并运行一个大循环。我在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()减慢执行时间有点太多..但也许这是不可避免的..

我想尝试它的信号和插槽s,但我似乎无法想象如何将推入的停止按钮与循环连接起来。或者,信号和插槽与否,也许有人有一个更好的方式来实现这一目标?

编辑

继此线程的建议,我现在有一个工人/线程场景。所以我有一个窗口的构造函数

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()); 

或者既不... ...但是,那么,怎么样?

+0

为什么不使用线程来完成繁重的工作? – OnWhenReady

回答

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(); 
} 
+0

看起来是这样做的。但是有可能在线程中使用该示例吗?看我的编辑...谢谢 – user2287453

1

一件事,你可以做的要少“块状”是做你的工作中使用QThread工作线程。那么,慢下来不会是一个如此大的问题,而你仍然能够优雅地终止工作。

我也将重新考虑这个大数目的迭代,赞成QTimer。然后,基本上取消按钮或定时器的超时会触发工作循环中断。在这种情况下,迭代的时间条件是m_stop后卫。

相关问题