如何在Qt中使用自定义数据类型 - zhezhelin - 博客园
Qt自定义组件方法

Qt⾃定义组件⽅法Qt⾃定义组件⽅法 该案例要实现⼀个如下图组件,右侧进度条会随着SpinBox数值的改变⽽做出相应变化。
功能简单,主要是通过⼀个简单例⼦掌握Qt组件的实现⽅法。
步骤1:UI设计器中,在需要放置⾃定义组件的位置放⼊Widget容器widge,并设置号Widget在UI界⾯的布局; 步骤2:如下如,添加新⽂件-->选择C++ Class,点击chose按钮,进⼊下⼀界⾯,输出Class name,选择Base class为QWidget,下⼀步-->完成。
步骤3:在myWidget.cpp类中添加如下代码:1//包含需要⽤到的组件2 #include <QSpinBox>3 #include <QProgressBar>4 #include <QHBoxLayout>56//构造函数中添加如下7 QSpinBox *spin = new QSpinBox(this);8 QProgressBar *progress = new QProgressBar(this);9 spin->setRange(0,100);10 progress->setRange(0,100);1112 QHBoxLayout *hLayout = new QHBoxLayout(this);13 hLayout->addWidget(spin);14 hLayout->addWidget(progress);1516 connect(spin,SIGNAL(valueChanged(int)),progress,SLOT(setValue(int)));View Code 步骤4:在UI设计界⾯,右键点击在步骤1中添加的Widget容器,弹出右键菜单,选择“提升为”弹出如下图窗⼝: 然后在提升的类名称中输⼊“myWidget”(步骤2中新添加类的名称,即⾃定义组件的对象名称),头⽂件⾃动补全,勾选全局包含,点击“添加”按钮,点击“提升”,在右侧组件属性窗⼝可以看出步骤1中添加的 widget组件的类名称变为myWidget,如下图: 编译运⾏软件效果: 以后在需要⽤到该⾃定义组件的地⽅,只需像步骤4中那样,右键菜单->提升为->选择“myWidget”即可。
qt窗口布局及自定义类-PPT课件

finddialog.cpp (4)
QHBoxLayout *topLeftLayout = new QHBoxLayout; topLeftLayout->addWidget(label); topLeftLayout->addWidget(lineEdit); QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout->addLayout(topLeftLayout); leftLayout->addWidget(caseCheckBox); leftLayout->addWidget(backwardCheckBox); 总布局 QVBoxLayout *rightLayout = new QVBoxLayout; 需要 rightLayout->addWidget(findButton); this rightLayout->addWidget(closeButton); rightLayout->addStretch(1); QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setMargin(30); 注意何时调用 mainLayout->setSpacing(6); addWidget, mainLayout->addLayout(leftLayout); 何时调用 mainLayout->addLayout(rightLayout); addLayout }
finddialog.cpp (3)
connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(enableFindButton(const QString &))); connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
qt窗口布局及自定义类

finddialog.cpp (4)
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);
QVBoxLayout *leftLayout = new QVBoxLayout;
qt窗口布局及自定义类
说明
以下将通过一个例子讲解自定义类的qt 程序设计的主要流程
要设计的界面
通过两个文件:finddialog.h 和 finddialog.cpp来实 现,即定义一个类
finddialog.h (1)
#ifndef FINDDIALOG_H #define FINDDIALOG_H #include <qdialog.h> class QCheckBox; class QLabel; class QLineEdit; class QPushButton; class FindDialog : public QDialog { Q_OBJECT public: FindDialog(QWidget *parent = 0, const char *name = 0); signals: void findNext(const QString &str, bool caseSensitive); void findPrev(const QString &str, bool caseSensitive); private slots: void findClicked(); void enableFindButton(const QString &text); private: QLabel *label; QLineEdit *lineEdit; QCheckBox *caseCheckBox; QCheckBox *backwardCheckBox; QPushButton *findButton; QPushButton *closeButton; }; #endif
qt中typedef的用法 -回复

