Qt中自定义数据类型的创建及使用

Qt中自定义数据类型的创建及使用

DateAuthorVersionNote
2022.12.17Dog TaoV1.0整理后发表。

前言

在Qt的项目开发过程中,特别是在制作一些特殊界面时,通常框架中自带的数据类型难已满足具体的要求,这时就需要开发者自己创建新的数据类型来扩展或替换原有的数据类型。本文将详细介绍自定义数据类型的方法以及如何将其集成到Qt对象模型中,为大家提供参考。

特别说明:本文档参考了此篇博文

创建一个自定义类型

Qt框架下开发时,创建一个自定义类型,需要确保创建的这个自定义类型符合QMetaType规定的所有要求,即它必须满足以下几个条件:

  • 有一个默认的公有构造函数
  • 有一个公有的拷贝构造函数
  • 有一个公有的析构函数

下面的Message类的定义满足这些条件,可以定义成一个新的数据类型:

class Message
{
public:
    Message();
    Message(const Message &other);
    ~Message();
    Message(const QString &body, const QStringList &headers);
    QString body() const;
    QStringList headers() const;
private:
    QString m_body;
    QStringList m_headers;
};

这个类还提供了一个带参数的构造函数和用于访问两个私有成员的公有函数。

自定义类型的声明

对于Message类,仅需要一个简单的实现,即可以使用,但是在Qt框架下,若没有其它的辅助信息,系统将无法理解这个类的存储方式、检索方式以及序列化方式。比如,我们无法将该类的值保存到QVariant中。因此,我们需要对该类进行声明。

Qt中,负责自定义类型的类是QMetaType ,为了让这个类识别自定义的数据类型,需要在定义Message类的头文件中使用Q_DECLARE_METATYPE()宏声明。注意是在”global scope”中调用完成Qt元类型的声明。

class Message
{
    /*省略无关内容*/
};

Q_DECLARE_METATYPE(Message);

经过声明后,便可以将Message类的值保存到QVariant对象中,以便在项目的其它地方读取。QVariant对象与自定类型的互相转化可以参考笔者的《使用QSettings保存和读取自定义数据类型》一文中的“QVariant与自定义结构体转化章节”。以下简要说明:

  • 自定类型转QVariant对象
QVariant Variant_Message = QVariant::fromValue<Message>(Message());
  • QVariant对象转自定类型
Message message = Variant_Message.value<Message>();

Q_DECLARE_METATYPE()声明的自定义类型, 其对应的值可用作信号SIGNAL()的参数,但是仅限于DirectConnection 信号槽连接方式。为了能满足全部的信号槽连接方式,我们还需要做一些其它的处理。

自定义对象的创建与销毁

虽然上面声明的自定义类型,可以在DirectConnection信号槽连接中使用,但是无法用于QueuedConnection信号连接中,比如,在不同线程间建立的连接。这是因为元对象系统不知道如何在运行时处理自定义类型对象的创建和销毁操作。

为了可以在运行时创建对象,需要调用qRegisterMetaType()模板函数在元对象系统中注册此类型。只要在使用此类型第一次建立连接前调用注册函数,该类型即可被用于QueuedConnection信号槽连接。

下面的示例中,在main.cpp中注册了一个Message类,而后在Information类中绑定信号。

//main.cpp
int main(int argc, char *argv[])
{
    QApplication a(argc,argv);
    //其它项目的代码
    qRegisterMetaType<Message>();
    //其它项目代码
    return a.exec();
}
 
//下面是Information类的相关调用
Information::Information()
{
    informatin_thread = new QThread();
    connect(information_thread, SIGNAL(sendMessage(Message)), this, SLOT(receiveMessage(Message)));
    //项目的其它代码
}

若类型未经注册而直接绑定在QueuedConnection信号槽中,则会报如下错误:

QObject::connect: Cannot queue arguments of type ‘Block’ (Make sure ‘Block’ is registered using qRegisterMetaType().)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全能骑士涛锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值