QMetaObject::invokeMethod()

转自:https://blog.csdn.net/luoyayun361/article/details/97915133
https://blog.csdn.net/xzh_blue/article/details/48679157?t=1501319627942
概述
Qt元对象系统是Qt最核心的一个基础特性,元对象系统负责信号和插槽对象间通信机制、运行时类型信息和Qt属性系统。为应用程序中使用的每个QObject子类创建一个QMetaObject实例,此实例存储QObject子类的所有元信息。通过元对象系统,你可以查询QObject的某个派生类的类名、有哪些信号、槽、属性、可调用方法等信息,然后可以使用QMetaObject::invokeMethod()调用QObject的某个注册到元对象系统中的方法。而这里,主要就介绍改函数的使用方法,以及大致简介。

QMetaObject::invokeMethod()
QMetaObject的invokeMethod()方法用来调用一个对象的信号、槽、可调用的方法。这是一个静态方法。

该函数就是调用obj对象中的member方法,如果调用成功则返回true,调用失败则返回false,失败的话要么就是没有这个方法要么就是参数传入不对。
例:QMetaObject::invokeMethod(a,“print”,Qt::DirectConnection,Q_ARG(QString,“Hello”));

参数介绍
第一个参数a是被调用对象的指针;
第二个参数"print"是a对象中方法的名字;
第三个参数Qt::DirectConnection是连接类型。可以指定连接类型,来决定是同步还是异步调用。
如果type是Qt :: DirectConnection,则会立即调用该成员。
如果type是Qt :: QueuedConnection,则会发送一个QEvent,并在应用程序进入主事件循环后立即调用该成员。
如果type是Qt :: BlockingQueuedConnection,则将以与Qt :: QueuedConnection相同的方式调用该方法,除了当前线程将阻塞直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。
如果type是Qt :: AutoConnection,则如果obj与调用者位于同一个线程中,则会同步调用该成员; 否则它将异步调用该成员。
第四个参数Q_ARG(QString,“Hello”)是向函数print()传递的参数。
省略了一个参数Q_RETURN_ARG()接收被调用函数的返回值;注意,如果调用是异步的,则无法计算返回值。
注意:传入的参数是有个数限制的,可以向成员函数传递最多十个参数(val0,val1,val2,val3,val4,val5,val6,val7,val8和val9)。
Q_ARG()接受该类型的类型名称和const引用; Q_RETURN_ARG()接受类型名称和非const引用。

注意:此功能是线程安全的。
假设要异步调用QThread上的quit()槽:
QMetaObject::invokeMethod(thread, “quit”, Qt::QueuedConnection);
注意,要调用的类型必须是信号、槽,以及Qt元对象系统能识别的类型, 如果不是信号和槽,可以使用qRegisterMetaType()来注册数据类型。此外,使用Q_INVOKABLE来声明函数,也可以正确调用。
具体例子如下:
class A: public QObject
{
Q_OBJECT
public:
A(QObject * parent=NULL);
Q_INVOKABLE void print(QString tmp);
signals: void sigA(QString tmp);
public slots:
void slotA();

};
void A::print(QString tmp){ qDebug()<<“A:”<<tmp;}
void A::slotA(){qDebug()<<“slotA”;}

在widget.cpp中:
#include < QMetaObject >
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
button=new QPushButton(this);
button->setText(“Close”);
a=new A();
connect(button,SIGNAL(clicked()),this,SLOT(close())); }
void Widget::on_button2_clicked()
{
QMetaObject::invokeMethod(a,“print”,Qt::DirectConnection,Q_ARG(QString,“Hello”));//调用a对象的成员方法print,需要声明print()为Q_INVOKABLE 类型
QMetaObject::invokeMethod(a,“slotA”,Qt::DirectConnection);//调用a对象的槽函数
QMetaObject::invokeMethod(this,“setWindowTitle”,Qt::DirectConnection,Q_ARG(QString,“Hello”));//调用窗口的槽函数,传递参数“Hello”
// QMetaObject::invokeMethod(button,“clicked”,Qt::DirectConnection);//调用button的信号

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值