当前位置: 首页 > news >正文

pos机网站模板中国建设银行app官网

pos机网站模板,中国建设银行app官网,怎么让WORDPRESS首页显示菜单,新网站开发费用目录 1.引言 2.QVariant的用法 2.1.包含头文件 2.2.基本类型的存储与获取 2.3.自定义类型的存储与获取 2.4.枚举类型的存储与获取 2.5.类型检查与转换 2.6.容器类型的存储与获取 3.枚举的问题 4.信号槽中使用自定义结构体 4.1.使用QVariant转换 4.2.直接传递自定义…

目录

1.引言

2.QVariant的用法

2.1.包含头文件

2.2.基本类型的存储与获取

2.3.自定义类型的存储与获取

2.4.枚举类型的存储与获取

2.5.类型检查与转换

2.6.容器类型的存储与获取

3.枚举的问题

4.信号槽中使用自定义结构体

4.1.使用QVariant转换

4.2.直接传递自定义结构体

5.性能开销

5.1. 内存开销

5.2. 时间开销

5.3. 与直接使用具体类型的对比

6.总结


1.引言

        在Qt框架中,QVariant类是一个非常强大的工具,它允许我们存储各种类型的数据,并在需要时将其转换为原始类型。QVariant类似于C语言中的void*,但它更加类型安全,并且能够存储多种数据类型。然而,QVariant在处理枚举类型(enum)、自定义结构体时存在一些限制。本文将探讨如何解决这一问题,使QVariant能够与枚举类型、自定义结构体协同工作。

2.QVariant的用法

  QVariant 是 Qt 中一个非常强大且灵活的类,它可以存储多种不同类型的数据,并且可以在不同类型之间进行转换。

2.1.包含头文件

在使用 QVariant 之前,需要包含相应的头文件:

#include <QVariant>

这一点我是经常忘掉,导致编译错误,但是又不是很容易发现是没有包含头文件QVariant。

2.2.基本类型的存储与获取

QVariant 可以存储许多基本数据类型,如整数、浮点数、字符串等。

存储基本类型

#include <QVariant>
#include <QDebug>int main() {// 存储整数QVariant intVariant = 42;// 存储浮点数QVariant doubleVariant = 3.14;// 存储字符串QVariant stringVariant = "Hello, World!";return 0;
}

获取基本类型

#include <QVariant>
#include <QDebug>int main() {QVariant intVariant = 42;QVariant doubleVariant = 3.14;QVariant stringVariant = "Hello, World!";// 获取整数int intValue = intVariant.toInt();// 获取浮点数double doubleValue = doubleVariant.toDouble();// 获取字符串QString stringValue = stringVariant.toString();qDebug() << "Int value:" << intValue;qDebug() << "Double value:" << doubleValue;qDebug() << "String value:" << stringValue;return 0;
}

2.3.自定义类型的存储与获取

对于自定义类型,需要将其注册到 Qt 的元对象系统中,以便 QVariant 能够处理。

定义自定义类型

#include <QObject>
#include <QVariant>
#include <QDebug>// 定义自定义类型
class MyClass {
public:MyClass(int value) : m_value(value) {}int value() const { return m_value; }
private:int m_value;
};// 注册自定义类型
Q_DECLARE_METATYPE(MyClass)int main() {// 存储自定义类型MyClass myObject(123);QVariant customVariant = QVariant::fromValue(myObject);// 获取自定义类型if (customVariant.canConvert<MyClass>()) {MyClass retrievedObject = customVariant.value<MyClass>();qDebug() << "Retrieved value:" << retrievedObject.value();}return 0;
}

2.4.枚举类型的存储与获取

对于枚举类型,需要使用 Q_ENUM 宏将其注册到元对象系统中。

#include <QObject>
#include <QVariant>
#include <QDebug>// 定义枚举类型
class MyEnumClass : public QObject {Q_OBJECT
public:enum MyEnum {Option1,Option2,Option3};Q_ENUM(MyEnum)
};int main() {// 存储枚举值QVariant enumVariant = QVariant::fromValue(MyEnumClass::Option2);// 获取枚举值if (enumVariant.canConvert<MyEnumClass::MyEnum>()) {MyEnumClass::MyEnum retrievedEnum = enumVariant.value<MyEnumClass::MyEnum>();qDebug() << "Retrieved enum value:" << retrievedEnum;}return 0;
}#include "main.moc"

2.5.类型检查与转换

QVariant 提供了一些方法来检查其存储的数据类型,并进行类型转换。

#include <QVariant>
#include <QDebug>int main() {QVariant variant = 42;if (variant.type() == QVariant::Int) {qDebug() << "The variant contains an integer.";}if (variant.canConvert(QVariant::String)) {qDebug() << "The variant can be converted to a string.";}return 0;
}

类型转换

#include <QVariant>
#include <QDebug>int main() {QVariant variant = 42;// 转换为字符串QString stringValue = variant.toString();qDebug() << "Converted to string:" << stringValue;return 0;
}

2.6.容器类型的存储与获取