qt中typedef的用法-回复typedef是C++中的一个关键字,用于给已有的数据类型或自定义的数据类型起一个新的名称。
通过使用typedef,可以方便地定义复杂的数据类型,并使代码更加易读和可维护。
本文将一步一步回答有关typedef在Qt中的使用的问题。
首先,让我们了解typedef的基本语法。
在C++中,使用typedef时需要先指定要定义的类型,然后使用关键字typedef给该类型起一个新的名称。
typedef的基本语法如下所示:typedef type new_name;其中,type是现有的数据类型,比如int、float、char等,或者是自定义的数据类型,比如结构体、枚举或类。
new_name是我们为该类型起的新名称。
在Qt中,我们通常使用typedef来定义复杂的数据类型,比如指针类型、函数指针类型和函数类型等。
下面,我们将通过几个例子来详细说明typedef在Qt中的用法。
1. typedef指针类型在Qt中,经常需要使用指针类型来操作动态分配的内存或者使用动态数组。
typedef可以方便地定义指针类型的新名称,使代码更易读。
例如,我们可以使用typedef定义一个指向int类型的指针类型,如下所示:typedef int* IntPtr;现在,我们可以使用IntPtr作为指向int类型的指针的新名称。
例如,我们可以声明一个使用IntPtr类型的指针变量,如下所示:IntPtr pInt;这等效于以下声明:int* pInt;2. typedef函数指针类型在Qt中,通过函数指针可以动态调用不同的函数。
typedef可以用于定义函数指针类型的新名称,使函数指针的声明更加清晰和简洁。
例如,我们可以使用typedef定义一个指向函数的指针类型,如下所示:typedef void (*FunctionPtr)(int);现在,我们可以使用FunctionPtr作为指向参数为int、返回类型为void 的函数指针的新名称。
Qt--自定义Model

Qt--⾃定义Model众所周知,Qt提供了⼀套Model/View框架供开发者使⽤,Model⽤来提供数据, View则⽤来提供视觉层的显⽰。
实际上这是⼀套遵循MVC设计模式的GUI框架,因为Qt还提供了默认的Delegate作为Controller来作为控制器。
MVC的好处这⾥就不多说了,为了开发者使⽤⽅便,Qt还提供了基于项(Item)的Model/View实现----QXxxWidget(QTableWidget、QListWidget等),对于⼀些简单的应⽤场景,这已经⾜够了并且使⽤起来⾮常⽅便。
这⾥我们简单介绍下如何使⽤⾃定义的数据模型,来满⾜各种花式的要求。
1. 选择合适的Model继承1.1 标准数据模型Qt实现了4类标准数据模型供我们在不同的场景下使⽤:1. QStringListModel:存储字符串列表。
2. QStandardItemModel:存储树状结构的任意数据。
3. QFileSystemModel:存储本地⽂件系统上的⽂件和⽬录信息。
4. QSqlQueryModel、QSqlRelationalTableModel、QSqlTableModel:存储关系型数据库中的数据。
如果使⽤情况和上述情况之⼀⽐较相似,则可以考虑继承对应的模型类,并重新实现少数虚函数。
1.2 抽象数据模型抽象数据模型有3类:1. QAbstractItemModel:项模型,这是所有数据模型的基类。
2. QAbstractListModel:列表模型,结合QListView使⽤最合适。
3. QAbstractTableModel:表模型,结合QTableView使⽤最合适。
2. 继承抽象模型Qt官⽅提供了完善的来帮助开发者来⾃定义模型类。
根据官⽹,⼦类化模型需要开发者实现的功能(即需要重新实现的虚函数)按功能来分可以分为三类:项数据处理:这⼜可以分为三类----只读访问、可编辑、调整⼤⼩。
Qt自定义配置文件configfile

