首页 > 其他分享 >Qt小知识1.Q_DECLARE_METATYPE和qRegisterMetaType

Qt小知识1.Q_DECLARE_METATYPE和qRegisterMetaType

时间:2023-12-08 17:55:27浏览次数:25  
标签:Qt 自定义 METATYPE qRegisterMetaType 类型 DECLARE

1 了解Q_DECLARE_METATYPE

Q_DECLARE_METATYPE 是一个Qt宏,用以通知Qt的反射系统关于自定义类型的存在。当使用此宏声明一个类型后,该类型可以在QVariant中使用。QVariant是Qt中用于存储可以包含任意类型的一个“通用”值容器。

Qt 元对象系统不知道非Qt类的存在,因此如果要在QVariant中存储自定义类型,就需要用这个宏声明它。此宏必须在全局作用域中使用,并且用于类型定义之后。它实际上就是为类型定义一个特殊的模板特化,这样QVariant才能了解如何使用它。

这个模板特化提供了一个静态函数qt_metatype_id,它为该类型分配并返回一个独一无二的ID。这个ID用于QVariant创建、复制、比较和析构该类型的实例。

综上,Q_DECLARE_METATYPE(Type)宏用于告诉 Qt 框架某个自定义类型Type是存在的,并且可以被元对象系统所使用。使用这个宏之后,Type就可以用于 QVariant 类型和信号与槽的参数传递中。该宏通常在类的定义外部使用,不需要修改类的定义。注意,仅仅使用Q_DECLARE_METATYPE并不能够在使用信号和槽时动态地创建类型的对象,为此需要使用qRegisterMetaType

struct MyStruct {
    int a;
    QString b;
};

Q_DECLARE_METATYPE(MyStruct)

上述代码使得MyStruct可以被用在 QVariant 内部。

2 了解qRegisterMetaType

qRegisterMetaType 是一个在运行时调用的函数,它将自定义类型注册到Qt的元对象系统中。此函数确保类型不仅已知于QVariant,还已知于Qt的整个类型系统,尤其是用于多线程环境中信号和槽的QObject通信。

注册类型之后,Qt可以动态地在运行时构造和销毁对象,即使是对于非Qt类型。这是因为qRegisterMetaType在内部为类型存储了创建和析构该类型对象所需的方法指针。这允许在运行时创建和复制传递给信号和槽作为参数的类型,这些参数必须能够在事件循环中跨线程边界安全移动。

综上,qRegisterMetaType("TypeName") 函数是在运行时被调用,用于注册类型 Type 到 Qt 的元类型系统。这个步骤是必须的,如果想在信号和槽中,跨线程边界使用该类型。它允许 Qt 知道如何在运行时构造、复制和销毁这种类型的对象。通常这个函数在 main 函数或者类被实际用作信号和槽之前的初始化代码中调用。

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 注册到元类型系统
    qRegisterMetaType<MyStruct>("MyStruct");

    // 现在 MyStruct 可以安全地用做信号和槽参数
    // ...

    return app.exec();
}

实际应用示例:

如果有一个自定义的类型 MyStruct 并想在不同线程间的信号和槽通信中使用它,需要这么做:

  1. 使用 Q_DECLARE_METATYPE() 声明这个结构体。
struct MyStruct {
    int a;
    QString b;
};

Q_DECLARE_METATYPE(MyStruct)
  1. 在应用程序启动时(例如在 main 函数中),使用 qRegisterMetaType() 来注册自定义类型。
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    qRegisterMetaType<MyStruct>("MyStruct");

    // ...
    return app.exec();
}

这使得 MyStruct 可以在跨线程的信号和槽调用中安全使用。如果只是想在同一线程内的信号和槽或者使用 QVariant 存储自定义类型的话,通常只需要 Q_DECLARE_METATYPE 宏。

此外,qRegisterMetaType 还使得自定义类型可用于QMetaObject中的类型信息,比如QObject::property(),QObject::setProperty(),以及QMetaProperty::read()和QMetaProperty::write()这些反射相关的函数。

3 总结

Q_DECLARE_METATYPE 通知Qt元对象系统关于自定义类型的存在,这样该类型就可以在QVariant中使用。qRegisterMetaType在此基础上更进一步,它将自定义类型完全集成到Qt的元对象系统中,使得类型可以跨线程在信号和槽中使用,以及在Qt的属性系统中使用。