QVariant 也可以存储 Qt 的容器类型,如 QListQMap 等。

#include <QVariant>
#include <QList>
#include <QDebug>int main() {// 存储QListQList<int> intList = {1, 2, 3};QVariant listVariant = QVariant::fromValue(intList);// 获取QListif (listVariant.canConvert<QList<int>>()) {QList<int> retrievedList = listVariant.value<QList<int>>();for (int value : retrievedList) {qDebug() << "List value:" << value;}}return 0;
}

3.枚举的问题

假设我们有一个简单的枚举类型:

class EnumValue {
public:enum Values {V1 = 100,V2,V3};
};

我们希望将EnumValue::Values枚举类型存储在QVariant中,并在需要时将其取出。我们可能会尝试以下代码:

QVariant var = EnumValue::V1;
EnumValue::Values ev = var.value<EnumValue::Values>();
qDebug() << "var = " << ev;

不幸的是,这段代码会导致编译错误:

错误: 'qt_metatype_id' is not a member of 'QMetaTypeId<EnumValue::Values>'

问题的根源

这个错误的根本原因是,QVariant在存储和取出数据时,依赖于Qt的元对象系统。为了能够正确地存储和取出自定义类型(包括枚举类型),这些类型必须被Qt的元对象系统所识别。枚举类型默认情况下并没有被Qt的元对象系统处理,因此QVariant无法直接存储和取出枚举类型。

解决方案

方法一:强制类型转换

一种简单的解决方法是使用强制类型转换。由于枚举类型本质上是一个整数,我们可以将QVariant中的值转换为int,然后再将其转换为枚举类型:

QVariant var = EnumValue::V1;
EnumValue::Values ev = static_cast<EnumValue::Values>(var.toInt());
qDebug() << "var = " << ev;

这种方法虽然可行,但它看起来不够优雅,并且容易出错。

方法二:使用Q_DECLARE_METATYPE宏

为了更优雅地解决这个问题,Qt提供了一个宏Q_DECLARE_METATYPE,它可以将自定义类型(包括枚举类型)注册到Qt的元对象系统中。我们只需要在枚举类型定义之后添加这个宏:

class EnumValue {
public:enum Values {V1 = 100,V2,V3};
};Q_DECLARE_METATYPE(EnumValue::Values)

然后,我们可以使用QVariant::fromValue()函数将枚举类型存储在QVariant中,并使用QVariant::value()函数将其取出:

QVariant var = QVariant::fromValue(EnumValue::V1);
EnumValue::Values ev = var.value<EnumValue::Values>();
qDebug() << "var = " << ev;

这次,代码将正确输出100,表示我们成功地将枚举类型存储并从QVariant中取出。

4.信号槽中使用自定义结构体

4.1.使用QVariant转换

首先定义一个结构体:

// 定义自定义结构体
struct MyStruct {int id;QString name;
};

然后用Q_DECLARE_METATYPE(MyStruct)注册自定义结构体

定义一个结构体并发送:

MyStruct stInfo;
stInfo.id = 100;
stInfo.name = "214124";
emit sig_sendInfo(QVariant::fromValue(stInfo));

接收端槽函数处理如下:

