文章目录
众所周知,QT的主线程必须保持畅通,才能刷新UI。所以,网 络通信端采用新开线程的方式
子线程发送Qt元数据类型
testthread.h
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <QThread>
class testthread : public QThread
{
Q_OBJECT
public:
testthread();
protected:
void run();
signals:
void TestSingal(int);
};
#endif // TESTTHREAD_H
testthread.cpp
#include "testthread.h"
testthread::testthread()
{
}
void testthread::run()
{
emit TestSingal(123);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "testthread.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void DisplayMsg(int);
private:
Ui::MainWindow *ui;
testthread *t;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//进行connect前必须实例化
t = new testthread();
connect(t,SIGNAL(TestSingal(int)),this,SLOT(DisplayMsg(int)));
//执行子线程
t->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::DisplayMsg(int a)
{
ui->textBrowser->append(QString::number(a));
}
子线程发送自定义数据类型
msg.h
#ifndef MSG_H
#define MSG_H
#include <string>
using namespace std;
struct Msg{
int int_info;
string str_info;
};
#endif // MSG_H
testthread.h
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <QThread>
#include "msg.h"
class testthread : public QThread
{
Q_OBJECT
public:
testthread();
protected:
void run();
signals:
void TestSingal(Msg);
public:
Msg msg;
};
#endif // TESTTHREAD_H
testthread.cpp
#include "testthread.h"
testthread::testthread()
{
}
void testthread::run()
{
msg.int_info = 999;
msg.str_info = "Hello Main Thread!";
//触发信号
emit TestSingal(msg);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "testthread.h"
#include "msg.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void DisplayMsg(Msg);
private:
Ui::MainWindow *ui;
testthread *t;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qRegisterMetaType<Msg>("Msg");
//进行connect前必须实例化
t = new testthread();
connect(t,SIGNAL(TestSingal(Msg)),this,SLOT(DisplayMsg(Msg)));
//执行子线程
t->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::DisplayMsg(Msg msg)
{
ui->textBrowser->append(QString::number(msg.int_info));
ui->textBrowser->append(QString::fromStdString(msg.str_info));
}
注意事项
- 信号与槽之间可以进行通信的根本原因是:当在类的头文件中添加Q_OBJECT以后QtCreator会自动的创建一个moc_***.cpp文件,用于实现信号与槽通信的代码。但是,有时当我们通过QtCreator创建类的时候,没有通过IDE选项选择其派生自QObject类,而是在后面添加的,则会出现QtCreator没有自动创建moc_**.cpp文件的情况。 这种情况下就会报错 : undefined reference to `vtable for ***
解决方法:
从QtCreator去除该类的头文件,然后再通过“添加现有文件”的方法,将该头文件添加进来。这样QtCreator就会自动为该类创建moc_.cpp文件 - 如果要用自己定义的数据类型,需要在connect前将其注册为元数据类型