Qt Core学习日记——第七天QMetaObject(上)
每一个声明Q_OBJECT的类都具有QMetaObject对象
Q_OBJECT宏源代码:
#define Q_OBJECT \
public: \
QT_WARNING_PUSH \
Q_OBJECT_NO_OVERRIDE_WARNING \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
QT_TR_FUNCTIONS \
private: \
Q_OBJECT_NO_ATTRIBUTES_WARNING \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
QT_WARNING_POP \
struct QPrivateSignal {}; \
QT_ANNOTATE_CLASS(qt_qobject, "")
每一个声明Q_OBJECT类的对象都具有同一静态成员staticMetaObject,staticMetaObject用于存储类的基础信息,比如类属性、类信息。
例如类XTest的QMetaObject staticMetaObject
XTest::staticMetaObject中包含类信息"author", "Sabrina Schweinsteiger",类属性autoStartup,槽函数、信号、其它函数
XTest.h
#pragma once
#include <qobject.h>
#include <QFlags>
class XTest : public QObject
{
Q_OBJECT
Q_CLASSINFO("author", "Sabrina Schweinsteiger")
Q_PROPERTY(bool autoStartup READ autoStartup WRITE setAutoStartup NOTIFY sigAutoStartup)
public:
XTest(QObject* p = nullptr) {}
~XTest() {}
public:
enum Priority
{
High,
Low,
VeryHigh,
VeryLow
};
Q_ENUM(Priority)
enum PriorityFlag
{
High1,
Low1,
VeryHigh1,
VeryLow1
};
Q_FLAG(PriorityFlag)
Q_DECLARE_FLAGS(Alignment, PriorityFlag)
Q_FLAG(Alignment)
public:
bool autoStartup() { return m_autoStartup; }
void setAutoStartup(bool b) { m_autoStartup = b; emit sigAutoStartup(); }
public slots:
void slot1(double* p1) {}
Q_INVOKABLE void slot2(int* p2) {}
Q_REVISION(1) void slot3(char* p3) {}
Q_INVOKABLE void slot4(int p2, double) {}
signals:
void sig1(void * p4);
void sigAutoStartup();
private:
Q_REVISION(1) bool m_autoStartup = false;
};
XTest.cpp:
#include "XTest.h"
qt生成的moc文件moc_XTest.cpp:
/****************************************************************************
** Meta object code from reading C++ file 'XTest.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include <memory>
#include "../../../XTest.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'XTest.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.15.2. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_XTest_t {
QByteArrayData data[29];
char stringdata0[212];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_XTest_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_XTest_t qt_meta_stringdata_XTest = {
{
QT_MOC_LITERAL(0, 0, 5), // "XTest"
QT_MOC_LITERAL(1, 6, 6), // "author"
QT_MOC_LITERAL(2, 13, 22), // "Sabrina Schweinsteiger"
QT_MOC_LITERAL(3, 36, 4), // "sig1"
QT_MOC_LITERAL(4, 41, 0), // ""
QT_MOC_LITERAL(5, 42, 2), // "p4"
QT_MOC_LITERAL(6, 45, 14), // "sigAutoStartup"
QT_MOC_LITERAL(7, 60, 5), // "slot1"
QT_MOC_LITERAL(8, 66, 7), // "double*"
QT_MOC_LITERAL(9, 74, 2), // "p1"
QT_MOC_LITERAL(10, 77, 5), // "slot2"
QT_MOC_LITERAL(11, 83, 4), // "int*"
QT_MOC_LITERAL(12, 88, 2), // "p2"
QT_MOC_LITERAL(13, 91, 5), // "slot3"
QT_MOC_LITERAL(14, 97, 5), // "char*"
QT_MOC_LITERAL(15, 103, 2), // "p3"
QT_MOC_LITERAL(16, 106, 5), // "slot4"
QT_MOC_LITERAL(17, 112, 11), // "autoStartup"
QT_MOC_LITERAL(18, 124, 8), // "Priority"
QT_MOC_LITERAL(19, 133, 4), // "High"
QT_MOC_LITERAL(20, 138, 3), // "Low"
QT_MOC_LITERAL(21, 142, 8), // "VeryHigh"
QT_MOC_LITERAL(22, 151, 7), // "VeryLow"
QT_MOC_LITERAL(23, 159, 12), // "PriorityFlag"
QT_MOC_LITERAL(24, 172, 5), // "High1"
QT_MOC_LITERAL(25, 178, 4), // "Low1"
QT_MOC_LITERAL(26, 183, 9), // "VeryHigh1"
QT_MOC_LITERAL(27, 193, 8), // "VeryLow1"
QT_MOC_LITERAL(28, 202, 9) // "Alignment"
},
"XTest\0author\0Sabrina Schweinsteiger\0"
"sig1\0\0p4\0sigAutoStartup\0slot1\0double*\0"
"p1\0slot2\0int*\0p2\0slot3\0char*\0p3\0slot4\0"
"autoStartup\0Priority\0High\0Low\0VeryHigh\0"
"VeryLow\0PriorityFlag\0High1\0Low1\0"
"VeryHigh1\0VeryLow1\0Alignment"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_XTest[] = {
// content:
8, // revision
0, // classname
1, 14, // classinfo
6, 16, // methods
1, 70, // properties
3, 74, // enums/sets
0, 0, // constructors
0, // flags
2, // signalCount
// classinfo: key, value
1, 2,
// signals: name, argc, parameters, tag, flags
3, 1, 52, 4, 0x06 /* Public */,
6, 0, 55, 4, 0x06 /* Public */,
// slots: name, argc, parameters, tag, flags
7, 1, 56, 4, 0x0a /* Public */,
10, 1, 59, 4, 0x0a /* Public */,
13, 1, 62, 4, 0x8a /* Public | MethodRevisioned */,
16, 2, 65, 4, 0x0a /* Public */,
// signals: revision
0,
0,
// slots: revision
0,
0,
1,
0,
// signals: parameters
QMetaType::Void, QMetaType::VoidStar, 5,
QMetaType::Void,
// slots: parameters
QMetaType::Void, 0x80000000 | 8, 9,
QMetaType::Void, 0x80000000 | 11, 12,
QMetaType::Void, 0x80000000 | 14, 15,
QMetaType::Void, QMetaType::Int, QMetaType::Double, 12, 4,
// properties: name, type, flags
17, QMetaType::Bool, 0x00495103,
// properties: notify_signal_id
1,
// enums: name, alias, flags, count, data
18, 18, 0x0, 4, 89,
23, 23, 0x1, 4, 97,
28, 23, 0x1, 4, 105,
// enum data: key, value
19, uint(XTest::High),
20, uint(XTest::Low),
21, uint(XTest::VeryHigh),
22, uint(XTest::VeryLow),
24, uint(XTest::High1),
25, uint(XTest::Low1),
26, uint(XTest::VeryHigh1),
27, uint(XTest::VeryLow1),
24, uint(XTest::High1),
25, uint(XTest::Low1),
26, uint(XTest::VeryHigh1),
27, uint(XTest::VeryLow1),
0 // eod
};
void XTest::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<XTest *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->sig1((*reinterpret_cast< void*(*)>(_a[1]))); break;
case 1: _t->sigAutoStartup(); break;
case 2: _t->slot1((*reinterpret_cast< double*(*)>(_a[1]))); break;
case 3: _t->slot2((*reinterpret_cast< int*(*)>(_a[1]))); break;
case 4: _t->slot3((*reinterpret_cast< char*(*)>(_a[1]))); break;
case 5: _t->slot4((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< double(*)>(_a[2]))); break;
default: ;
}
} else if (_c == QMetaObject::IndexOfMethod) {
int *result = reinterpret_cast<int *>(_a[0]);
{
using _t = void (XTest::*)(void * );
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&XTest::sig1)) {
*result = 0;
return;
}
}
{
using _t = void (XTest::*)();
if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&XTest::sigAutoStartup)) {
*result = 1;
return;
}
}
}
#ifndef QT_NO_PROPERTIES
else if (_c == QMetaObject::ReadProperty) {
auto *_t = static_cast<XTest *>(_o);
Q_UNUSED(_t)
void *_v = _a[0];
switch (_id) {
case 0: *reinterpret_cast< bool*>(_v) = _t->autoStartup(); break;
default: break;
}
} else if (_c == QMetaObject::WriteProperty) {
auto *_t = static_cast<XTest *>(_o);
Q_UNUSED(_t)
void *_v = _a[0];
switch (_id) {
case 0: _t->setAutoStartup(*reinterpret_cast< bool*>(_v)); break;
default: break;
}
} else if (_c == QMetaObject::ResetProperty) {
}
#endif // QT_NO_PROPERTIES
}
QT_INIT_METAOBJECT const QMetaObject XTest::staticMetaObject = { {
QMetaObject::SuperData::link<QObject::staticMetaObject>(),
qt_meta_stringdata_XTest.data,
qt_meta_data_XTest,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *XTest::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *XTest::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_XTest.stringdata0))
return static_cast<void*>(this);
return QObject::qt_metacast(_clname);
}
int XTest::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 6)
qt_static_metacall(this, _c, _id, _a);
_id -= 6;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 6)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 6;
}
#ifndef QT_NO_PROPERTIES
else if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty
|| _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType) {
qt_static_metacall(this, _c, _id, _a);
_id -= 1;
} else if (_c == QMetaObject::QueryPropertyDesignable) {
_id -= 1;
} else if (_c == QMetaObject::QueryPropertyScriptable) {
_id -= 1;
} else if (_c == QMetaObject::QueryPropertyStored) {
_id -= 1;
} else if (_c == QMetaObject::QueryPropertyEditable) {
_id -= 1;
} else if (_c == QMetaObject::QueryPropertyUser) {
_id -= 1;
}
#endif // QT_NO_PROPERTIES
return _id;
}
// SIGNAL 0
void XTest::sig1(void * _t1)
{
void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t1))) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
// SIGNAL 1
void XTest::sigAutoStartup()
{
QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE
函数解析:
静态函数
bool QMetaObject::checkConnectArgs(const char *signal, const char *method)
检查2个字符串参数是否相同。传入参数字符串需要是QMetaObject::normalizedSignature返回的字符串。例如slots2函数签名是“slots2(int*)”。就是上一篇QMetaMethod::methodSignature函数返回值
bool QMetaObject::checkConnectArgs(const QMetaMethod &signal, const QMetaMethod &method)
检查信号与槽参数连接参数是否相同
QByteArray QMetaObject::normalizedSignature
获取函数签名。例如slots2函数签名是“slots2(int*)”。就是上一篇QMetaMethod::methodSignature函数返回值
相关文章:

Qt Core学习日记——第七天QMetaObject(上)
每一个声明Q_OBJECT的类都具有QMetaObject对象 Q_OBJECT宏源代码: #define Q_OBJECT \ public: \ QT_WARNING_PUSH \ Q_OBJECT_NO_OVERRIDE_WARNING \ static const QMetaObject staticMetaObject; \ virtual const QMetaObject *metaObject() const; \ vir…...

100、用简洁的语言描述一下:TCP的三次握手和四次挥手(不需要长篇大论)
TCP的三次握手和四次挥手 TCP协议是7层网络协议中的传输层协议,负责数据的可靠传输。 1、三次握手 在建立TCP连接时,需要通过三次握手来建立,过程是: 客户端向服务端发送一个SYN服务端接收到SYN后,给客户端发送一个SYN_ACK客户…...

中南大学硕士论文latex版本全指导
要毕业了,闲下点时间写的东西。之前一直收益与师兄师姐流传下来的latex版本,用起来很舒服,希望后面的学弟学妹也能完美用上。latex功能很强大,不需要自己排版,只管内容即可,但是安装流程会多一丢丢。 目录 …...

RFC8470在HTTP中使用早期数据
摘要 使用TLS早期数据会暴露出重放攻击的可能性。本文定义了允许客户端与服务器就早期数据中发送的HTTP请求进行通信的机制。描述了使用这些机制来减轻重放风险的技术。 1. 介绍 TLS 1.3[TLS13]引入了早期数据(也称为零往返时间(0-RTT)数…...

macOS Big Sur 11.7.9 (20G1426) 正式版 ISO、PKG、DMG、IPSW 下载
macOS Big Sur 11.7.9 (20G1426) 正式版 ISO、PKG、DMG、IPSW 下载 本站下载的 macOS 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装。另外也支持在 Window…...

【LeetCode】62.不同路径
题目 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? …...

使用序列化和反序列化函数archivedDataWithRootObject和unarchivedObjectOfClasses的使用和遇到问题及解决方案
为何archiveRootObject和unarchiveObjectWithFile正常,而archivedDataWithRootObject和unarchivedObjectOfClasses一直报错。 [NSKeyedArchiver archiveRootObject:account toFile:path];和c PPAccountModel *account [NSKeyedUnarchiver unarchiveObjectWithFile:…...

python获取鼠标出颜色
import pyautogui as pg import keyboarddef rgb2hex(r, g, b):return #{:02x}{:02x}{:02x}.format(r, g, b)try:width, height pg.size()print(f"Display resolution: {width} * {height}\n") # 打印屏幕分辨率print(按下shift键打印出鼠标所指位置的颜色......)w…...

Github Flow工作流简单介绍(以部署为中心的开发模式)
前言 这篇文章主要介绍Github Flow的理念,以下内容来源于《Github入门与实践》。 Github Flow是以部署为中心的开发模式,通过简单的规则,持续高速且安全地进行部署。而Gitflow则是以发布为中心的分支管理模型,它提供了一种更灵活…...

selenium浏览器驱动下载
Chrome谷歌浏览器 下载地址:http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的chromedriver.exe 版本也不一样,下载时不要搞错了。 如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。 Firefox火狐浏览器 驱…...

go学习 模块与包 - Init函数 - 如何导入第三方包 - 切片与数组的数据传递方式 - go中文件的读写
目录 包(package)是组织和复用代码的基本单元。 包的种类: 包的导入 包的组成 如下两个文件中定义了A变量和 sc_num变量,他们的首字母开头分别为大写和小写,因此可以说明A变量是公有变量,而sc_num是私…...

2023第五届全国生物资源提取与应用创新论坛即将举办
01、会议背景 为进一步加强生物资源提取行业交流与合作,促进业“产学研用”融合,提升行业科技创新水平,增强行业国际竞争力,中国生物发酵产业协会、浙江科技学院、浙江工业职业技术学院、浙江省农业生物资源生化制造协同创新中心&…...

Socks5代理在爬虫与HTTP应用中的重要性
IP代理的类型及原理常见的IP代理类型有HTTP代理、Socks代理等,本文重点关注Socks5代理。Socks5代理是一种网络协议,可以实现传输层的数据转发,使客户端在不直接连接服务器的情况下与其进行通信。其原理在于接收客户端的请求,然后将…...

二叉树详解
这里写目录标题 前言树型结构(了解)树常见的概念树的表示形式(了解)树的应用 二叉树概念两种特殊的二叉树二叉树的性质(重要)二叉树的存储二叉树的基本操作 前言 本篇博客讲述了以下几个知识点 树的基本概念二叉树概念及特性二叉树的基本操作 树型结构…...

Git的核心概念:探索Git中的提交、分支、合并、标签等核心概念,深入理解其作用和使用方法
🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~ἳ…...

JAVA设计模式——23种设计模式详解
一、什么是设计模式🍉 设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目…...

Oracle输出文本平面(CSV、XML)文本数据详细过程
此过程是提供给前端,调用的接口,为报表提供”下载“功能。以下是本人在测试环境的测试,有什么不足的地方,请留言指教,谢谢。 1、测试表 分别对测试表输出csv、xml两种格式文件数据。前期的准备工作。 --在服务器端创建directory,用管理员用户 create or replace directo…...

基于C++的QT基础教程学习笔记
文章目录: 来源 教程社区 一:QT下载安装 二:注意事项 1.在哪里写程序 2.如何看手册 3.技巧 三:常用函数 1.窗口 2.相关 3.按钮 4.信号与槽函数 5.常用栏 菜单栏 工具栏 状态栏 6.铆接部件 7.文本编辑 8…...

【数据分享】全国地级市1999—2020年工业企业数(Shp/Excel格式)
在之前的文章中,我们分享过基于2000-2022年《中国城市统计年鉴》整理的1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额(可查看之前的…...

设计模式【行为型】-- 责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象依次处理同一个请求,形成一条责任链。当客户端提交一个请求时,请求沿着责任链传递,直到有一个处理者能够处理该请求为止。…...

[Spring] 三级缓存解决循环依赖详解
什么是循环依赖 注册一个bean对象的过程: Spring扫描class得到BeanDefinition – 根据得到的BeanDefinition去生成bean – 现根据class推断构造方法 – 根据推断出来的构造方法,反射,得到一个对象 – 填充初始对象中的属性(依赖注入) – 如果…...

gerrit 从安装到出坑
一般公司在做代码审核的时候选择codereview gerrit来处理代码的入库的问题。 它是通过提交的时候产生Change-Id: If4e0107f3bd7c5df9e2dc72ee4beb187b07151b9 来决定是不是入库,一般如果不是通过这个管理,那么就是我们通常的操作 git add . git comm…...

Java工程师就业前景怎么样?能拿多少工资?
Java软件工程师是指运用Java这个开发工具去完成软件产品的软件程序设计、开发、测试、维护升级等工作的人员。Java程序员可以分为初级、中级、高级、资深等。不同级别的Java程序员,薪资也不一样。 Java除了一般的编程,还可以开发游戏、进行桌面设计、Ja…...

极速跳板机登陆服务器
目录 一:简单登陆跳板器二:一键申请相关的服务器权限三:简化登陆 一:简单登陆跳板器 登陆公司提供的网址, 下载自己的专属RSA密钥。在密钥文件处, 执行登陆指令: ssh -p 36000 -i id_rsa 用户跳…...

【算法与数据结构】226、LeetCode翻转二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:这道题的思路很简单,本质上就是遍历每一个节点,然后交换左右节点。我们可以用前…...

metaRTC6.0 new feature (一)
概要 metaRTC6.0社区版最新版是6.0.212,标准版最新版本是6.0.276,企业版基础版最新版本是6.0.362,在企业版和标准版新增了一些实用功能模块,文件数字证书模块将并入社区版。 New Feature rtsp协议支持 新增rtsp协议࿰…...

聊天机器人如何增加电子商务销售额
聊天机器人和自动化对企业和客户来说都是福音。自动对话和聊天机器人(以下统称为“自动化”)通过自动回答问题或分配会话信息来帮助用户浏览品牌网站或电商商店。即时答案对客户来说非常有用,使用自动化也可以让原本与客户聊天的客服员工专注…...

stm32 IIC通信
文章目录 IIC 通信一、硬件电路二、IIC时序基本单元三、IIC时序1.指定地址写2.当前地址读3.指定地址读 IIC 通信 IIC总线是一种通用数据总线,有两根通信线(SCL(串行时钟总线),SDA(串行数据总线))。 特点:同…...

Elasticsearch监控工具Cerebro安装
Elasticsearch监控工具Cerebro安装 1、在windwos下的安装 1.1 下载安装包 https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.zip 1.2 解压 1.3 修改配置文件 如果需要修改相关信息,编辑C:\zsxsoftware\cerebro-0.9.4\conf\applica…...

RTOS 低功耗设计原理及实现
RTOS 低功耗设计原理及实现 文章目录 RTOS 低功耗设计原理及实现👨🏫前言👨🔬Tickless Idle Mode 的原理及实现👨🚀Tickless Idle Mode 的软件设计原理👨💻Tickless Idle Mo…...