了解这两者是如何工作的有助于在Qt应用程序中更有效地使用自定义类型,特别是在需要类型信息的高级特性时,如跨线程信号与槽的通信或属性系统。

标签:Qt,自定义,METATYPE,qRegisterMetaType,类型,DECLARE
From: https://www.cnblogs.com/luoxiang/p/17888430.html

相关文章

  • Qt显示OpenCV的单通道图片
    一、概述Qt中显示OpenCV的图片。OpenCV中的Mat默认是3通道图片。但是其灰度图、二值图片会是8位单通道的。示例代码中记录了如何显示二、代码示例#include"ImageUtils.h"MatImageUtils::qImageToMat(QImageqImage){//QImage转Mat三通道图片QImageimage=......
  • vcpkg 包管理在Clion 和 Qt中的使用
    在使用C++的过程中,发现了一个强大的包管理器,以后再也不用自己去单独编译某个C++的外部插件了。下面说一下教程:安装好git后,直接在D:\Plugins\develop目录下克隆一个vcpkg的目录gitclonehttps://github.com/microsoft/vcpkg进入vcpkg目录后,打开管理员命令台,输入./vcpkgins......
  • 13、QT窗口API函数基础知识
    QT窗口API函数geometry()用于获取窗口在屏幕上的几何位置和大小QRectgeo=widget->geometry();intx=geo.x();//窗口左上角的x坐标inty=geo.y();//窗口左上角的y坐标intw=geo.width();//窗口的宽度inth=geo.height();//窗口的高度width()函数返......
  • 12、QT自定义消息框
     #include"dialog.h"Dialog::Dialog(QWidget*parent):QDialog(parent){resize(260,80);glayout=newQGridLayout(this);labelmsg=newQLabel("自定义消息框");msgButton=newQPushButton("测试操作");labeldis......
  • Qt/C++音视频开发58-逐帧播放/上一帧下一帧/切换播放进度/实时解码
    一、前言逐帧播放是近期增加的功能,之前也一直思考过这个功能该如何实现,对于mdk/qtav等内核组件,可以直接用该组件提供的接口实现即可,而对于ffmpeg,需要自己处理,如果有缓存的数据的话,可以通过在缓存中的数据往前移动往后移动即可。这样就要求做一个比较大的缓存队列,占用一定的内存是......
  • Qt6 c++教程1简介
    1Qt6简介Qt一个跨平台应用程序开发框架,旨在为桌面、嵌入式和移动平台创建具有统一用户界面(UI)的优秀软件应用程序。它为开发人员设计和构建优秀应用程序提供了一套强大的工具,而无需担心平台依赖性。本章主要内容:Qt介绍使用Qt的原因下载和安装Qt从源代码构建Qt61.1Qt简......
  • 如何在 PyQt 中实现异步数据库请求
    需求开发软件的时候不可避免要和数据库发生交互,但是有些SQL请求非常耗时,如果在主线程中发送请求,可能会造成界面卡顿。这篇博客将会介绍一种让数据库请求变得和前端的ajax请求一样简单,且不会阻塞界面的异步请求方法。实现过程在实现异步请求之前,需要先明确一下函数签名:def......
  • 解决QtCreator启动失败
    在.zshrc中加入:exportQT_DEBUG_PLUGINS=1然后再启动,发现报错:library:"/home/itfanr/Desktop/sdb/Qt/Tools/QtCreator/lib/Qt/plugins/platforms/libqxcb.so"cannotload:Cannotloadlibrary/home/itfanr/Desktop/sdb/Qt/Tools/QtCreator/lib/Qt/plugins/platfor......
  • Android Studio开发连接MQTT服务器
    新建安卓项目第一步第二步修改代码在AndroidManifest.xml文件中添加网络状态,确保连接mqtt服务器!<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>下载mqttjar包下载地址:ht......
  • QT最小化程序到托盘运行
    MinTray说明实现程序关闭时最小化托盘的功能托盘实现显示主页面和退出的功能支持扩展,直接引用TrayIcon类即可,对外暴露接口单例实现,可复用警告注:博主所有资源永久免费,若有帮助,请点赞转发是对我莫大的帮助注:博主本人学习过程的分享,引用他人的文章皆会标注原......