プッシュボタンを使用してスレッドを頻繁に開始および停止する必要があります。Qtを使用しています。最近、Qtでスレッドを実装する正しい方法として、ワーカーのQObjectを作成し、それをQThreadのオブジェクトに移動することを学びました。以下は私の実装です...
Worker.h
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
void StopWork();
void StartWork();
bool IsWorkRunning();
signal:
void SignalToObj_mainThreadGUI();
public slots:
void do_Work();
private:
void Sleep();
volatile bool running,stopped;
QMutex mutex;
QWaitCondition waitcondition;
};
Worker.cpp
worker::worker(QObject *parent) :
QObject(parent),stopped(false),running(false)
{
}
void worker::do_Work()
{
running = true;
while(!stopped)
{
emit SignalToObj_mainThreadGUI();
Sleep();
}
}
void worker::Sleep()
{
mutex.lock();
waitcondition.wait(&mutex,10);
mutex.unlock();
}
void worker::StopWork()
{
mutex.lock();
stopped = true;
running = false;
mutex.unlock();
}
void worker::StartWork()
{
mutex.lock();
stopped = false;
running = true;
mutex.unlock();
}
bool worker::IsWorkRunning()
{
return running;
}
MainWindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
private slots:
void on_pushButton_push_to_start_clicked();
void on_pushButton_push_to_stop_clicked();
private:
Ui::MainWindow *ui;
worker *myWorker;
QThread *WorkerThread;
};
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
myWorker = new worker;
WorkerThread = new QThread;
myWorker.moveToThread(WorkerThread);
QObject::connect(WorkerThread,SIGNAL(started()),myWorker,SLOT(do_Work()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_push_to_start_clicked()
{
if(!myWorker.IsWorkRunning())
{
myWorker->StartWork();
WorkerThread->start();
}
}
void MainWindow::on_pushButton_push_to_stop_clicked()
{
if(myWorker.IsWorkRunning())
{
myWorker->StopWork();
WorkerThread->quit();
}
}
最初はアプリケーションは正常に動作しますが、プッシュボタンを操作してスレッドの動作をオンまたはオフにすると、次のエラーが発生します...
QObject :: killTimers():タイマーを別のスレッドから停止することはできません
私はこのエラーにかなり戸惑っています...クラスのメンバー関数ではなく、信号とスロットとして開始/停止関数を実装する必要がありますか?