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函数返回值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习入门教程(2):使用预训练模型来文字生成图片TextToImageGenerationWithNetwork

本深度学习入门教程是在polyu HPCStudio 启发以及资源支持下进行的&#xff0c;在此也感谢polyu以及提供支持的老师。 本文内容&#xff1a;在GoogleColab平台上使用预训练模型来文字生成图片Text To Image Generation With Network &#xff08;1&#xff09;你会学到什么&a…

Fiddler使用教程|渗透测试工具使用方法Fiddler

提示&#xff1a;如有问题可联系我&#xff0c;24小时在线 文章目录 前言一、Fiddler界面介绍二、菜单栏1.菜单Fiddler工具栏介绍Fiddler命令行工具详解 前言 网络渗透测试工具&#xff1a; Fiddler是目前最常用的http抓包工具之一。 Fiddler是功能非常强大&#xff0c;是web…

伦敦金在非农双向挂单

对伦敦金投资有一定经验的投资者都知道&#xff0c;在非农时期&#xff0c;伦敦金市场会出现很大的波动&#xff0c;那么我们如何才能抓住这些波动呢&#xff1f;答案是很难的。但是&#xff0c;有些投资者在多年实践中发明了一种双向挂单的方法&#xff0c;这里和大家一切分享…

向量数据库Milvus的四个版本

目录 MilvusLite版 单机版 分布式版 Milvus Cloud版 Milvus是一个功能强大的向量数据库管理系统,提供了多种版本,以满足不同用户的需求。以下是关于Milvus四个版本的具体介绍。 MilvusLite版 MilvusLite版是Milvus的轻量级版本,适合于小规模数据集和高性能计算场景。…

el-popover在原生table中,弹出多个以及内部取消按钮无效问题

问题&#xff1a;当el-popover和原生table同时使用的时候会失效&#xff08;不是el-table) <el-popover placement"bottom" width"500" trigger"click" :key"popover-${item.id}"></el-popover> 解决&#xff1a; :key…

vue 项目中使用阿里巴巴矢量图标库

1.网址&#xff1a;https://www.iconfont.cn/ 2.手动创建自己的项目图标库 选中图标 → 添加入库&#xff08;点击购物车&#xff09;→ 完成后点击上方菜单栏的购物车 → 添加至项目&#xff08;没有则新建项目&#xff09;→ 自动打开项目图标库 → 点击下载至本地 → 点击de…

【Redis-02】Redis的缓存

Redis的缓存 1.概念1.1什么是缓存1.2为什么使用缓存1.3如何使用1.3.1不适用缓存之前1.3.2 缓存模型和思路&#xff08;使用方法&#xff09;1.3.3 使用之后 2.缓存更新策略2.1数据库缓存不一致解决方案2.2数据库和缓存不一致采用什么方案2.3代码实例 3.缓存穿透3.1缓存穿透是什…

(四)RabbitMQ高级特性(消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列

Lison <dreamlison163.com>, v1.0.0, 2023.06.23 RabbitMQ高级特性&#xff08;消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列 文章目录 RabbitMQ高级特性&#xff08;消费端限流、利用限流实现不公平分发、消息存活时间、优先级队列消费端限流利用限流…

一个简单的 Android 版本目录(Version catalog)实现指南

一个简单的 Android 版本目录实现指南 使用 TOML 格式 在本文中&#xff0c;我们将探讨版本目录以及如何实现它。 版本目录 Gradle 版本目录使您能够以可扩展的方式添加和维护依赖项和插件。因此&#xff0c;不必在各个构建文件中硬编码依赖项名称和版本&#xff0c;而是在目…

【NodeJs】如何将Markdown文件生成HTML文件在线浏览

经常用的编辑器是Markdown&#xff0c;有自带预览排版效果功能的&#xff0c;预览的是HTML网页&#xff0c;如果想要将它转换成HTML网页文件&#xff0c;要怎么做呢。 首先&#xff0c;借助Node的插件来做&#xff0c;在使用前&#xff0c;确保电脑已安装了NodeJS应用&#xf…

Linux相关指令(上)

常见指令&#xff1a; 1 pwd&#xff1a;查看用户当前所在目录 以下面的路径为例&#xff1a; 2 ls&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。 对于文件&#xff0c;将列出文件名以及其他信息 ls-l&#xff08;or ll&#xff09;&#xff1a;列…

【西安交通大学】:融合传统与创新的学府之旅

【西安交通大学】&#xff1a;融合传统与创新的学府之旅 引言历史与发展学校特色学科优势院系专业校园环境与设施学生生活与社团活动校友荣誉与成就未来发展展望总结&#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&…

Huge and Efficient! 一文了解大规模预训练模型高效训练技术

本文分为三部分介绍了大模型高效训练所需要的主要技术&#xff0c;并展示当前较为流行的训练加速库的统计。文章也同步发布在AI Box知乎专栏&#xff08;知乎搜索 AI Box专栏&#xff09;&#xff0c;欢迎大家在知乎专栏的文章下方评论留言&#xff0c;交流探讨&#xff01; 引…

效率与质量兼备的6个设计工具!

今天本文为大家推荐的这6个设计工具&#xff0c;将帮助设计师实现高效工作&#xff0c;同时也更好地展示自己的创作力&#xff0c;一起来看看吧&#xff01; 1、即时设计 即时设计是一款国内的设计工具&#xff0c;它为设计师提供了非常多实用的设计功能和精致的设计素材&…

【C++】开源:grpc远程过程调用(RPC)配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍grpc远程过程调用&#xff08;RPC&#xff09;配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜…

【转载+修改】pytorch中backward求梯度方法的具体解析

原则上&#xff0c;pytorch不支持张量对张量的求导&#xff0c;它只支持标量对张量的求导 我们先看标量对张量求导的情况 import torch xtorch.ones(2,2,requires_gradTrue) print(x) print(x.grad_fn)输出&#xff0c;由于x是被直接创建的&#xff0c;也就是说它是一个叶子节…

Linux查看内存的几种方法

PS的拼接方法 ps aux|head -1;ps aux|grep -v PID|sort -rn -k 4|head 进程的 status 比如说你要查看的进程pid是33123 cat /proc/33123/status VmRSS: 表示占用的物理内存 top PID&#xff1a;进程的ID USER&#xff1a;进程所有者 PR&#xff1a;进程的优先级别&#x…

python内置函数

https://www.runoob.com/python/python-built-in-functions.html https://www.runoob.com/python3/python3-function.html

SSD寿命和写放大测试

一、简述 SSD寿命规格&#xff0c;业界标准为TBW&#xff0c;TBW指的是Terabyte Writteb写入的兆兆字节&#xff0c;也有定义为Total Bytes Written&#xff0c;SSD使用寿命结束之前指定工作量可以写入SSD的总数据量&#xff0c;用来表达固态硬盘的寿命指标。 因为 SSD 使用 N…

同步、异步、阻塞、非阻塞

一、概念 同步与异步&#xff08;线程间调用&#xff09;的区别&#xff1a;关注的是调用方与被调用方之间的交互方式。同步调用会等待被调用方的结果返回&#xff0c;而异步调用则不会等待结果立即返回&#xff0c;可以通过回调或其他方式获取结果。 阻塞非阻塞&#xff08;…