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()、実行時間が少し遅くなりすぎることです..しかし、おそらくそれは避けられない..

シグナルとスロットで試してみたかったのですが、押された停止ボタンをループに接続する方法が思いつかないようです。

または、信号とスロットかどうかにかかわらず、誰かがこれを達成するためのより良い方法を持っているのでしょうか?

編集

このスレッドのアドバイスに従って、ワーカー/スレッドのシナリオができました。だから私はウィンドウコンストラクターにいます

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

これはうまくいくようです。しかし、どうすれば now を導入できQTimerますか?

QTimerをスレッドのstart()関数に接続する必要がありますか

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

または、スレッドをQTimerstart()関数に接続する必要がありますか?

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

またはどちらでもない...しかし、どうやって?

4

2 に答える 2

2

Qタイマーを使う

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();
}
于 2014-04-07T16:04:19.433 に答える
1

「むら」を少なくするためにできることの 1 つは、 を使用してワーカー スレッドで作業を行うことですQThread。そうすれば、作業を正常に終了できる一方で、スローダウンはそれほど大きな問題にはなりません。

また、この多数の反復を再考して、 を支持しQTimerます。次に、基本的にキャンセル ボタンまたはタイマーのタイムアウトが、ワーカー ループの中断をトリガーします。その場合、反復の while 条件はm_stopガードになります。

于 2014-04-07T23:59:24.887 に答える