尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Qt学习日记 Day2:MOC原理+信号槽底层实现分析+信号槽lambda练习

Qt学习日记 Day2:MOC原理+信号槽底层实现分析+信号槽lambda练习 ## 今天学了什么今天学习Qt中MOC原理信号槽底层实现原理以及练习结合lambda表达式对信号槽的运用。## MOC原理元对象编译器它是Qt额外的预处理器在标准C编译之前扫描带 Q_OBJECT 的头文件MOC编译期扫描带 Q_OBJECT 的类生成 staticMetaObject 元信息表记录所有信号/槽/invokable、名字、参数、MOC分配的唯一methodIndex同时自动生成信号的实现信号里面只有一行调用 activate(this, metaObj, 信号编号, 参数数组)。## 信号槽底层实现原理运行时执行 connect从发送类的元表里查出这个信号的编号用它当下标找到发送对象 d‑ptr 里的connections 链表存入一条记录{接收对象指针接收方那边要调用的元方法编号连接类型}。运行时 emit 信号(触发信号) 时调用 moc生成的信号函数 → 进入 activateactivate 拿着这个信号编号当下标去发送对象的 connections[该编号] 取出全部连接记录循环每一条用接收对象 接收方的元方法编号通过 qt_metacall 调用对应的槽或者信号跨线程就打包成事件丢进对方事件循环。注①staticMetaObject类级、编译期写死、MOC产出存名字‑编号映射。即该类的QMetaObject元对象里面存放着编译期MOC生成的整套元信息表方法、属性、名字、编号等它属于类不是对象实例运行时不变②d_ptr‑connections对象实例级、运行时才由connect构建、MOC不参与存一条条「谁连谁」的连接卡片接收对象 接收端methodIndex 连接类型③methodIndexMOC扫描头文件时按顺序分配的连续编号是元方法在本类元表里的ID只在当前类内有效。④ 元方法表里有三类可登记项Signal信号MOC额外生成带 activate 调用的函数体可以广播Slot槽仅登记编号不生成新函数体Q_INVOKABLE给普通成员函数“登记进元表、获得编号”的资格可以被元系统调用但既不是信号也不是槽没有广播能力。⑤qt_metacallMOC自动生成的分发函数给它「对象 methodIndex」它就能调用对应的原生函数它不知道连接、不知道广播QML这类没有C函数指针的环境就是靠它调用C函数。⑥activate不是MOC生成的是Qt库提供收到发送对象信号编号参数去发送对象 d_ptr-connections[编号] 遍历全部已注册连接再通过 qt_metacall 挨个触发接收端方法。⑦ 信号可以当槽用信号在元表里只有固定那一个methodIndex不会新建编号只是 qt_metacall 可以调用它调用后又会执行它里面的 activate继续广播。## 信号与槽练习** 通过按钮打开关闭另一个窗口 **要求结合lambda让一个按钮实现开关窗口操作。QPushButton *btnnew QPushButton(打开,this); btn-resize(200,100); btn-move(200,200); QWidget *mywidgetnew QWidget; connect(btn,QPushButton::clicked,this,[](){ if(btn-text()打开) { //mywidget-move(200,200); mywidget-show(); btn-setText(关闭); } else { mywidget-close(); btn-setText(打开); } });
返回列表