天天看點

子線程發信号更新UI-QT5.6.2/麒麟/x86子線程發送Qt中繼資料類型子線程發送自定義資料類型注意事項

文章目錄

  • 子線程發送Qt中繼資料類型
    • testthread.h
    • testthread.cpp
    • mainwindow.h
    • mainwindow.cpp
  • 子線程發送自定義資料類型
    • msg.h
    • testthread.h
    • testthread.cpp
    • mainwindow.h
    • mainwindow.cpp
  • 注意事項

衆所周知,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));
}
           

注意事項

  1. 信号與槽之間可以進行通信的根本原因是:當在類的頭檔案中添加Q_OBJECT以後QtCreator會自動的建立一個moc_***.cpp檔案,用于實作信号與槽通信的代碼。但是,有時當我們通過QtCreator建立類的時候,沒有通過IDE選項選擇其派生自QObject類,而是在後面添加的,則會出現QtCreator沒有自動建立moc_**.cpp檔案的情況。 這種情況下就會報錯 : undefined reference to `vtable for ***

    解決方法:

    從QtCreator去除該類的頭檔案,然後再通過“添加現有檔案”的方法,将該頭檔案添加進來。這樣QtCreator就會自動為該類建立moc_.cpp檔案

  2. 如果要用自己定義的資料類型,需要在connect前将其注冊為中繼資料類型
Qt

繼續閱讀