子線程通過QMetaObject::invokeMethod控制UI控件


1、注意,要調用的類型必須是信號、槽,以及Qt元對象系統能識別的類型。此外,使用Q_INVOKABLE來聲明函數,也可以正確調用。

2、該方法線程安全,其他講解看手冊,就不翻譯了

3、隱藏ui

QMetaObject::invokeMethod(ui_Ptr,
                                  "hide",
                                  Qt::QueuedConnection)

 4、在子線程中給QListWidget子類MyListWidget使用addItems方法,當然你也可以在主線程additems。

 1 #ifndef MYWORK_H
 2 #define MYWORK_H
 3 
 4 #include <QObject>
 5 
 6 class MyWork : public QObject
 7 {
 8     Q_OBJECT
 9 public:
10     explicit MyWork(void *, QObject *parent = nullptr);
11 
12 public:
13     void doWork();
14 signals:
15     void sendNum(QList<int>);
16 private:
17     void *m_p;  
18 };
19 
20 #endif // MYWORK_H
mywork.h(工作類)
 1 #include "mywork.h"
 2 #include<QRandomGenerator>
 3 #include<QDebug>
 4 #include<QThread>
 5 #include"mylistwidget.h"
 6 
 7 MyWork::MyWork(void *p, QObject *parent) : QObject(parent)
 8 {
 9     m_p = p;
10 }
11 
12 void MyWork::doWork()
13 {
14     QStringList strList;
15 
16     for(int i = 0; i < 10000; i++)
17         strList.append(QString::number(i));
18 
19     QMetaObject::invokeMethod(static_cast<MyListWidget*>(m_p),
20                               "add",
21                               Qt::QueuedConnection,
22                               Q_ARG(QStringList, strList));
23 
24     qDebug()<<"子線程結束"<<QThread::currentThread();
25 }
mywork.cpp(工作類)
 1 #include "mainwindow.h"
 2 #include "ui_mainwindow.h"
 3 #include"mywork.h"
 4 #include"mythread.h"
 5 #include "mylistwidget.h"
 6 
 7 #include<QRandomGenerator>
 8 #include<QDebug>
 9 #include<QElapsedTimer>
10 
11 MainWindow::MainWindow(QWidget *parent)
12     : QMainWindow(parent)
13     , ui(new Ui::MainWindow)
14 {
15     ui->setupUi(this);
16     qDebug()<<"主線程地址: "<<QThread::currentThread()<<this;
17 
18     QThread *sub = new QThread;
19     MyWork *work = new MyWork(ui->listWidget);      //  不能指定父對象,不然無法moveToThread
20     work->moveToThread(sub);
21     qDebug()<<"sub線程地址: "<<sub->currentThread()<<sub;
22 
23     connect(ui->pushButton, &QPushButton::clicked, work, &MyWork::doWork);
24 
25     sub->start();
26 }
27 
28 MainWindow::~MainWindow()
29 {
30     delete ui;
31 }
mainswindow.cpp
 1 #ifndef MYLISTWIDGET_H
 2 #define MYLISTWIDGET_H
 3 
 4 #include <QListWidget>
 5 
 6 class MyListWidget : public QListWidget
 7 {
 8     Q_OBJECT
 9 public:
10     explicit MyListWidget(QWidget *parent = nullptr);
11 
12 signals:
13 
14 public slots:
15     void add(QStringList str);      //  用於調用additems
16 
17 };
18 
19 #endif // MYLISTWIDGET_H
mylistwidget
 1 #include "mylistwidget.h"
 2 
 3 MyListWidget::MyListWidget(QWidget *parent) : QListWidget(parent)
 4 {
 5 
 6 }
 7 
 8 void MyListWidget::add(QStringList str)
 9 {
10     this->addItems(str);
11 }
mylistwidget

 

mywork.h中聲明了一個add,用於調用addItems,因為QMetaObject::invokeMethod識別不到addItems。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM