子线程通过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。

 

posted @ 2021-10-29 15:49  补码  阅读(1192)  评论(0编辑  收藏  举报