因此,我正在围绕QThread
学习,并且我在合理的程度上理解了它。
然而,我正在尝试实现一个从QThread派生的类来执行一个基本函数,然后在值发生变化时发出信号。
让我发布Header
和Source
文件:
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "mythread.h"
#include <QTextEdit>
#include <QPushButton>
#include <QSpinBox>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
void setGUI();
void Start_Thread();
void Stop_Thread(); //will be implemented later to stop all threads
public slots:
void Update_O1(int);
private:
MyThread *m_Thread1;
QPushButton *START;
QPushButton *STOP;
QSpinBox *L1Input;
QSpinBox *L2Input; //For when a second Thread is added
QSpinBox *L3Input; //For when a third Thread is added
QTextEdit *L1Out;
QTextEdit *L2Out; //For when a second Thread is added
QTextEdit *L3Out; //For when a third Thread is added
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include <QGridLayout>
Dialog::Dialog(QWidget *parent)
: QDialog(parent), m_Thread1(new MyThread), START(new QPushButton("Start")),
STOP(new QPushButton("Stop")), L1Input(new QSpinBox), L2Input(new QSpinBox),
L3Input(new QSpinBox),L1Out(new QTextEdit),L2Out(new QTextEdit), L3Out(new QTextEdit)
{
setGUI();
connect(START, &QPushButton::clicked, this, &Dialog::Start_Thread);
connect(STOP, &QPushButton::clicked, this, &Dialog::Stop_Thread);
connect(m_Thread1, SIGNAL(NumberChanged(int)), this, SLOT(Update_01(int)));
//I know this is the old Syntax, but I don't know how else to do this...yet.
//I got a similar function to work on a different project using the same format
}
Dialog::~Dialog()
{
}
void Dialog::setGUI()
{
setWindowTitle("Three Threads");
resize(300,300);
START->setMaximumWidth(100);
STOP->setMaximumWidth(100);
L1Input->setRange(1,100);
L2Input->setRange(1,100);
L3Input->setRange(1,100);
L1Out->setReadOnly(true);
L2Out->setReadOnly(true);
L3Out->setReadOnly(true);
QGridLayout *GLout = new QGridLayout;
GLout->addWidget(START,0,1);
GLout->addWidget(STOP,0,2);
GLout->addWidget(L1Input,1,0);
GLout->addWidget(L2Input,1,1);
GLout->addWidget(L3Input,1,2);
GLout->addWidget(L1Out,2,0);
GLout->addWidget(L2Out,2,1);
GLout->addWidget(L3Out,2,2);
setLayout(GLout);
}
void Dialog::Start_Thread()
{
qDebug() << "START works"; //this is just to let me know the Start_Thread function is called properly
m_Thread1->start();
}
void Dialog::Stop_Thread()
{
}
void Dialog::Update_O1(int x)
{
qDebug() << QString::number(x);
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QObject>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void run();
void setSnum(int); //setter function
bool Stop = false; //will be used later to stop a thread
signals:
void NumberChanged(int);
private:
int Snum = 10; //temporary value. will later implement setter to use value from GUI
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QDebug>
#include <QtCore>
MyThread::MyThread(QObject *parent)
: QThread{parent}
{
}
void MyThread::run()
{
while(!(Snum == 1))
{
QMutex mutex;
mutex.lock();
if(this->Stop) break;
mutex.unlock();
if(Snum % 2 == 0)
{
Snum /= 2;
}else{
Snum *= 3;
Snum += 1;
}
emit this->NumberChanged(Snum);
}
}
void MyThread::setSnum(int startnum)
{
Snum = startnum;
}
最后,一个非常基本的main.cpp
文件
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
不过,我面临的问题是,在mythread.cpp
的run函数中,我似乎没有从emit函数获得信号。我在QtCreator
的qDebug()部分没有得到输出
我做错了什么?
我使用的是Qt 6.3.0。
您有这样的连接:
connect(m_Thread1, SIGNAL(NumberChanged(int)), this, SLOT(Update_01(int)));
但你的方法实际上是这样叫的:
void Dialog::Update_O1(int x)
注意Update_01与Update_O1。他们是不同的人物。一个是零,另一个是大写的"o"。
所以,你应该有:
connect(m_Thread1, SIGNAL(NumberChanged(int)), this, SLOT(Update_O1(int)));
然而,最好的解决方案是使用";新的";信号槽语法。
connect(m_Thread1, &QThread::NumberChanged, this, &QDialog::Update_O1);
实际上,如果插槽很短,您甚至可以使用lambda:
connect(m_Thread1, &QThread::NumberChanged, this, [](int x) {qDebug() << QString::number(x);});
新的信号槽语法的主要优点是,这类问题将在编译时而不是运行时发现。因此,您可能不会发布带有此错误的软件。