スタート ボタン、ストップ ボタン、およびテキスト フィールドを備えた単純な Qt4 アプリケーションがあります。[開始] ボタンが押されると、(while ループで) カウンターを継続的にインクリメントする新しいスレッドが生成され、シグナル/スロットを介してこれを反映するようにテキスト フィールドが更新されます。停止ボタンを押すと、再度開始ボタンを押すまでカウントが停止します。
それは動作します...一種の。カウンターは 1 秒に 1 回だけ更新されます。毎秒44100回など、もっと速くしたいです。ただし、sleep(1) 呼び出しを実行すると、while ループがブロックされ、GUI イベントが認識されず、アプリケーションがフリーズします。また、停止ボタンは 2 回目の試行でしか機能しませんか?
これは、QThread をサブクラス化していたときにかなりうまく機能していましたが、そうしないように言われたので、QObject をサブクラス化してからオブジェクトを QThread に移動して解決策を作成しようとしましたが、うまく機能しません。以前のように。
コードは次のとおりです。
Worker.h
class Worker : public QObject
{
Q_OBJECT
public:
Worker();
public slots:
void process();
void stopRunning();
signals:
void signalValueUpdated(QString);
private:
bool running;
};
ワーカー.cpp
#include "Worker.h"
void Worker::process()
{
qDebug("Worker thread id %d",(int)QThread::currentThreadId());
static int value=0;
running = 1;
while(running == 1)
{
QString string = QString("value: %1").arg(value++);
sleep(1); //I want to take this out or make it way shorter but I can't without it crashing.
emit signalValueUpdated(string);
QCoreApplication::processEvents();
}
}
void Worker::stopRunning()
{
qDebug("stopRunning() invoked");
running = 0;
}
MainWindow.h
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private:
//Widgets
QHBoxLayout * boxLayout;
QPushButton * startButton;
QPushButton * stopButton;
QLineEdit * lineEdit;
//Thread where the worker lives
QThread * workerThread;
//Worker object itself
Worker * worker;
};
MainWindow.cpp
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
boxLayout = new QHBoxLayout(this);
startButton = new QPushButton("Start Counter", this);
stopButton = new QPushButton("Stop Counter", this);
lineEdit = new QLineEdit(this);
boxLayout->addWidget(startButton);
boxLayout->addWidget(stopButton);
boxLayout->addWidget(lineEdit);
qDebug("Thread id %d",(int)QThread::currentThreadId());
workerThread = new QThread;
worker = new Worker();
worker->moveToThread(workerThread);
connect( startButton, SIGNAL(clicked()), workerThread, SLOT(start()), Qt::QueuedConnection ); //When the start button is clicked, start the worker thread
connect( startButton, SIGNAL(clicked()), worker, SLOT(process()), Qt::QueuedConnection ); //When the start button is clicked, start the worker thread
connect( workerThread, SIGNAL(started()), worker, SLOT(process()), Qt::QueuedConnection ); //When the worker thread starts, begin the Worker object's process function
connect( stopButton, SIGNAL(clicked()), worker, SLOT(stopRunning()), Qt::QueuedConnection ); //When the stop button is clicked, invoke the Worker's stopRunning()
connect( worker, SIGNAL(signalValueUpdated(const QString&)), lineEdit, SLOT(setText(const QString&)), Qt::QueuedConnection ); //When the Worker emits a signalValueChanged, update the lineEdit to reflect this
}
Worker.cpp に sleep(1) と processEvents() がないと、全体がクラッシュしますが、遅くなりすぎて、1000 以上ではなく 1 秒に 1 回しか更新されません。while(running) ループをブロックしないようにするにはどうすればよいですか?
前もって感謝します!Qt でマルチスレッドを実行するための最良の方法に頭を悩ませようとしています。