connect(信号类指针, &信号类::sig_trainInfo, 槽函数指针, [=](QVariant var){if (var.canConvert<TRANS_DOT_INFO>()){MyStruct stInfo = var.value<MyStruct>();//...}});

4.2.直接传递自定义结构体

在使用 Q_DECLARE_METATYPE 宏声明该结构体为元类型,然后在使用信号槽之前调用 qRegisterMetaType 函数进行注册。

// 声明元类型
Q_DECLARE_METATYPE(MyStruct)// 在合适的地方(如 main 函数中)进行注册
int main(int argc, char *argv[]) {QApplication a(argc, argv);// 注册自定义结构体到元对象系统qRegisterMetaType<MyStruct>("MyStruct");// 后续代码...return a.exec();
}

完整的实例代码如下:

#include <QObject>
#include <QMetaType>
#include <QDebug>
#include <QApplication>// 定义自定义结构体
struct MyStruct {int id;QString name;
};// 声明元类型
Q_DECLARE_METATYPE(MyStruct)// 发送信号的类
class Sender : public QObject {Q_OBJECT
public:explicit Sender(QObject *parent = nullptr) : QObject(parent) {}signals:// 定义包含自定义结构体参数的信号void mySignal(const MyStruct &data);public slots:void sendData() {MyStruct data;data.id = 1;data.name = "Example";// 发射信号emit mySignal(data);}
};// 接收信号的类
class Receiver : public QObject {Q_OBJECT
public:explicit Receiver(QObject *parent = nullptr) : QObject(parent) {}public slots:// 定义槽函数void handleSignal(const MyStruct &data) {qDebug() << "Received data - ID:" << data.id << ", Name:" << data.name;}
};int main(int argc, char *argv[]) {QApplication a(argc, argv);// 注册自定义结构体到元对象系统qRegisterMetaType<MyStruct>("MyStruct");// 创建发送者和接收者对象Sender sender;Receiver receiver;// 连接信号和槽QObject::connect(&sender, &Sender::mySignal, &receiver, &Receiver::handleSignal);// 触发信号sender.sendData();return a.exec();
}#include "main.moc"

5.性能开销

QVariant 是 Qt 中一个用于存储多种不同数据类型的通用容器类,它为数据的存储和处理提供了很大的灵活性,但也带来了一定的性能开销,下面从几个方面详细分析:

5.1. 内存开销

  • 额外的元数据存储QVariant 除了要存储实际的数据外,还需要存储关于该数据类型的元信息。这包括数据类型的标识(如 QMetaType::Type),用于在运行时识别存储的数据类型。这种额外的元数据存储会增加内存的使用量,尤其是在需要存储大量 QVariant 对象时,内存开销会更加明显。
  • 深拷贝问题:对于一些复杂的数据类型(如自定义类或容器),QVariant 在存储时可能会进行深拷贝。深拷贝意味着会复制整个对象及其所有成员,这会占用额外的内存空间。例如,当存储一个包含大量元素的 QList 时,QVariant 会复制该列表的所有元素,导致内存使用量显著增加。

5.2. 时间开销

  • 类型检查和转换:在使用 QVariant 时,经常需要进行类型检查和转换操作。例如,使用 canConvert 方法检查是否可以将 QVariant 转换为特定类型,以及使用 toXXX 系列方法(如 toInttoString)进行类型转换。这些操作需要在运行时进行类型判断和转换逻辑,会带来一定的时间开销。特别是在频繁进行类型检查和转换的场景下,性能影响会更加突出。
    QVariant var = "123";if (var.canConvert<int>()) {int num = var.toInt();}
  • 构造和析构:创建和销毁 QVariant 对象也会有一定的时间开销。构造 QVariant 对象时,需要初始化其内部的元数据和存储数据;析构时,需要释放相关的资源。对于简单的数据类型,这种开销可能相对较小,但对于复杂的数据类型,开销会相应增加。

5.3. 与直接使用具体类型的对比

  • 性能差异:相比于直接使用具体的数据类型,QVariant 的性能要低很多。直接使用具体类型时,编译器可以进行更多的优化,并且不需要进行额外的类型检查和转换。例如,直接使用 int 类型进行计算的速度会比使用 QVariant 存储 int 类型并进行操作快得多。
    // 直接使用 int 类型int a = 10;int b = 20;int result = a + b;// 使用 QVariant 存储 int 类型QVariant varA = 10;QVariant varB = 20;if (varA.canConvert<int>() && varB.canConvert<int>()) {int resultVariant = varA.toInt() + varB.toInt();}
  • 适用场景:虽然 QVariant 存在性能开销,但在某些场景下它是非常有用的。例如,当需要处理多种不同类型的数据,或者在不同模块之间传递数据且数据类型不确定时,QVariant 可以提供很大的便利。但在对性能要求极高且数据类型明确的场景下,应尽量避免使用 QVariant

6.总结

   QVariant 是 Qt 框架中一个极为实用的类,它为不同类型数据的存储与处理提供了统一的解决方案,不妨去试一试吧!

http://www.dtcms.com/a/583492.html

相关文章:

  • 学做效果图网站有哪些戴尔网站建设
  • 建设部网站怎么查询相关专业湖南省郴州市天气
  • 校园服装网站建设演示文稿永州微网站建设
  • 上犹网站建设企业网站怎么制作
  • 建材在哪些网站做介绍西安网页设计
  • 如何制作手机商城网站视频背景做网站背景
  • 做柜子设计的网站设计电脑公司网站设计
  • 网站推广策划方案范文中国工商银行官网
  • 青海市建设局网站打折网站模板
  • js做网站登录界面p2p网站策划
  • Docker 安全:如何安全地运行容器
  • 动作识别2——问题分析
  • 广州专业网站建设哪家公司好免费一键生成转账截图
  • 【经典书籍】《代码整洁之道》第二章“命名”精华讲解
  • 全国城市雕塑建设官方网站免费网站推广网址
  • 傻瓜式网站建设新网网站备案流程
  • 乾安网站建设公司电话用jsp做网站步骤
  • 音乐网站建设策划wordpress插件翻译
  • 如何“优雅”地处理,影刀RPA创建文件文件夹时"含非法字符"的报错?
  • 汽车网站和移动端建设方案300500启迪设计
  • 广州做网站优化澄海区建设局网站
  • 彩票娱乐网站建设成都网站建设询q479185700霸屏
  • 杭州 做网站wordpress评论加强
  • 合肥网站seo诊断住房城乡建设部门户网站主页
  • 爱站网关键词挖掘工具熊猫八师石河子精神文明建设网站
  • 太仓市建设招标网站网站推广和优化的原因网络营销
  • 欧美做暧网站大学思政类网站建设
  • 企业网站建设投标书国内手机怎么上google浏览器
  • Linux29初识网络:核心概念与分层逻辑
  • 秦皇岛网站开发费用外贸专业网站制作