博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt之创建自定义类型
阅读量:6494 次
发布时间:2019-06-24

本文共 2820 字,大约阅读时间需要 9 分钟。

摘要: 简述 当使用Qt创建用户界面时,特别是那些带有特殊控制和特征的界面时,开发者通常需要创建新数据类型来扩展或替换Qt现有的的值类型集合。 标准类型,比如:QSize、QColor和QString都可以被存储到QVariant对象中,在基于QObject的类中可用作属性的类型,并且可以在信号-槽通信时发射。 下面,我会创建一个自定义类型,并且说明如何将它集成到Qt的对象模型

简述

当使用Qt创建用户界面时,特别是那些带有特殊控制和特征的界面时,开发者通常需要创建新数据类型来扩展或替换Qt现有的的值类型集合。

标准类型,比如:QSize、QColor和QString都可以被存储到QVariant对象中,在基于QObject的类中可用作属性的类型,并且可以在信号-槽通信时发射。

下面,我会创建一个自定义类型,并且说明如何将它集成到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; };

这个类同时还提供了一个经常使用的构造函数,以及两个用于获取私有数据的共有成员函数。

使用QMetaType声明类型

Message类仅需要一个合适的实现,以便可以使用。然而,如果没有其他辅助信息,Qt类型系统将无法理解如何存储、检索和序列化该类的实例。例如:我们无法将Message的值保存到QVariant中。

Qt中负责自定义类型的类是QMetaType。为了让这个类识别该类型,当定义这个类时,需要头文件中使用Q_DECLARE_METATYPE()宏:

Q_DECLARE_METATYPE(Message);

这样,就可以将Message的值保存在QVariant对象中,并在以后读取。完整代码可参见Custom Type Example中的示范代码。

所述Q_DECLARE_METATYPE()宏同时也使得这些值可以被用作信号的参数,但是仅限于direct信号槽连接。为了能在信号槽机制中使用自定义类型,我们需要做一些另外的工作。

创建和销毁自定义对象

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

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

Queued Custom Type Example示例中在main.cpp文件中声明了一个Block类:

int main(int argc, char *argv[]){    QApplication app(argc, argv);    ...    qRegisterMetaType
(); ... return app.exec();}

这个类型后来在文件window.cpp中被用于一个信号-槽连接:

Window::Window(){    thread = new RenderThread();    ...    connect(thread, SIGNAL(sendBlock(Block)), this, SLOT(addBlock(Block)));    ...    setWindowTitle(tr("Queued Custom Type"));}

如果一个没有被注册的类型被用于queued连接中,在控制台中会输出一条警告信息。例如:

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

使类型可打印

出于调试目的,使一个自定义类型可打印是非常有用的,就像下面的代码一样:

Message message(body, headers);qDebug() << "Original:" << message;

可以通过为此类型创建流操作符来达到目的,这通常定义在该类型的头文件中:

QDebug operator<<(QDebug dbg, const Message &message);

在Custom Type Example的Message类实现中,我们努力让可打印的内容尽可能的通俗易读:

QDebug operator<<(QDebug dbg, const Message &message){    const QString body = message.body();    QVector
pieces = body.splitRef("\r\n", QString::SkipEmptyParts); if (pieces.isEmpty()) dbg.nospace() << "Message()"; else if (pieces.size() == 1) dbg.nospace() << "Message(" << pieces.first() << ")"; else dbg.nospace() << "Message(" << pieces.first() << " ...)"; return dbg.maybeSpace(); }

当然,输出到debug流的信息是简单还是复杂都随你的意思。需要注意的是这个函数的返回值是QDebug对象本身,尽管它通常通过调用QDebug的成员函数maybeSpace()来获得,用空白字符填充流,以使其更具可读性。

 

转自:https://yq.aliyun.com/articles/62082

 

转载地址:http://whkyo.baihongyu.com/

你可能感兴趣的文章
深入剖析Android系统试读样章
查看>>
测试用例出错重跑--flaky插件
查看>>
yaf的安装
查看>>
比较java与C++的不同
查看>>
Twitter Storm入门
查看>>
Windows 平台安装 MongoDB
查看>>
Linux Tar Split压缩解压缩分片压缩解压缩
查看>>
使用scikit-learn进行文本分类
查看>>
Ansible自动化运维配置与应用(结合实例)
查看>>
下面简要介绍软件工程的七条原理
查看>>
java POI实现excel实现表格导出
查看>>
Lua(三)——语句
查看>>
TensorFlow的基本运算01
查看>>
怎么看电脑有没有安装USB3.0驱动
查看>>
overflow清除浮动的原理
查看>>
Spring Boot 使用parent方式引用时 获取值属性方式默认@
查看>>
Elasticsearch之中文分词器插件es-ik(博主推荐)
查看>>
解决maven下载jar慢的问题(如何更换Maven下载源)
查看>>
linux安装gitLab
查看>>
concurrent包的实现示意图
查看>>