Qt⾃定义配置⽂件configfile1、定义configfile函数为外部静态函数,⽅便其他直接⽂件引⽤。
2、配置⽂件初始化,先判断路径,没有创建,然后新建配置信息。
3、配置⽂件读取,写⼊采取QSetting分组,键值对的⽅式。
configfile.h#ifndef CONFIGFILE_H#define CONFIGFILE_H#include "globe_data.h"#include "system_config.h"class ConfigFile{public:ConfigFile();~ConfigFile();//----------配置⽂件----------//static int ConfigFile_Init();static void ConfigFile_Read_SetUp(Globe_Data *g);//返回读取的个数static void ConfigFile_Write(Globe_Data *g);};#endif// CONFIGFILE_Hconfigfile.cpp#include "configfile.h"#include <QDir>#include <QSettings>#include <QDebug>ConfigFile::ConfigFile(){}ConfigFile::~ConfigFile(){}int ConfigFile::ConfigFile_Init(){QDir parameterDir;QFile file;Globe_Data globeData;//数据配置⽂件路径创建****************{//QDir::currentPath()if(parameterDir.exists(QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG) )){qDebug("the file /Navigator_WorkSpace/DataStore/DataConfig is exists");}else{qDebug("the file /Navigator_WorkSpace/DataStore/DataConfig is not exists !");if(parameterDir.mkpath(QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG) ) ){qDebug("the dir /Navigator_WorkSpace/DataStore/DataConfig is created!!");}else{qCritical("/Navigator_WorkSpace/DataStore/DataConfig is falied to create !!");}}}//数据配置⽂件夹创建****************{ // /Navigator_WorkSpace/DataStore/DataConfig/config.inifile.setFileName( QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG)+\QString::fromUtf8(FILE_CONFIG));if(!file.open(QIODevice::ReadOnly)){qDebug("配置⽂件不存在!准备创建!");//----------写⼊数据库配置数据----------//QSettings set( QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG)+\QString::fromUtf8(FILE_CONFIG) , QSettings::IniFormat);//⽂件存在则打开,不存在则创建set.setIniCodec("UTF-8");set.beginGroup("SQL-Standard");set.setValue("hostName","127.0.0.1");set.setValue("databasePath","/Navigator_WorkSpace/HY_01/");set.setValue("databaseName","/Navigator_WorkSpace/HY_01/HT_12.db");set.setValue("username","");set.setValue("password","");set.setValue("databaseType","QSQLITE");set.setValue("testOnBorrow",true);set.setValue("testOnBorrowSql","SELECT 1");set.setValue("maxWaitTime",1000);set.setValue("waitInterval",200);set.setValue("maxConnectionCount",5);set.endGroup();//----------写⼊SetUp界⾯数据----------//set.beginGroup("SetUp-AppConfig");set.setValue("depth",1);set.setValue("timeDate",2);set.setValue("time",3);set.setValue("ID",28);set.endGroup();file.close();return -1;}else{qDebug()<<"找到配置⽂件,正在打开!";return0;}}}void ConfigFile::ConfigFile_Read_SetUp(Globe_Data *g){QSettings set( QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG)+\QString::fromUtf8(FILE_CONFIG) , QSettings::IniFormat);//⽂件存在则打开,不存在则创建set.setIniCodec("UTF-8");set.beginGroup("SetUp-AppConfig");g->configFileInfor.mutex.lock();g->configFileInfor.configValue.str_depth = set.value("depth").toString();g->configFileInfor.configValue.str_timeDate = set.value("timeDate").toString();g->configFileInfor.configValue.str_time = set.value("time").toString();g->configFileInfor.configValue.str_ID = set.value("ID").toString();g->configFileInfor.mutex.unlock();//qDebug()<<"进程所在⽬录="<<QDir::currentPath();进程⼯作位置set.endGroup();}void ConfigFile::ConfigFile_Write(Globe_Data *g){QSettings set( QString::fromUtf8(DIR_WORKSPACE)+\QString::fromUtf8(DIR_CONFIG)+\QString::fromUtf8(FILE_CONFIG) , QSettings::IniFormat);//⽂件存在则打开,不存在则创建set.setIniCodec("UTF-8");set.beginGroup("SetUp-AppConfig");g->configFileInfor.mutex.lock();set.setValue("depth",g->configFileInfor.configValue.str_depth);set.setValue("timeDate",g->configFileInfor.configValue.str_timeDate);set.setValue("time",g->configFileInfor.configValue.str_time);set.setValue("ID",g->configFileInfor.configValue.str_ID); g->configFileInfor.mutex.unlock();set.endGroup();}。
qt中typedef的用法

