[英]Simple multithreading with Qt: am I doing this right?
我是StackOverflow的新手,想知道我是否做对了:
我正在编写一个简单的Qt应用程序来测试多线程(这也是我的新手)。 我制作了一个包含小部件的MainWindow,以及一个MyThread类,该类继承QThread并覆盖run()方法。
该应用程序仅显示两个按钮,“开始计数器”和“停止计数器”,以及一个文本字段。 当按下“启动计数器”时,将创建一个工作线程并在后台运行,在while循环中不断增加计数器,并用更新的值向主线程(GUI所在的位置)发出信号。 当按下“停止计数器”时,一个信号被发送到主线程,该线程停止while循环,并且计数器停止直到再次按下“启动计数器”。
这工作得很好...但这是最好的方法吗? 我是新来的人,读过很多人说“不要把QThread子类化”,还有其他人说“不要把QThread子类化”,这有点令人困惑。 如果这不是实现这种事情的最佳方法(使用“开始”和“停止”按钮在后台线程中运行计算密集型循环),那是什么? 如果我做错了,该怎么做? 我不想学习错误的方法。
谢谢! 这是代码:
MyThread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QMutex>
class MyThread : public QThread
{
Q_OBJECT
public slots:
void stopRunning();
protected:
virtual void run();
signals:
void signalValueUpdated(QString);
private:
bool isRunning;
};
MyThread.cpp
#include "MyThread.h"
#include <QString>
void MyThread::run()
{
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
static int value=0; //If this is not static, then it is reset to 0 every time this function is called.
isRunning = 1;
while(isRunning == 1)
{
QString string = QString("value: %1").arg(value++);
sleep(1/1000); //If this isn't here, the counter increments way too fast and dies, or something; the app freezes, anyway.
emit signalValueUpdated(string);
}
}
void MyThread::stopRunning()
{
isRunning = 0;
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include "MyThread.h"
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private:
//Widgets
QHBoxLayout * boxLayout;
QPushButton * startButton;
QPushButton * stopButton;
QLineEdit * lineEdit;
MyThread thread;
};
#endif
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());
//When the start button is pressed, invoke the start() method in the counter thread
QObject::connect(startButton,SIGNAL(clicked()),&thread,SLOT(start()), Qt::QueuedConnection);
//When the stop button is pressed, invoke the stop() method in the counter thread
QObject::connect(stopButton,SIGNAL(clicked()),&thread,SLOT(stopRunning()), Qt::QueuedConnection);
//When the counter thread emits a signal saying its value has been updated, reflect that change in the lineEdit field.
QObject::connect(&thread,SIGNAL(signalValueUpdated(const QString&)),lineEdit,SLOT(setText(const QString&)), Qt::QueuedConnection);
}
大多数时候,QThread子类化是在Qt中进行线程化的错误方法。 我建议您阅读有关线程,事件循环和其他内容的文章,这可以使您了解如何以更好的方式在Qt中使用线程。 但是,不要听任何人争论使用QThread是唯一正确的方法。 有两种方法,虽然通常不需要子类化,但有时它可能很有用。 您只需要使用非子类化方式,直到真正需要子类化为止。 在您的特定情况下,您不需要子类化。
替换sleep(1/1000);
与msleep(100);
一切都会好起来的:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.