在项目开发时,常常需要用线程采集数据,如果要给界面发送数据,本文是方法之二,动态调用。
第一步:在界面类里定义一个带Q_INVOKABLE关键字的函数接收信息
第二步:在线程类里,用 QMetaObject::invokeMethod函数把数据发送出去,注意此函数中中指明的第二个参数是在第一步中的函数名称,第四个参数中指明了函数参数类型和个数,要和第一步保的函数参数类型和个数保持一致。
bool QMetaObject::invokeMethod
(QObject *obj,//第一个参数
const char *member,//第2个参数
Qt::ConnectionType type = Qt::AutoConnection,//第3个参数
QGenericReturnArgument ret = QGenericReturnArgument(),//可以有返回值,也可以没有返回值
QGenericArgument val0 = QGenericArgument(nullptr),//member字符变量对应函数的第1个参数
QGenericArgument val1 = QGenericArgument(), ...,//...
QGenericArgument val9 = QGenericArgument()///member字符变量对应函数最多10个参数
)
例子
1.线程
(1)头文件
#ifndef THREAD1_H
#define THREAD1_H
#include <QThread>
#include <QDebug>
class Thread1 : public QThread
{
Q_OBJECT
public:
explicit Thread1(QObject *parent = nullptr);
protected:
void run() override; //线程的循环
private:
int seq=0;
};
#endif // THREAD1_H
(2)cpp文件
#include "thread1.h"
Thread1::Thread1(QObject *parent)
: QThread{parent}
{
}
void Thread1:: run()
{ qDebug()<<"void Thread1:: run()";
while(1)
{
QThread::msleep(100);
seq++;
//emit send_info(seq);
QMetaObject::invokeMethod
(this->parent(),
"DataChanged",
Qt::QueuedConnection,
Q_ARG(int, seq)
);
//qDebug()<<this->parent();
}
}
2.界面
(1)头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "thread1.h"
#include <QString>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
Q_INVOKABLE void DataChanged(int a);
//public slots://本行及下一行和上行的效果一样
// void DataChanged(int a);
private:
Ui::Widget *ui;
Thread1 * thread1;
};
#endif // WIDGET_H
(2)cpp文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
thread1=new Thread1(this);
thread1->start();
}
Widget::~Widget()
{
delete ui;
}
void Widget:: DataChanged(int a)
{
//qDebug() << "DataChanged:"<<a;
ui->plainTextEdit->setPlainText(QString::number(a));
}