【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall

背景:

 【qt信号槽-1】槽函数重写问题,qt_metacall和qt_static_metacall

【qt信号槽-2】Qt中窗体继承,槽响应多次执行的解决_qt界面继承 槽函数多次执行

【qt信号槽-3】(QObject::connect: No such slot)的一种解决方法,connect函数qt4/qt5格式,元数据注册

【qt信号槽-4】槽函数不响应不执行的一种原因:ui提升导致重名_qt 按钮不能进入函数

【qt信号槽-5】信号槽相关注意事项记录

【qt信号槽-6】槽函数不执行的一种原因——未知线程

之前写了重写多态的理解,我自认为是一种比较极端,但是容易在使用角度掌握的理解。

用过简短的八行代码,从使用角度理解c++虚函数、重写、多态_大橘的博客-CSDN博客当然,上面的描述不严谨,也不一定准确,这里不是要纠结概念和理论,仅仅在使用角度考虑,用不用virtual,是否重写,会有什么效果,仅此而已。https://blog.csdn.net/u012999461/article/details/125690231

之所以开始研究这个概念,是因为遇到了问题,我做了一个比较通用的界面,现在想继承一个并丰富其功能,这需要重写其中一个槽函数,而这个槽函数是有其内部控件触发的。

按照重写函数的经验,我以为还需要显式调用父类的函数功能,但实际上它是自动实现的,这就超出我认知了,所以尝试跟踪代码看看。

分析:

汇编部分比较麻烦,真的不擅长,只看高级语言部分。

源头在于发信号:

QMetaObject::activate(this, &staticMetaObject, 1, _a);

都会用到一个staticMetaObject结构体,而这个结构体定义是这样的:

const QMetaObject HQ_Base_Db_Grid::staticMetaObject = {
    { &QTableWidget::staticMetaObject, qt_meta_stringdata_HQ_Base_Db_Grid.data,
      qt_meta_data_HQ_Base_Db_Grid,  qt_static_metacall, nullptr, nullptr}
};

其中有我自己定义的类名,不重要。重点是qt_static_metacall函数的调用。也就是说,只要发信号,肯定调用qt_static_metacall。而qt_static_metacall会调用本类当中的槽函数。比如某个界面中各种控件的响应,都是这样开始的。

再看一个子类的moc代码:

int Config_User_Users::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = Base_Grid_Single::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 1)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 1;
    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
        if (_id < 1)
            *reinterpret_cast<int*>(_a[0]) = -1;
        _id -= 1;
    }
    return _id;
}

很明显,它显式地调用了父类的qt_metacall函数。但执行子类这段代码的时候,它并不会跳转到下面的qt_static_metacall函数那一句。

接着,在父类的qt_metacall函数中,跳转到了父类的qt_static_metacall函数,于是执行了父类的槽函数。而后子类才又调用了自己的qt_static_metacall函数,来执行自己的槽函数。

结论:

当某个类没有重写父类槽函数时,它会直接调用qt_static_metacall函数,进而执行自己的槽函数。

当重写了父类的槽函数时,它会调用qt_metacall函数,然后显式调用父类的qt_static_metacall函数,从而执行父类的槽函数。而且这个过程是一直递归到基类的,所有的槽函数按照辈分执行。最后子类再调用自己的qt_static_metacall函数,从而执行自己的槽函数。

所以我能否这样理解?

qt的槽机制中,为重写槽函数提供了更智能的方法,不用程序员再显式调用父类槽函数。相当于槽函数可以像类一样继承。

我想,其实验证一下也容易,重写系统某个槽函数,比如事件过滤器,试试就知道了。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值