2014-04-07 7 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, но я не могу представить, как я могу подключить нажатую кнопку остановки с помощью цикла.

Или, сигналы и слоты или нет, может быть, у кого-то есть лучший способ достичь этого?

EDIT

После этого совета резьбы, теперь у меня есть сценарий, рабочий/нить. Таким образом, у меня есть в оконном конструкторе

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 сейчас?

Должен ли я подключить к QTimerstart() функции потока

connect(timer, &QTimer::timeout, thread, &QThread::start); 

Или я должен соединить нить start() функции в QTimer «ы?

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. Затем, в основном кнопка отмены или тайм-аут таймера вызовет разрыв рабочего цикла. В этом случае условием while для итерации будет защита m_stop.