这里写目录标题
- 1、Qt顺序容器类和关联容器类
- 2、Qt迭代器(Java类型和STL类型)
- 3、Qt foreach关键字用法
- 4、Qt类库模块划分
- 5、Qt字符串与数字之间的转换方法
- 6、Qt QString类及常用函数功能
- 7、Qt QSpinBox使用
- 8、Qt数值输入组件和显示组件用法
- 9、Qt获取当前时间
- 10、Qt定时器及实现
- 11、Qt QComboBox下拉框及用法
- 12、Qt QPlainTextEdit用法
- 13、Qt QListWidget和QToolButton用法
- 14、Qt QTreeWidget和QDockWidget用法
- 15、Qt QTableWidget
- 16、Qt Model/View(模型/视图)结构
- 17、Qt QFileSystemModel功能及用法
- 18、Qt QStringListModel
- 18、Qt QStringListModel
1、Qt顺序容器类和关联容器类
-
顺序容器类:QList、QLinkedList、QVector、QStack、QQueue。
-
QList
-
以数组列表的形式实现,以下标索引的方式对数据项访问。
-
用于添加、插入、替换、移动的函数:insert()、replace()、removeAt()、move()、swap()、append()、prepend()、removeFirst() 和 removeLast() 等。
-
QList 提供下标索引方式访问数据项,如同数组一样,也提供 at() 函数。
QList<QString> list;//定义一个Qlist容器变量list list << "one" << "two" << "three"; QString str1=list[1]; //str1=="two" QString str0=list.at(0); //str0=="one"
-
QList 的 isEmpty() 函数在数据项为空时返回 true,size() 函数返回数据项的个数。
-
-
QLinkedList
- QLinkedList 是链式列表,数据项不是用连续的内存存储的,它基于迭代器访问数据项,并且插入和删除数据项的操作时间相同。
- 不提供基于下标索引的数据项访问。
- QLinkedList 的其他接口函数与 QList 基本相同。
-
QVector
- QVector 提供动态数组的功能,以下标索引访问数据。
- QVector 的函数接口与 QList 几乎完全相同,QVector 的性能比 QList 更高,因为 QVector
的数据项是连续存储的。
-
QStack
-
QStack 是提供类似于堆栈的后入先出(LIFO)操作的容器类,push() 和 pop() 是主要的接口函数。
QStack<int> stack; stack.push(10); stack.push(20); stack.push(30); while (!stack.isEmpty()) cout << stack.pop() << endl; //程序输出30 20 10
-
-
QQueue
-
QQueue 是提供类似于队列先入先出(FIFO)操作的容器类。enqueue() 和 dequeue() 是主要操作函数。
QQueue<int> queue; queue.enqueue(10); queue.enqueue(20); queue.enqueue(30); while(!queue.isEmpty()) cout<<queue.dequeue()<<endl; //程序输出10 20 30
-
-
-
关联容器类:QMap、QMultiMap、QHash、QMultiHash、QSet。
(QMultiMap 和 QMultiHash 支持一个键关联多个值,QHash 和 QMultiHash 类使用散列函数进行查找,查找速度更快。)
-
QSet
-
QSet 是基于散列表的集合模板类,它存储数据的顺序是不定的,查找值的速度非常快。 QSet 内部就是用 QHash 实现的。
-
定义 QSet 容器和输入数据的实例代码如下:
QSet<QString> set; set<<"dog"<<"cat"<<"tiger";
-
测试一个值是否包含于这个集合,用 contains() 函数,示例如下:
if(!set.contains("cat")) ...
-
-
QMap
-
QMap<Key, T> 提供一个字典(关联数组),一个键映射到一个值。QMap 存储数据是按照键的顺序,如果不在乎存储顺序,使用 QHash 会更快。
-
定义 QMap<QString,int> 类型变量和赋值的示例代码如下:
QMap<QString,int> map; map["one"] = 1;//one是Key(键),1是T(值) map["two"] = 2; map["three"] = 3;
-
使用 insert() 函数赋值,或 remove() 移除一个键值对,示例如下:
map.insert("four",4); map.remove("two");
-
要查找一个值,使用运算符“[]”或 value() 函数,如果在映射表中没有找到指定的键,会返回一个缺省构造值,例如,如果值的类型是字符串,会返回一个空的字符串。,示例如下:
int num1 = map["one"]; int num2 = map.value("two");//value类似于vector的at()函数
-
在使用 value() 函数查找键值时,还可以指定一个缺省的返回值,示例如下:
timeout = map.value("TIMEOUT",30);//如果在map中找到键“TIMEOUT”就返回关联的值,否则返回值为30
-
-
QMultiMap
-
QMultiMap 是 QMap 的子类,是用于处理多值映射的便利类。多值映射就是一个键可以对应多个值。QMap 正常情况下不允许多值映射,除非使用 QMap::insertMulti() 添加键值对。
-
QMultiMap 是 QMap 的子类,所以 QMap 的大多数函数在 QMultiMap 都是可用的,但是有几个特殊的,QMultiMap::insert() 等效于 QMap::insertMulti() , QMultiMap::replace() 等效于 QMap::insert()。
QMultiMap<QString,int> map1,map2,map3; map1.insert("plenty",100); map1.insert("plenty",200);//map1.size()==2 map2.insert("plenty",300);//map2.size()==1 map3 = map1+map2;//map3.size()==3
-
QMultiMap 不提供“[]”操作符,使用 value() 函数访问最新插入的键的单个值。如果要获取一个键对应的所有值,使用 values() 函数,返回值是 QList 类型。
QList<int> values = map.values("plenty"); for(int i=0;i<values.size();i++){ cout<<values.at(i)<<endl; }
-
-
QHash
- QHash 是基于散列表来实现字典功能的模板类,QHash<Key,T> 存储的键值对具有非常快的查找速度。
- QHash 与 QMap 的功能和用法相似,区别在于以下几点:
- QHash 比 QMap 的查找速度快;
- 在 QMap 上遍历时,数据项是按照键排序的,而 QHash 的数据项是任意顺序的;
- QMap 的键必须提供“<”运算符,QHash 的键必须提供“==”运算符和一个名称为 qHash() 的全局散列函数。
-
QMultiHash
- QMultiHash 是 QHash 的子类,是用于处理多值映射的便利类,其用法与 QMultiMap 类似。
-
2、Qt迭代器(Java类型和STL类型)
-
Java类型迭代器
-
对于每个容器类,有两个 Java 类型迭代器:一个用于只读操作,一个用于读写操作,各个Java 类型的容器类见表
容器类 只读迭代器 读写迭代器 QList,QQueue QListIterator QMutableListIterator QLinkedList QLinkedListIterator QMutableLinkedlistIterator QVector,QStack QVectorIterator QMutableVectorIterator QSet QSetIterator QMutableSetIterator QMap<Key, T>, QMultiMap<Key, T> QMapIterator<Key, T> QMutableMapIterator<Key, T> QHash<Key, T>, QMultiHash<Key, T> QHashIterator<Key, T> QMutableHashlterator<Key, T> -
顺序容器的迭代器使用
-
访问QList容器的所有数据项:
//QList<QString> 容器对象 list 作为参数传递给 QListIterator<QString> 迭代器 i 的构造函数,i 用于对 list 作只读遍历。起始时刻,迭代器指针在容器第一个数据项的前面;调用 hasNext() 判断在迭代器指针后面是否还有数据项,如果有,就调用 next() 跳过一个数据项,并且 next() 函数返回跳过去的那个数据项。 QList<QString> list; list<<"A"<<"B"<<"C"<<"D"; QListIterator<QString> i(list); while(i.hasNext()) qDebug()<<i.next();
-
QListItemtor 用于移动指针和读取数据的函数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6f4tbos8-1589382598197)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327150851269.png)]
-
QListIterator 是只读访问容器内数据项的迭代器,若要在遍历过程中对容器的数据进行修改, 需要使用 QMutableListlterator。
QList<int> list; list<<1<<2<<3<<4; QMutableListIterator<int> i(list); i.toBack(); while(i.hasPrevious()){//从后往前遍历 if(i.previous()%2!=0)//删除容器中数据为奇数的项 i.remove(); }
-
-
关联容器的迭代器使用
-
对于关联容器类 QMap,使用 QMapIterator 和 QMutableMapIterator 迭代器类,它们具有表 3 所示的所有函数,主要是增加了 key() 和 value() 函数用于获取刚刚跳过的数据项的键和值。
-
例如,下面的代码将删除键(城市名称)里以“City”结尾的数据项:
QMap<QString, QString> map; map.insert("Paris", "France"); map.insert("New York", "USA"); map.insert("Mexico City", "USA"); map.insert("Moscow", "Russia"); ... QMutableMapIterator<QString, QString> i(map); while (i.hasNext ()) { if (i.next().key().endsWith("City")) i.remove(); }
-
如果是在多值容器里遍历,可以用 findNext() 或 findPrevious() 查找下一个或上一个值。如下面的代码将删除上一示例代码中 map 里值为“USA”的所有数据项:
QMutableMapIterator<QString,QString> i(map); while(i.findNext("USA")) i.remove();
-
-
-
STL类型迭代器
-
对于每一个容器类,都有两个 STL 类型迭代器:一个用于只读访问,一个用于读写访问。无需修改数据时一定使用只读迭代器,因为它们速度更快。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7ho1Xf8-1589382598199)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327152609407.png)]
-
注意,在定义只读迭代器和读写迭代器时的区别,它们使用了不同的关健字,const_iterator 定义只读迭代器,iterator 定义读写迭代器。此外,还可以使用 const_reverse_iterator 和 reverse_iterator 定义相应的反向迭代器。
-
与 Java 类型的迭代器不同,STL 迭代器直接指向数据项。
-
begin() 函数使迭代器指向容器的第一个数据项,end() 函数使迭代器指向一个虚拟的表示结尾的数据项,end() 表示的数据项是无效的,一般用作循环结束条件。
-
顺序容器类的迭代器和用法:
-
下面的示例代码将 QList list 里的数据项逐项输出:
QList<QString> list; list << "A" << "B" << "C" << "D"; QList<QString>::const_iterator i; for(i=list.constBegin();i!=list.constEnd();i++) qDebug<<*i; //constBegin()和 constEnd() 是用于只读迭代器的,表示起始和结束位置。
若使用反向读写迭代器,并将上面示例代码中 list 的数据项都改为小写,代码如下:
QList<QString>::reverse_iterator i; for(i=list.rbegin();i!=list.rend();i++) *i=i->toLower();//将数据项A B C D改为小写字母
-
-
关联容器类的迭代器用法:
-
对于关联容器类 QMap 和 QHash,迭代器的操作符返回数据项的值。如果想返回键,使用 key() 函数。对应的,用 value() 函数返回一个项的值。
例如,下面的代码将 QMap<int,int> map 中所有项的键和值输出:
QMap<int,int> map; ... QMap<int,int>::const_iterator i; for(i=map.constBegin();i!=constEnd();i++) qDebug<<i.key()<<":"<<i.value()<<endl;
-
Qt API 包含很多返回值为 QList 或 QStringList 的函数,要遍历这些返回的容器,必须先复制。由于 Qt 使用了隐式共享,这样的复制并无多大开销。
例如,下面的代码是正确的:
const QList<int> sizes=splitter->size(); QList<int>::const_iterator i; for(i=sizes.begin();i!=sizes.end();i++) ...
下面的代码是错误的:
QList<int>::const_iterator i; for (i = splitter->sizes().begin(); i != splitter->sizes().end(); ++i)
-
隐式共享是对象的管理方法。一个对象被隐式共享,只是传递该对象的一个指针给使用者,而不实际复制对象数据,只有在使用者修改数据时,才实质复制共享对象给使用者。如在上面的代码中,splitter->sizes() 返回的是一个 QListM 表对象 sizes,但是实际上代码并不将 splitter->sizes() 表示的列表内容完全复制给变量 sizes,只是传递给它一个指针,只有当 sizes 发生数据修改时,才会将共享对象的数据复制给 sizes,这样避免了不必要的复制,减少了资源占用。
-
-
3、Qt foreach关键字用法
-
Qt提供一个关键字 foreach (实际是 里定义的一个宏)用于方便地访问容器里所有数据项。
-
foreach 关键字用于遍历容器中所有的项,使用 foreach 的句法是:
foreach(variable,container);//foreach(和容器重元素类型相同的变量,容器)
-
例如,使用 foreach 遍历一个 QLinkedList 的示例代码如下:
QLinkedList<QString> list; ... QString str; foreach(str,list) qDebug()<<str;
-
用于迭代的变量也可以在 foreach 语句里定义,foreach 语句也可以使用花括号,可以使用 break 退出迭代,示例代码如下:
QLinkedList<QString> list; ... foreach(const QString &str,list){ if(str.isEmpty()) break; qDebug()<<str; }
-
对于 QMap 和 QHash,foreach 会自动访问“键-值”对里的值,所以无需调用 values()。如果需要访问键则可以调用 keys(),示例代码如下:
QMap<QString,int> map; ... foreach(const QString &str,map.key()) qDebug()<<str<<":"<<map.value(str);
-
对于多值映射,可以使用两重 foreach 语句,示例代码如下:
QMultiMap<QString,int> map; ... foreach(const QString &str,map.uniqueKeys()){ foreach(int i,map.values(str)) qDebug()<<str<<":"<<i; }
-
foreach 关徤字遍历一个容器变量是创建了容器的一个副本,所以不能修改原来容器变量的数据项。
4、Qt类库模块划分
Qt 类库里大量的类根据功能分为各种模块,这些模块又分为以下几大类:Qt 基本模块(Qt Essentials)、Qt 附加模块(Qt Add-Ons)、增值模块(Value-AddModules)、技术预览模块(Technology Preview Modules)、Qt 工具(Qt Tools)。
-
Qt 基本模块(Qt Essentials):提供了 Qt 在所有平台上的基本功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8jhhRni9-1589382598201)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327160443011.png)]
-
Qt Core 模块是 Qt 类库的核心,所有其他模块都依赖于此模块,如果使用 qmake 构建项目, 则 Qt Core 模块是自动被加入项目的。
-
Qt GUI 模块提供了用于开发 GUI 应用程序的必要的类,使用 qmake 构建应用程序时,Qt GUI 模块是自动被加入项目的。如果项目中不使用 GUI 功能,则需要在项目配置文件中加入如下的一行:
QT -= gui
-
其他的模块一般不会被自动加入到项目,如果需要在项目中使用某个模块,则可以在项目配置中添加此模块。例如,如果需要在项目中使用 Qt Multimedia 和 Qt Multimedia Widgets 模块,需要在项目配置文件中加入如下的语句:
QT += multimedia multimediawidgets
-
需要在项目中使用 Qt SQL 模块,就在项目配置文件中加入如下的语句:
QT += sql
-
-
Qt 附加模块(Qt Add-Ons):实现一些特定功能的提供附加价值的模块。
- Qt 附加模块可以实现一些特定目的。这些模块可能只在某些开发平台上有,或只能用于某些操作系统,或只是为了向后兼容。用户安装时可以选择性地安装这些附加模块。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SwfSJMfb-1589382598204)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327161153101.png)]
-
增值模块(Value-AddModules):单独发布的提供额外价值的模块或工具。
- 这些模块只在商业版许可的 Qt 里才有。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dlft45W1-1589382598205)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327161333612.png)]
-
技术预览模块(Technology Preview Modules):一些处于开发阶段,但是可以作为技术预览使用的模块。
- 技术预览模块就是一些还处于开发和测试阶段的模块。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0OFqfpza-1589382598207)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327161405830.png)]
-
Qt 工具(Qt Tools):帮助应用程序开发的一些工具。
- 在所有支持的平台上都可以使用,用于帮助应用程序的开发和设计。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KspGSvFH-1589382598208)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327161432247.png)]
5、Qt字符串与数字之间的转换方法
界面设计时使用最多的组件恐怕就是 QLabel 和 QLineEdit 了,QLabel 用于显示字符串,QLineEdit 用于显示和输入字符串。这两个类都有如下的两个函数用于读取和设置显示文字。
QString text() const
void setText(const QString &)
-
QString 类是 Qt 程序里经常使用的类,用于处理字符串。QString 类可以进行字符串与数字之间的转换,使用 QLineEdit 就可以实现数字量的输入与输出。
-
QString 类从字符串转换为整数的函数有:
int toInt(bool * ok = Q_NULLPTR, int base = 10) const long toLong (bool * ok = Q_NULLPTR, int base = 10) const short toShort (bool * ok = Q_NULLPTR, int base = 10) const uint toUInt (bool *ok = Q_NULLPTR, int base = 10) const ulong toULong (bool *ok = Q_NULLPTR, int base = 10) const
这些函数如果不设置参数,缺省表示从十进制表示的字符串转换为整数;若指定整数基参数,还可以直接将二进制、十六进制字符串转换为整数。
-
QString 将字符串转换为浮点数的函数有:
double toDouble(bool *ok = Q_NULLPTR) const float toFloat (bool * ok = Q_NULLPTR) const
-
可以使用 QString 的静态函数 number() 和 asprintf(),也可以使用其公共函数 setNum() 和 sprintf()将数值转换为字符串。setNum 和 number 有多个重载函数定义,可以处理各种类型的整数和浮点数,在处理整数时还可以指定进制,例如将一个整数直接转换为十六进制或二进制字符串。
//将浮点数保留两位小数,转换为QString QString str; str=QString::number(total,'f',2); str=QString::asprintf ("%.2f", total); str=str.setNum(total,'f',2); str=str.sprintf ("%.2f",total);
eg:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NslIuB6Z-1589382598209)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200327163556248.png)]
//计算按钮的槽函数 void Widget::on_btnCal_clicked() { QString str=ui->editNum->text () ;//读取n数量n int num=str.toInt(); str=ui->editPrice->text (); //读取"单价" float price=str.toFloat(); float total=num*price; str=str.sprintf ("%.2f",total); ui->editTotal->setText(str); }
-
进制转换
-
将一个整数转换为不同进制的字符串,可以使用 QString 的函数 setNum() 或静态函数 number(),它们的函数原型是:
Qstring &setNum (int n, int base = 10) QString number (int n, int base = 10)
其中 n 是待转换的整数,base 是使用的进制,缺省为十进制,也可以指定为十六进制和二进制。
//以下是读取十进制数转换为二进制和十六进制字符串的按钮的槽函数代码: void Widget::on_btnDec_clicked() { //读取十进制数,转换为其他进制 QString str=ui->editDec->text(); int val=str.toInt();//缺省为十进制 // str=QString::number(val, 16);//转换为十六进制的字符串 str=str.setNum (val, 16); //十六进制 str=str.toUpper();//将字符串转换为大写字母-----转换为小写字母:toLower() ui->editHex->setText(str); str=str.setNum (val, 2) ; //二进制 // str=QString::number(val,2); ui->editBin->setText(str); }
-
下面是读取二进制字符串,然后转换为十进制和十六进制显示的按钮的槽函数代码。
void Widget::on_btnBin_clicked() { //读取二进制数,转换为其他进制的数 QString str=ui->editBin->text () ; //读取二进制字符串 bool ok; int val=str.tolnt (&ok, 2) ; //以二进制数读入,ok表示转换是否成功,成功则ok为true,失败则ok为false。 str=QString::number (val, 10) ;//数字显示为十进制字符串 ui->editDec->setText(str); str=str.setNum (val, 16) ; //显示为十六进制,将val转换为16进制 str=str.toUpper();//将字符串转换为大写字母 ui->editHex->setText(str); }
-
6、Qt QString类及常用函数功能
-
QString 存储字符串釆用的是 Unicode 码,每一个字符是一个 16 位的 QChar,而不是 8 位的 char,所以 QString 处理中文字符没有问题,而且一个汉字算作是一个字符。
-
append() 和 prepend():append() 在字符串的后面添加字符串,prepend() 在字符串的前面添加字符串。
QString str1 = "卖",str2 = "拐"; QString str3 = str1; str1.append(str2);//str1="卖拐" str3.prepend(str2);//str3="拐卖"
-
toUpper() 和 toLower():toUpper() 将字符串内的字母全部转换为大写形式,toLower() 将字母全部转换为小写形式。
-
count()、size() 和 length():count()、size() 和 length() 都返回字符串的字符个数,这 3 个函数是相同的,但是要注意,字符串中如果有汉字,一个汉字算一个字符。
-
trimmed() 和 simplified():trimmed() 去掉字符串首尾的空格,simplified() 不仅去掉首尾的空格,中间连续的空格也用一个空格替换。
-
indexOf () 和 lastIndexOf ():
-
indexOf()函数原型:
int indexOf (const QString &str, int from = 0 , Qt::CaseSensitivity cs = Qt::CaseSensitive) const
其功能是在自身字符串内查找参数字符串 str 出现的位置,参数 from 是幵始查找的位置,Qt::CaseSensitivity cs 参数指定是否区分大小写。
-
lastIndexOf() 函数则是查找某个字符串最后出现的位置。
QString str1="G:\Qt5Book\QT5.9Study\qw.cpp"; N=str1.indexOf("5.9"); // N=13 N=str1.lastIndexOf("\\"); //N=21 //提示,"\" 是转义字符,如果要查找 "\",需要输入 "\\"。
-
-
isNull() 和 isEmpty():两个函数都判读字符串是否为空,但是稍有差别。如果一个空字符串,只有“\0”,isNull() 返回 false,而 isEmpty() 返回 true;只有未赋值的字符串,isNull() 才返回 true。
QString str1, str2=""; N=str1.isNull () ; // N=true 未赋值字符串变量 N=str2.isNull () ; // N=false 只有"\0"的字符串,也不是 Null N=str1.isEmpty(); // N=true N=str2.isEmpty(); // N=true
QString 只要赋值,就在字符串的末尾自动加上 “\0”,所以,如果只是要判断字符串内容是否为空,常用 isEmpty()。
-
contains():判断字符串内是否包含某个字符串,可指定是否区分大小写。
QString str1="G:\Qt5Book\QT5.9Study\qw.cpp"; N=str1.contains (".cpp", Qt::CaseInsensitive) ; // N=true,不区分大小写 N=str1.contains (".CPP", Qt::CaseSensitive) ; // N=false,区分大小写
-
endsWith() 和 startsWith():startsWith() 判断是否以某个字符串幵头,endsWith() 判断是否以某个字符串结束。
QString str1="G:\Qt5Book\QT5.9Study\qw.cpp"; N=str1.endsWith (".cpp", Qt::CaseInsensitive) ; // N=true,不区分大小写 N=str1.endsWith (".CPP", Qt::CaseSensitive) ; // N=false,区分大小写 N=str1.startsWith ("g: ") ; // N=true,缺省为不区分大小写
-
left() 和 right():left 表示从字符串中取左边多少个字符,right 表示从字符串中取右边多少个字符。注意,一个汉字被当作一个字符。
QString str2, str1="学生姓名,男,1984-3-4,汉族,山东"; N=str1.indexOf (",") ; // N=4,第一个","出现的位置 str2=str1.left (N) ; //str2="学生姓名" N=str1.lastIndexOf (",") ; // N=18,最后一个逗号的位置 str2=str1.right (str1.size()-N-1); //str2=”山东",提取最后一个逗号之后的字符串
-
section():
-
原型:
QString section (const QString &sep, int start, int end = -1, SectionFlags flags = SectionDefault) const
-
功能是从字符串中提取以 sep 作为分隔符,从 start 端到 end 端的字符串。
-
7、Qt QSpinBox使用
-
QSpinBox 用于整数的显示和输入,一般显示十进制数,也可以显示二进制、十六进制的数,而且可以在显示框中增加前缀或后缀。
-
QDoubleSpinBox 用于浮点数的显示和输入,可以设置显示小数位数,也可以设置显示的前缀和后缀。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oNq7OlMo-1589382598210)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200328105906683.png)]
-
一个属性在类的接口中一般有一个读取函数和一个设置函数,如 QDoubleSpinBox 的 decimals 属性,读取属性值的函数为 int decimals(),设置属性值的函数为 void setDecimals(int prec)。
int val=ui->spinBin->value ();//读取二进制数 ui->spinDec->setValue(val);//以十进制数显示 ui->spinHex->setValue(val);//以十六进制数显示
-
在使用 QSpinBox 和 QDoubleSpinBox 读取和设置数值时,无需做字符串与数值之间的转换,也无需做进制的转换,其显示效果(前缀、后缀、进制和小数位数)在设置好之后就自动按照效果进行显示,这对于数值的输入输出是非常方便的。
8、Qt数值输入组件和显示组件用法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vIT7htS-1589382598211)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200328145140576.png)]
-
QSlider:是滑动的标尺型组件,滑动标尺上的一个滑块可以改变值。
-
基类 QAbstractSlider 的主要属性包括以下几种:
- inimum、maximum:设置输入范围的最小值和最大值。
- singleStep:单步长,拖动标尺上的滑块,或按下左/右光标键时的最小变化数值。
- pageStep:在 Slider 上输入焦点,按 PgUp 或 PgDn 键时变化的数值。
- value:组件的当前值,拖动滑块时自动改变此值,并限定在 minimum 和 maximum 定义的范围之内。
- sliderPosition:滑块的位置,若 tracking 属性设置为 true,sliderPosition 就等于 value。
- tracking:sliderPosition 是否等同于 value,如果 tracking=tme,改变 value 时也同时改变 sliderPosition。
- orientation:Slider 的方向,可以设置为水平或垂直。方向参数是 Qt 的枚举类型 enum Qt::Orientation,取值包括以下两种:
- Qt::Horizontal 水平方向
- Qt::Vertical 垂直方向
- invertedAppearance:显示方式是否反向,invertedAppearance=false 时,水平的 Slider 由左向右数值增大,否则反过来。
- invertedControls:反向按键控制,若 invertedControls=true,则按下 PgUp 或 PgDn 按键时调整数值的反向相反
-
属于 QSlider 的专有属性有两个,如下:
- tickPosition:标尺刻度的显示位置,使用枚举类型 QSliderzTickPosition,取值包括以下 6 种:
- QSlider::NoTicks:不显示刻度
- QSlider::TicksBothSides:标尺两侧都显示刻度
- QSlider::TicksAbove:标尺上方显示刻度
- QSlider::TicksBelow:标尺下方显示刻度
- QSlider::TicksLeft:标尺左侧显示刻度
- QSlider::TicksRight:标尺右侧显示刻度
- tickInterval:标尺刻度的间隔值,若设置为 0,会在 singleStep 和 pageStep 之间自动选择。
- tickPosition:标尺刻度的显示位置,使用枚举类型 QSliderzTickPosition,取值包括以下 6 种:
-
QScrollBar:QScrollBar 从 QAbstractSlider 继承而来的,具有 QAbstractSlider 的基本属性,没有专有属性。
-
QDial:QDial 是仪表盘式的组件,通过旋转表盘获得输入值。QDial 的特有的属性包括以下两种:
- notches Visible:表盘的小刻度是否可见。
- notchTarget:表盘刻度间的间隔像素值。
-
QProgressBar:QProgressBar 的父类是 QWidget,一般用于进度显示,常用属性如下:
- minimum、maximum:最小值和最大值。
- value:当前值,可以设定或读取当前值。
- textVisible:是否显示文字,文字一般是百分比表示的进度。
- orientation:可以设置为水平或垂直方向。
- format:显示文字的格式,“%p%”显示百分比,“%v”显示当前值,“%m”显示总步数。缺省为“%p%”。
-
QLCDNumber:QLCDNumber 是模拟 LCD 显示数字的组件,可以显示整数或小数,但就如实际的 LCD 一样,要设定显示数字的个数。显示整数时,还可以选择以不同进制来显示,如十进制、二进制、十六进制。其主要属性如下:
- digitCount:显示的数的位数,如果是小数,小数点也算一个数位。
- smallDecimalPoint:是否有小数点,如果有小数点,就可以显示小数。
- mode:数的显示进制,通过调用函数 setDecMode()、setBinMode()、setOctMode()、setHexMode() 可以设置为常用的十进制、二进制、八进制、十六进制格式。
- value:返回显示值,浮点数。若设置为显示整数,会自动四舍五入后得到整数,设置为 intValue 的值。如果 smallDecimalPoint=true,设置 value 时可以显示小数,但是数的位数不能超过 digitCounto
- intValue:返回显示的整数值。
-
QColor 的静态函数 setRgb() 定义为:
void QColor::setRgb(int r, int g, int b, int a = 255)
其中 r、g、b 是红、绿、蓝颜色值,均在 0 在 255 之间,a 是颜色的 alpha 值,缺省是 255,取值范围也是 0〜255。
9、Qt获取当前时间
Qt 中时间日期类型的类如下:
- QTime:时间数据类型,仅表示时间,如15:23:13。
- QDate:日期数据类型,仅表示日期,如2017-4-5。
- QDateTime:日期时间数据类型,表示日期和时间,如2017-03-23 08:12:43。
Qt 中有专门用于日期、时间编辑和显示的界面组件,介绍如下:
- QTimeEdit:编辑和显示时间的组件。
- QDateEdit:编辑和显示日期的组件。
- QDateTimeEdit:编辑和显示日期时间的组件。
- QCalendarWidget: 一个用日历形式选择日期的组件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSgrw4Jk-1589382598212)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200328162132304.png)]
-
时间、日期编辑器属性
- 时间、日期编辑器属性设置:QDateEdit 和 QTimeEdit 都从 QDateTimeEdit 继承而来,实现针对日期或时间的特定显示功能。实际上,QDateEdit 和 QTimeEdit 的显示功能都可以通过 QDateTimeEdit 实现,只需设置好属性即可。
- QDateTimeEdit 类的主要属性的介绍如下:
- datetime:日期时间。
- date:日期,设置 datetime 时会自动改变 date,同样,设置 date 时,也会自动改变 datetime 里的日期。
- time:时间,设置 datetime 时会自动改变 time,同样,设置 time 时,也会自动改变 datetime 里的时间。
- maximumDateTime、 minimumDateTime:最大、最小日期时间。
- maximumDate、minimumDate:最大、最小日期。
- maximumTime、minimumTime:最大、最小时间。
- currentSection:当前输入光标所在的时间日期数据段,是枚举类型 QDateTimeEdit::Section。QDateTimeEdit 显示日期时间数据时分为多个段,单击编辑框右侧的上下按钮可修改当前段的值。如输入光标在YearSection段,就修改“年”的值。
- currentSectionIndex:用序号表示的输入光标所在的段。
- calendarPopup:是否允许弹出一个日历选择框。当取值为 true 时,右侧的输入按钮变成与 QComboBox 类似的下拉按钮,单击按钮时出现一个日历选择框,用于在日历上选择日期。对于 QTimeEdit,此属性无效。
- displayFormat:显示格式,日期时间数据的显示格式,例如设置为“yyyy-MM-dd HH:mm:ss”,一个日期时间数据就显示为“2016-11-02 08:23:46”。
-
日期时间数据的获取与转换为字符串
“设置日期时间”按钮的 clicked() 信号的槽函数代码如下:
void Dialog::on_btnGetTime_clicked() { //获取当前日期时间,为三个专用编辑器设置日期时间数据,并转换为字符串 QDateTime curDateTime=QDateTime::currentDateTime(); ui->timeEdit->setTime(curDateTime.time()); ui->editTime->setText (curDateTime.toString ("hh:mm: ss11)); ui->dateEdit->setDate(curDateTime.date()); ui->editDate->setText(curDateTime.toString("yyyy-MM-dd")); ui->dateTimeEdit->setDateTime(curDateTime); ui->editDateTime->setText(curDateTime.toString("yyyy-MM-dd hh:mm:ss")); }
-
首先用 QDateTime 类的静态函数currentDateTime() 获取当前日期时间,并赋值给变量curDateTime。
-
QDateTime 的 time() 和 date() 分别提取时间和日期。
-
时间日期转换为字符串使用了 QDateTime 的 toString() 函数,函数原型是:
QString QDateTime::toString(const QString fiformat) const
它将日期时间数据按照 format 指定的格式转换为字符串。format 是一个字符串,包含一些特定的字符,表示日期或时间的各个部分,表 2 是用于日期时间显示的常用格式符。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWLQEajB-1589382598213)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200328162550312.png)]
//将 curDateTime 表示的日期时间数据转换为字符串,然后在 LineEdit 编辑框上显示。 ui->editTime->setText(curDateTime.toString(Mhh:mm:ss")); ui->editDate->setText(curDateTime.toString("yyyy-MM-dd")); ui->editDateTime->setText(curDateTime.toString("yyyy-MM-dd hh:mm:ss"));
-
在设置日期时间显示字符串格式时,还可以使用填充字符,甚至使用汉字。例如,日期显示格式可以设置为:
curDateTime.toString ("yyyy 年 MM 月 dd 日");
这样得到的字符串是“2016年11月21日”。
-
-
字符串转换为日期时间
-
使用静态函数 QDateTime::fromString()将字符串转换为 QTime、QDate 或 QDateTime 类型。函数原型是:
QDateTime QDateTime::fromString(const QString &string, const QString &format)
其中,第 1 个参数 string 是日期时间字符串形式,第 2 个参数 format 是字符串表示的格式,按照表 2 的格式字符定义。
-
10、Qt定时器及实现
-
定时器是用来处理周期性事件的一种对象,类似于硬件定时器。例如设置一个定时器的定时周期为 1000 毫秒,那么每 1000 毫秒就会发射定时器的 timeout() 信号,在信号关联的槽函数里就可以做相应的处理。
-
Qt中的定时器类是 QTimer。
-
QTimer 主要的属性是 interval,是定时中断的周期,单位毫秒。QTimer 主要的信号是 timeout(),在定时中断时发射此信号,要想在定时中断里做出响应,这就需要编写 timeout() 信号的槽函数。
-
下面是窗口类中增加的定义:这里定义了一个定时器 fTimer,—个计时器 fTimeCounter。还定义了一个槽函数 on_timer_ timeout(),作为定时器的 timeout() 信号的响应槽函数。
class Dialog : public QDialog { private: QTimer *fTimer; //定时器 QTime fTimeCounter;//计时器,记录定时器走过的毫秒数 private slots: void on_timer_timeout () ; //定时溢出处理槽函数 };
需要在窗口类的构造函数里创建定时器,并进行信号与槽的关联。代码如下:
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); fTimer=new QTimer(this); fTimer->stop(); fTimer->setInterval (1000) ;//设置定时周期,单位:毫秒 connect(fTimer,SIGNAL(timeout()),this,SLOT(on_timer_timeout())); }
-
计时:定义一个QTime类的对象time,当你调用其成员函数start()时,time就开始自动计时,一直到你调用其成员函数elapsed();该成员函数会返回一个整数表示从start()开始到现在所经历的毫秒数,且每当该计数时间到达24小时后自动清零。
11、Qt QComboBox下拉框及用法
QComboBox 是下拉列表框组件类,它提供一个下拉列表供用户选择,也可以直接当作一个 QLineEdit 用作输入。QComboBox 除了显示可见下拉列表外,每个项(item,或称列表项)还可以关联一个 QVariant 类型的变量,用于存储一些不可见数据。
-
addItem() 用于添加一个列表项,如果只是添加字符串列表项,而且数据来源于一个 QStringList 变量,可以使用 addltems() 函数,示例代码如下:
ui->ComeBox->clear(); QStringList strlist; strlist<<"北京"<<"上海"<<"天津"<<"湘潭"; ui->ComeBox->addItem(strlist);
-
添加具有用户数据的项 QComboBox::addltem() 函数的两种参数的原型定义如下:
void addItem (const QString &text, const QVariant &userData = QVariant()) void addItem (const QIcon &icon, const QString &text, const QVariant &userData = QVariant())
不管是哪一个 addItem() 函数,后面都有一个可选的 QVariant 类型的参数 userData,可以利用这个变量存储用户定义数据。
eg:
void Widget::on_btnIni2_clicked() {//初始化具有自定义数据的comboBox //QMap自动根据 key排序 QMap<QString, int> City_Zone; City_Zone.insert("北京",10); City_Zone.insert("上海",21); City_Zone.insert("天津",22); City_Zone.insert("大连",411); City_Zone.insert("锦州",416); City_Zone.insert("徐州",516); City_Zone.insert("福州",591); City_Zone.insert("青岛",532); ui->comboBox2->clear(); foreach(const QString &str,City_Zone.keys()) ui->comboBox2->addItem(str,City_Zone.value(str)); //城市名称作为项显示的字符串,电话区号作为项关联的用户数据,但是在列表框里只能看到城市名称。 }
-
QComboBox列表项的访问
-
访问项的一些函数主要有以下几种:
- int currentlndex():返回当前项的序号,第一个项的序号为0。
- QString currentText():返回当前项的文字。
- QVariant currentData(int role = Qt::UserRole):返回当前项的关联数据,数据的缺省角色为 role = Qt::UserRole,角色的意义在后续章节会详细介绍。
- QString itemText(int index):返回指定索引号的项的文字。
- QVariant itemData(int index, int role = Qt%:UserRole):返回指定索引号的项的关联数据。
- int count():返回项的个数。
-
在一个 QComboBox 组件上选择项发生变化时,会发射如下两个信号:
void currentlndexChanged(int index) void currentlndexChanged(const QString &text)
这两个信号只是传递的参数不同,一个传递的是当前项的索引号,一个传递的当前项的文字。
-
12、Qt QPlainTextEdit用法
QPlainTextEdit 是一个多行文本编辑器,用于显示和编辑多行简单文本。另外,还有一个 QTextEdit 组件,是一个所见即所得的可以编辑带格式文本的组件,以 HTML 格式标记符定义文本格式。
-
使用 QPlainTextEdit::appendPlainText(const QString) 函数就可以向 PlainTextEdit 组件添加一行字符串。QPlainTextEdit 提供 cut()、copy()、paste()、undo()、redo()、clear()、selectAll() 等标准编辑功能的槽函数,QPlainTextEdit 还提供一个标准的右键快捷菜单。
-
如果要将 QPlainTextEdit 组件里显示的所有文字读取出来,有一个简单的函数 toPlainText() 可以将全部文字内容输出为一个字符串,其定义如下:
QString QPlainTextEdit::toPlainText() const
-
逐行读取plainTextEdit的文字:
QPlainTextEdit 的文字内容以 QTextDocument 类型存储,函数 document() 返回这个文档对象的指针。
void Widget::on_btnToComboBox_clicked() { //plainTextEdit的内容逐行添加为comboBox的项 QTextDocument* doc=ui->plainTextEdit->document () ; //文本对象 int cnt=doc->blockCount () ;//回车符是一个 block QIcon icon(M:/images/icons/aim.ico");//定义图标 ui->comboBox->clear(); for (int i=0; i<cnt;i++) { QTextBlock textLine=doc->findBlockByNumber (i) ; // 文本中的一段 QString str=textLine.text(); ui->comboBox->addItem(icon,str);//将该行文字带图标添加到comebox } }
QTextDocument 是内存中的文本对象,以文本块的方式存储,一个文本块就是一个段落,每个段落以回车符结束。QTextDocument 提供一些函数实现对文本内容的存取:
- int blockCount():获得文本块个数。
- QTextBlock findBlockByNumber(int blockNumber):读取某一个文本块,序号从 0 开始,至 blockCount()-1 结束。
一个 document 有多个 TextBlock,从 document 中读取出的一个文本块类型为 QTextBlock,通过 QTextBlock::text() 函数可以获取其纯文本文字。
-
QPlainTextEdit 是一个多行文字编辑框,有自带的右键快捷菜单,可实现常见的编辑功能。在 UI 设计器里,选择为 plainTextEdit 的 customContextMenuRequested() 信号生成槽函数,编写如下的代码,就可以创建并显示 QPlainTextEdit 的标准快捷菜单:
void Widget::on_plainTextEdit_customContextMenuRequested(const QPoint &pos) { //创建并显示标准弹出式菜单 QMenu* menu=ui->plainTextEdit->createStandardContextMenu(); menu->exec(pos); }
13、Qt QListWidget和QToolButton用法
Qt中用于项(Item)处理的组件有两类,一类是 Item Views,包括 QListView、QTreeView、 QTableView、QColumnView 等;另一类是 Item Widgets,包括 QListWidget、QTreeWidget 和 QTable Widget。
Item Views 基于模型/视图(Model/View)结构。
Item Widgets 是直接将数据存储在每一个项里,一个项存储了文字、文字的格式、自定义数据等。
-
QToolButton 有一个 setDefaultAction() 函数,可以使其与一个 Action 关联,按钮的文字、图标、ToolTip 都将自动设置为与关联的 Action 一致,单击一个 QToolButton 按钮就是执行 Action 的槽函数。
函数 setDefaultAction()的原型:
void QToolButton: :setDefaultAction(QAction * action)
-
QToolButton 还有一个 setMenu() 函数,可以为其设置一个下拉式菜单,配合 QToolButton 的一些属性设置,可以有不同的下拉菜单效果。
-
QListWidget 的设置:
比较重要的是其 flags 属性(如图 3 所示),用于设置项的一些标记,这些标记是枚举类型 Qt::ItemFlag 的具体值,包括以下几种:
- Selectable:项是否可被选择,对应枚举值 Qt::ItemIsSelectable。
- Editable:项是否可被编辑,对应枚举值 Qt:: ItemlsEditable。
- DragEnabled:项是否可以被拖动,对应枚举值 Qt:: ItemlsDragEnabled。
- DropEnabled:项是否可以接收拖放的项,对应枚举值 Qt:: ItemlsDropEnabled。
- UserCheckable:项是否可以被复选,若为 true,项前面出现一个 CheckBox,对应枚举值 Qt::ItemlsUserCheckable。
- Enabled:项是否被使能,对应枚举值 Qt:: ItemlsEnabled。
- Tristate:是否允许 Check 的第三种状态,若为 false,则只有 checked 和 unchecked 两种状态,对应枚举值 Qt::ItemIsAutoTristate。
在代码中设置项的 flags 属性时,使用函数 setFlags(),例如:
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable IQt::ItemIsEnabled);
-
QListWidget 的操作:
- 列表框里一行是一个项,是一个 QListWidgetltem 类型的对象,向列表框添加一个项,就需要创建一个 QListWidgetltem 类型的实例 aItem,然后设置 aItem 的一些属性,再用 QListWidget::AddItem() 函数将该 aItem 添加到列表框里。
- 插入项使用 QListWidget 的 *insertItem(int row, QListWidgetItem item) 函数,在某一行 row 的前面插入一个 QListWidgetItem 对象 item,也需要先创建这个 item,并设置好其属性。
- takeItem(int row) 函数只是移除一个项,并不删除项对象,所以还需要用 delete 从内存中删除它。要清空列表框的所有项,只需调用 QListWidget::clear() 函数即可。
- 函数 QListWidgetItem::setCheckState(Qt::CheckState state) 设置列表项的复选状态,枚举类型 Qt::CheckState 有 3 种取值:
- Qt::Unchecked:不被选中。
- Qt::PartiallyChecked:部分选中。在目录树中的节点可能出现这种状态,比如其子节点没有全部被勾选时。
- Qt::Checked:被选中。
- QListWidget 在当前项切换时发射两个信号,只是传递的参数不同:
- currentRowChanged(int currentRow):传递当前项的行号作为参数。
- currentItemChanged(QListWidgetItem * current, QListWidgetItem * previous):传递两个 QList Widgetltem对象作为参数,current表示当前项,previous是前一项。
-
创建右键快捷菜单:
每个从 QWidget 继承的类都有信号 customContextMenuRequested(),这个信号在鼠标右击时发射,为此信号编写槽函数,可以创建和运行右键快捷菜单。
-
首先创建一个 QMenu 类型的对象 menuList,然后利用 QMenu 的 addAction() 方法添加己经设计的 Actions 作为菜单项。
-
创建完菜单后,使用 QMenu::exec() 函数显示快捷菜单:
menuList->exec(QCursor::pos());
这样会在鼠标当前位置显示弹出式菜单,静态函数 QCursor::pos() 获得鼠标光标当前位置。
-
14、Qt QTreeWidget和QDockWidget用法
QTreeWidget 目录树组件:QTreeWidget 类是创建和管理目录树结构的类。
QDockWidget 停靠区域组件:QDockWidget 是可以在 QMainWindow 窗口停靠,或在桌面最上层浮动的界面组件。
-
QTreeWidget 的每个节点都是一个 QTreeWidgetItem 对象,添加一个节点前需先创建它,并做好相关设置。创建节点的语句是:
item=new QTreeWidgetItem(MainWindow::itTopItem);
传递了一个枚举常量 MainWindow::itTopItem 作为构造函数的参数,表示节点的类型。在构造函数里传递一个类型值之后,就可以用 QTreeWidgetItem::type() 返回这个节点的类型值。itTopItem 是在 MainWindow 里定义的枚举类型 treeltemType 的一个常量值。枚举类型 treeItemType 定义了节点的类型,自定义的节点类型值必须大于 1000。
-
QTreeWidgetItem 的 setIcon() 和 setText() 都需要传递一个列号作为参数,指定对哪个列进行设置。列号可以直接用数字,但是为了便于理解代码和统一修改,在 MainWindow 里定义了枚举类型 treeColNum, colItem 表示第 1 列,colItemType 表示第 2 列。
-
setFlags() 函数设置节点的一些属性标记,是 Qt::ItemFlag 枚举类型常量的组合。
-
setData() 函数为节点的某一列设置一个角色数据,setData() 函数原型为:
void QTreeWidgetltem::setData(int column, int role, const QVariant &value)
其中,column 是列号,role 是角色的值,value 是一个 QVariant 类型的数。
-
设置节点数据的语句是:
item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr));
它为节点的第 1 列,角色 QtrUserRole,设置了一个字符串数据 dataStr。
-
创建并设置好节点后,用 QTreeWidget::addTopLevelItem() 函数将节点作为顶层节点添加到目录树。
-
QPixmap 存储图片数据,可以缩放图片,有以下几个函数:
- QPixmap scaledToHeight(int height):返回一个缩放后的图片的副本,图片缩放到一个高度 height。
- QPixmap scaledToWidth(int width):返回一个缩放后的图片的副本,图片缩放到一个宽度 width。
- QPixmap scaled(int width, int height):返回一个缩放后的图片的副本,图片缩放到宽度 width 和高度 height,缺省为不保持比例。
-
在界面上的一个标签 label上显示图片,使用了 QLabel 的 setPixmap(const QPixmap &) 函数。
15、Qt QTableWidget
- QTableWidget 是 Qt 中的表格组件类,表格的第 1 行称为行表头,用于设置每一列的标题,第 1 列称为列表头,可以设置其标题,但一般使用缺省的标题,即为行号。行表头和列表头一般是不可编辑的。
- 在 QTableWidget 表格中,每一个单元格是一个 QTable Widgetltem 对象,可以设置文字内容、字体、前景色、背景色、图标,也可以设置编辑和显示标记。每个单元格还可以存储一个 QVariant 数据,用于设置用户自定义数据。
- 填充表格的步骤:
- 创建一个QTableWidgetItem对象item;
- 初始化item的相关属性数据;
- 用函数setItem(行号,列号,item)将该item添加到对应表格。
16、Qt Model/View(模型/视图)结构
**视图(View)**是显示和编辑数据的界面组件,**模型(Model)**是视图与原始数据之间的接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPbz3jhS-1589382598215)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200406092402786.png)]
- 数据是实际的数据,如数据库的一个数据表或SQL查询结果,内存中的一个 StringList,或磁盘文件结构等。
- **视图或视图组件是屏幕上的组件,视图从数据模型获得每个数据项的模型索引(model index),通过模型索引获得数据,然后为界面显示数据。**Qt 提供一些现成的数据视图组件,如 QListView、QTreeView 和 QTableView 等。
- **模型或数据模型与实际数据通信,并为视图组件提供数据接口。**它从原始数据提取需要的内容,用于视图组件进行显示和编辑。Qt 中有一些预定义的数据模型,如 QStringListModel 可作为 StringList 的数据模型,QSqlTableModel 可以作为数据库中一个数据表的数据模型。
模型、视图和代理之间使用信号和槽通信。当源数据发生变化时,数据模型发射信号通知视图组件;当用户在界面上操作数据时,视图组件发射信号表示这些操作信息;当编辑数据时,代理发射信号告知数据模型和视图组件编辑器的状态。
-
数据模型
- 所有的基于项数据的数据模型(Model)都是基于 QAbstractltemModel 类的,这个类定义了视图组件和代理存取数据的接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QQb3JVxK-1589382598217)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200406093128529.png)]
- 图 2 中的抽象类是不能直接使用的,需要由子类继承来实现一些纯虚函数。Qt 提供了一些模型类用于项数据处理,常见的几个见表 3。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mpJXot44-1589382598218)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200406094920611.png)]
-
视图组件
- 视图组件(View)就是显示数据模型的数据的界面组件,Qt 提供的视图组件如下:
- QListView:用于显示单列的列表数据,适用于一维数据的操作。
- QTreeView:用于显示树状结构数据,适用于树状结构数据的操作。
- QTableView:用于显示表格状数据,适用于二维表格型数据的操作。
- QColumnView:用多个QListView显示树状层次结构,树状结构的一层用一个QListView显示。
- QHeaderView:提供行表头或列表头的视图组件,如QTableView的行表头和列表头。
- 视图组件在显示数据时,只需调用视图类的 setModel() 函数,为视图组件设置一个数据模型就可以实现视图组件与数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。
- 视图组件不存储数据。
- 视图组件(View)就是显示数据模型的数据的界面组件,Qt 提供的视图组件如下:
-
代理
- 代理就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个 QLineEdit 编辑框。代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后,又将其保存到数据模型中。
- QAbstractltemDelegate 是所有代理类的基类,作为抽象类,它不能直接使用。它的一个子类 QStyledltemDelegate,是 Qt 的视图组件缺省使用的代理类。
-
模型索引
- QModelIndex 表示模型索引的类。模型索引提供数据存取的一个临时指针,用于通过数据模型提取或修改数据。因为模型内部组织数据的结构随时可能改变,所以模型索引是临时的。如果需要使用持久性的模型索引,则要使用 QPersistentModelIndex 类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZSvhooYS-1589382598219)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200406100321455.png)]
-
要获得一个模型索引,必须提供 3 个参数:行号、列号、父项的模型索引;对于列表和表格模式的数据模型,顶层节点总是用 QModelIndex() 表示。
eg:对于如图 5 中的表格数据模型中的 3 个数据项 A、B、C,获取其模型索引的代码是:
QModelIndex indexA = model->index(0, 0, QModelIndex()); QModelIndex indexB = model->index(1, 1, QModelIndex()); QModelIndex indexC = model->index(2, 1, QModelIndex());
-
对于图 5 中的树状数据模型,节点 A 和节点 C 的父节点是顶层节点,获取模型索引的代码是:
QModelIndex indexA = model->index(0, 0, QModelIndex()); QModelIndex indexC = model->index(2, 1, QModelIndex()); //节点 B 的父节点是节点 A,节点 B 的模型索引由下面的代码生成: QModelIndex indexB = model->index(1, 0, indexA);
-
项的角色
-
在为数据模型的一个项设置数据时,可以赋予其不同项的角色的数据。例如,数据模型类 QStandardItemModel 的项数据类是 QStandardItem,其设置数据的函数是:
void QStandardItem::setData(const QVariant &value, int role= Qt::UserRole + 1)
其中,value 是需要设置的数据,role 是设置数据的角色。一个项可以有不同角色的数据,用于不同的场合。
-
role 是Qt::ItemDataRole枚举类型,有多种取值,如
Qt::DisplayRole
角色是在视图组件中显示的字符串,Qt::ToolTipRole
是鼠标提示消息,Qt::UserRole
可以自定义数据。项的标准角色是Qt::DisplayRole
。 -
在获取一个项的数据时也需要指定角色,以获取不同角色的数据:
QVariant QStandardItem::data(int role = Qt::UserRole + 1) const
-
17、Qt QFileSystemModel功能及用法
QFileSystemModel 提供了一个可用于访问本机文件系统的数据模型。
-
要通过 QFileSystemModel 获得本机的文件系统,需要用 setRootPath() 函数为 QFileSystemModel 设置一个根目录,例如:
QFileSystemModel *model = new QFileSystemModel; model->setRootPath(QDir::currentPath());
静态函数
QDir::currentPath()
获取应用程序的当前路径。 -
用于获取磁盘文件目录的数据模型类还有一个 QDirModel,QDirModel 的功能与 QFileSystemModel 类似,也可以获取目录和文件,但是 QFileSystemModel 采用单独的线程获取目录文件结构,而 QDirModel 不使用单独的线程。使用单独的线程就不会阻碍主线程,所以推荐使用 QFileSystemModel。
-
FileSystemModel 的一些函数来获得节点的一些参数,包括以下几种:
- bool isDir(QModelIndex &index):判断节点是不是一个目录。
- QString filePath(QModelIndex &index):返回节点的目录名或带路径的文件名。
- QString fileName(QModelIndex &index):返回去除路径的文件夹名称或文件名。
- QString type(QModelIndex &index):返回描述节点类型的文字,如硬盘符是 “Drive”,文件夹是 “FileFolder”,文件则用具体的后缀描述,如"txtFile"、“exeFile”、"pdfFile"等。
- qint64 size(QModelIndex &index):如果节点是文件,返回文件大小的字节数:如果节点是文件夹,返回 0。
18、Qt QStringListModel
QStringListModel 用于处理字符串列表的数据模型,它可以作为 QListView 的数据模型,在界面上显示和编辑字符串列表。
-
QStringListModel 的 setStringList() 函数可以初始化数据模型的字符串列表的内容,stringList() 函数返回数据模型内的字符串列表。
-
QStringListModel 提供编辑和修改字符串列表数据的函数,如 insertRows()、removeRows()、setData() 等,这些操作直接影响数据模型内部的字符串列表,并且修改后的数据会自动在关联的 ListView 组件里刷新显示。
-
QListView::setEditTriggers() 函数设置 QListView 的条目是否可以编辑,以及如何进入编辑状态,函数的参数是 QAbstractItemView::EditTrigger 枚举类型值的组合。
ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked |QAbstractItemView::SelectedClicked);//表示在双击,或选择并单击列表项后,就进入编辑状态。 ui->listView->setEditTriggers(QAbstractItemView:: NoEditTriggers);//设置为不可编辑
-
插入一行使用的是 QStringListModel 的 insertRow (int row) 函数,其中 row 是一个行号,表示在 row 行之前插入一行。
-
QStringListModel 的 index(行号,列号) 函数根据传递的行号、列号、父项的模型索引返回一个模型索引.
带路径的文件名。
- QString fileName(QModelIndex &index):返回去除路径的文件夹名称或文件名。
- QString type(QModelIndex &index):返回描述节点类型的文字,如硬盘符是 “Drive”,文件夹是 “FileFolder”,文件则用具体的后缀描述,如"txtFile"、“exeFile”、"pdfFile"等。
- qint64 size(QModelIndex &index):如果节点是文件,返回文件大小的字节数:如果节点是文件夹,返回 0。
18、Qt QStringListModel
QStringListModel 用于处理字符串列表的数据模型,它可以作为 QListView 的数据模型,在界面上显示和编辑字符串列表。
-
QStringListModel 的 setStringList() 函数可以初始化数据模型的字符串列表的内容,stringList() 函数返回数据模型内的字符串列表。
-
QStringListModel 提供编辑和修改字符串列表数据的函数,如 insertRows()、removeRows()、setData() 等,这些操作直接影响数据模型内部的字符串列表,并且修改后的数据会自动在关联的 ListView 组件里刷新显示。
-
QListView::setEditTriggers() 函数设置 QListView 的条目是否可以编辑,以及如何进入编辑状态,函数的参数是 QAbstractItemView::EditTrigger 枚举类型值的组合。
ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked |QAbstractItemView::SelectedClicked);//表示在双击,或选择并单击列表项后,就进入编辑状态。 ui->listView->setEditTriggers(QAbstractItemView:: NoEditTriggers);//设置为不可编辑
-
插入一行使用的是 QStringListModel 的 insertRow (int row) 函数,其中 row 是一个行号,表示在 row 行之前插入一行。
-
QStringListModel 的 index(行号,列号) 函数根据传递的行号、列号、父项的模型索引返回一个模型索引.