在C++编程中,typedef是一种用于定义类型别名的关键字。
在Qt框架中,typedef也常被用于简化复杂数据类型的声明和使用。
以下是在Qt中使用typedef的一些常见场景:1.定义新的数据类型:2.cpp复制代码typedef QList<int> IntList;这样,你就可以使用IntList作为QList<int>的别名,而不是每次都写QList<int>。
2. 定义函数指针类型:cpp复制代码typedef void(*SignalType)(int);在Qt中,信号(signals)和槽(slots)机制经常使用这种函数指针类型。
上面的代码定义了一个名为SignalType的函数指针类型,该函数接受一个int参数并返回void。
3. 定义枚举类型:cpp复制代码typedef QFlags<Qt::AlignmentFlag> AlignmentFlags;Qt的QFlags模板类用于表示位集,它可以方便地处理枚举值的组合。
上面的代码定义了一个新的类型AlignmentFlags,它是Qt::AlignmentFlag枚举类型的位集别名。
4. 简化复杂类型声明:对于复杂的模板类型或指针类型,typedef可以帮助你简化声明。
cpp复制代码typedef QSharedPointer<QObject> QObjectPointer;这样,你就可以使用QObjectPointer代替原始的复杂类型。
5. 定义数组类型:cpp复制代码typedef QList<int> IntList;typedef IntList::ConstIterator IntListConstIterator;上面的代码定义了一个常量迭代器类型IntListConstIterator,它是IntList的常量迭代器类型别名。
6. 定义函数指针或成员函数指针类型:这些用法与常规C++中的用法相似,但也可以在Qt中使用。
qtself.用法-概述说明以及解释

