永久个人网站,高级感ppt模板,wordpress网页游戏模板,建设青岛公司网站最近用QT做一个服务器#xff0c;众所周知#xff0c;QT的主线程必须保持畅通#xff0c;才能刷新UI。所以#xff0c;网络通信端采用新开线程的方式。在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦。网上提供了很多同一线程不同类间采用信号槽通信的方式#xff0c;…       最近用QT做一个服务器众所周知QT的主线程必须保持畅通才能刷新UI。所以网络通信端采用新开线程的方式。在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦。网上提供了很多同一线程不同类间采用信号槽通信的方式但是并不完全适合线程间的信号槽通信这主要体现在自定义消息的传递上。 首先我们看看一般的方式 testthread.h 文件 [cpp] view plaincopy   print?   #ifndef TESTTHREAD_H   #define TESTTHREAD_H      #include QThread      #include msg.h      class TestThread : public QThread   {       Q_OBJECT   public:       explicit TestThread(QObject *parent  0);      protected:       void run();      signals:       void TestSignal(int);      private:       Msg msg;   };      #endif // TESTTHREAD_H   testthread.cpp文件 [cpp] view plaincopy   print?   #include testthread.h      TestThread::TestThread(QObject *parent) :       QThread(parent)   {   }      void TestThread::run()   {       //触发信号       emit TestSignal(123);   }   自己定义的类继承了QThread类重写run函数然后触发TestSignal信号。 mainwindow.h [cpp] view plaincopy   print?   #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 [cpp] view plaincopy   print?   #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(TestSignal(int)), this, SLOT(DisplayMsg(int)));          //执行子线程       t-start();    }      void MainWindow::DisplayMsg(int a)   {       ui-textBrowser-append(QString::number(a));   }      MainWindow::~MainWindow()   {       delete ui;   }   Mainwindow里面连接信号槽并且将收到的int参数显示在界面上。 运行效果 下面我们对程序进行一些简单修改使得它传输我们的自定义消息。 testthread.h 文件  [cpp] view plaincopy   print?   #ifndef TESTTHREAD_H   #define TESTTHREAD_H      #include QThread      #include msg.h      class TestThread : public QThread   {       Q_OBJECT   public:       explicit TestThread(QObject *parent  0);       Msg msg;      protected:       void run();      signals:       void TestSignal(Msg);   //Msg!!!   };      #endif // TESTTHREAD_H   testthread.h 文件[cpp] view plaincopy   print?   #include testthread.h      TestThread::TestThread(QObject *parent) :       QThread(parent)   {   }      void TestThread::run()   {       msg.int_info  999;       msg.str_info  Hello Main Thread!;       //触发信号       emit TestSignal(msg);   }   mainwindow.h 文件  [cpp] view plaincopy   print?   #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);   //Msg!!!      private:       Ui::MainWindow *ui;       TestThread *t;   };      #endif // MAINWINDOW_H   mainwindow.cpp 文件[cpp] view plaincopy   print?   #include mainwindow.h   #include ui_mainwindow.h      MainWindow::MainWindow(QWidget *parent) :       QMainWindow(parent),       ui(new Ui::MainWindow)   {       ui-setupUi(this);          //进行connect前必须实例化       t  new TestThread();          //Msg!!!       connect(t, SIGNAL(TestSignal(Msg)), this, SLOT(DisplayMsg(Msg)));          //执行子线程       t-start();   }      void MainWindow::DisplayMsg(Msg msg)   {       ui-textBrowser-append(QString::number(msg.int_info));       ui-textBrowser-append(msg.str_info);   }      MainWindow::~MainWindow()   {       delete ui;   }   此时再进行编译能够通过但是Qt Creator会有提示 [cpp] view plaincopy   print?   QObject::connect: Cannot queue arguments of type Msg   (Make sure Msg is registered using qRegisterMetaType().)   并且运行程序不会有任何反应。 mainwindow.cpp文件 改动为 [cpp] view plaincopy   print?   ui-setupUi(this);      qRegisterMetaTypeMsg(Msg);   此时能够正常运行 说明 在线程间使用信号槽进行通信时需要注意必须使用元数据类型 Qt内生的元数据类型如int double QString 等 如果要用自己定义的数据类型需要在connect前将其注册为元数据类型。形式见代码。