qtself.用法-概述说明以及解释1.引言1.1 概述QTSELF(Query Tuple Self-exploring Language Framework)是一种面向对象的编程语言框架,主要用于数据查询与处理。
它提供了一种灵活且高效的方式来处理各种类型的数据,并支持自我探索和操作。
QTSELF的设计目标是简化数据处理的过程,提高开发效率,并使得数据查询和分析更加直观和易于理解。
QTSELF的特点之一是其灵活性。
它允许开发人员在查询过程中自由定义和编写各种操作,包括对数据的过滤、排序、聚合、连接等。
这种灵活性使得开发人员可以根据具体的需求和场景设计并执行复杂的数据处理逻辑,从而更好地满足用户的需求。
另一个重要特点是QTSELF的自我探索能力。
在数据处理过程中,QTSELF可以根据数据的结构和特性进行自动推理和分析,从而生成相应的查询和操作代码。
这种自我探索能力使得开发人员无需事先了解数据的具体细节,可以直接对数据进行查询和处理,大大简化了开发的复杂性。
QTSELF的基本用法非常简单直观。
开发人员只需要按照特定的语法规则编写查询语句,并指定相应的操作和条件。
QTSELF会自动解析和执行查询语句,并返回相应的结果。
同时,QTSELF还提供了丰富的API和工具,使得开发人员可以更加灵活和高效地使用和扩展框架的功能。
QTSELF在实际应用场景中具有广泛的适用性。
无论是数据分析、业务决策还是科学研究,QTSELF都可以为开发人员提供强大的支持。
它可以用于处理各种类型的数据,包括结构化数据、非结构化数据、图像数据等。
同时,QTSELF还支持多种数据源和格式,例如数据库、CSV文件、JSON数据等,使得开发人员能够方便地处理不同来源和格式的数据。
总之,QTSELF是一个功能强大、灵活易用的数据查询与处理框架。
它的特点包括灵活性、自我探索能力和简单直观的使用方法。
在不同的应用场景中,QTSELF都能够为开发人员提供快速、高效和准确的数据处理解决方案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如何在Qt中使用自定义数据类型 - zhezhelin - 博客园如何在Qt中使用自定义数据类型Q_DECLARE_METATYPE,Qt自定义类型这里我们使用下面这个struct来做说明(这里不管是struct还是class都一样):复制代码QVariant为了能在QVariant中使用自定义数据类型做,需要使用Q_DECLARE_METATYPE()来向Qt的元系统声明这个自定义类型。
如下列所示:复制代码在作为QVariant传递自定义数据类型时,需要使用QVariant::fromValue()或者qVariantFromValue:复制代码为了更方便一点,你可以在自定义类型中定义一个QVariant() 类型转换符:复制代码这样我们便可以像下面这样使用了:复制代码信号和槽对于直接连接类型(默认情况下就是直接连接)而言,使用自定义数据类型做信号参数不需要做其他其他处理,就像内置数据类型一样:复制代码但在跨线程时如果你还这么做,编译器就会给出警告了:复制代码这时我们需要先注册Player:qRegisterMetaType<Player>("Player");qRegisterMetaType<Player>( ); (上面那个是错误的,除非名字刚好和类名一样)connect(sender, SIGNAL(playerCreated(const Player&)), receiver, SLOT(addPlayer(const Player&)));复制代码QDebug最好是能这样:复制代码而不是这样:复制代码怎么做呢?我们需要对QDebug<<操作符重载一下:复制代码QDataStream跟上面的QDebug很像,我们也需要重载一下<<操作符:复制代码QSettings为了能在QSettings中使用自定义数据类型,需要让Qt的元系统知道有此类型,就像上面介绍QVariant部分一样,另外还要提供相应的QDataStream操作符,还必须注册这个流操作符:复制代码如此处理之后我们就可以像下面这样使用了:复制代码复制代码参考:QString QSettingsPrivate::variantToString(const QVariant &v){QString result;switch (v.type()) {case QVariant::Invalid:result = QLatin1String("@Invalid()");break;case QVariant::ByteArray: {QByteArray a = v.toByteArray();result = QLatin1String("@ByteArray("); result += QString::fromLatin1(a.constData(), a.size()); result += QLatin1Char(')');break;}case QVariant::String:case QVariant::LongLong:case QVariant::ULongLong:case QVariant::Int:case QVariant::UInt:case QVariant::Bool:case QVariant::Double:case QVariant::KeySequence: {result = v.toString();if (result.startsWith(QLatin1Char('@')))result.prepend(QLatin1Char('@'));break;}#ifndef QT_NO_GEOM_VARIANTcase QVariant::Rect: {QRect r = qvariant_cast<QRect>(v);result += QLatin1String("@Rect(");result += QString::number(r.x());result += QLatin1Char(' ');result += QString::number(r.y());result += QLatin1Char(' ');result += QString::number(r.width());result += QLatin1Char(' ');result += QString::number(r.height());result += QLatin1Char(')');break;}case QVariant::Size: {QSize s = qvariant_cast<QSize>(v);result += QLatin1String("@Size("); result += QString::number(s.width());result += QLatin1Char(' ');result += QString::number(s.height());result += QLatin1Char(')');break;}case QVariant::Point: {QPoint p = qvariant_cast<QPoint>(v);result += QLatin1String("@Point("); result += QString::number(p.x());result += QLatin1Char(' ');result += QString::number(p.y());result += QLatin1Char(')');break;}#endif // !QT_NO_GEOM_VARIANTdefault: {#ifndef QT_NO_DATASTREAMQByteArray a;{QDataStream s(&a, QIODevice::WriteOnly);s.setVersion(QDataStream::Qt_4_0);s << v;}result = QLatin1String("@Variant(");result += QString::fromLatin1(a.constData(), a.size());result += QLatin1Char(')');#elseQ_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");#endifbreak;}}return result;}qsetting为了让保存的ini文件能和ascii兼容,所以∙我们将ini文件中的键值读入到 QVariant 中,需要两个步骤:∙因为文件内的一些字符被转义了,比如"\x1234\t\0"等,所以需要 unescape ∙从 unescape 后的字符串构造出 QVariant∙当将QVariant写入文件时:∙将 QVariant 转换成字符串∙处理字符串中的特殊字符,即 escapeIf you store types that QVariant can't convert to QString (e.g., QPoint, QRect, and QSize), Qt uses an @-based syntax to encode the type. For example:pos = @Point(100 100)To minimize compatibility issues, any @ that doesn't appear at the first position in the value or that isn't followed by a Qt type (Point, Rect, Size, etc.) is treated as a normal character.不能转化为 QString 的QVariant 会以@-based 编码,base为(Point, Rect, Size, etc.)Although backslash is a special character in INI files, most Windows applications don't escape backslashes (\) in file paths:windir = C:\WindowsQSettings always treats backslash as a special character and provides no API for reading or writing such entries.反斜杠不能用在键值中The INI file format has severe restrictions on the syntax of a key. Qt works around this by using % as an escape character in keys. In addition, if you save a top-level setting (a key with no slashes in it, e.g., "someKey"), it will appear in the INI file's "General" section. To avoid overwriting other keys, if you save something using the a key such as"General/someKey", the key will be located in the"%General" section, not in the "General" section.key用%转义。