Qt 学习之路 2(42):QListWidget、QTreeWidget 和 QTableWidget
Qt 学习之路 2(42):QListWidget、QTreeWidget 和 QTableWidget
上一章我们了解了 model/view 架构的基本概念。现在我们从最简单的QListWidget
、QTreeWidget
和QTableWidget
三个类开始了解最简单的 model/view 的使用。这部分内容的确很难组织。首先,从最标准的 model/view 开始,往往会纠结于复杂的代码;但是,如果从简单的 QListWidget
、QTreeWidget
和QTableWidget
开始,由于这三个类都是继承自各自的 view 类,很难避免 model/view 的相关内容。于是,我们这部分的组织是,首先进行简单的数据显示,更复杂的设置则放在后面的章节。
QListWidget
我们要介绍的第一个是QListWidget
。先来看下面的代码示例:
label->setFixedWidth(70);
listWidget = new QListWidget(this);
new QListWidgetItem(QIcon(":/Chrome.png"), tr("Chrome"), listWidget);
new QListWidgetItem(QIcon(":/Firefox.png"), tr("Firefox"), listWidget);
listWidget->addItem(new QListWidgetItem(QIcon(":/IE.png"), tr("IE")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Netscape.png"), tr("Netscape")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Opera.png"), tr("Opera")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Safari.png"), tr("Safari")));
listWidget->addItem(new QListWidgetItem(QIcon(":/TheWorld.png"), tr("TheWorld")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Traveler.png"), tr("Traveler")));
QListWidgetItem *newItem = new QListWidgetItem;
newItem->setIcon(QIcon(":/Maxthon.png"));
newItem->setText(tr("Maxthon"));
listWidget->insertItem(3, newItem);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(label);
layout->addWidget(listWidget);
setLayout(layout);
connect(listWidget, SIGNAL(currentTextChanged(QString)),
label, SLOT(setText(QString)));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
label = new QLabel(this);
label->setFixedWidth(70);
listWidget = new QListWidget(this);
new QListWidgetItem(QIcon(":/Chrome.png"), tr("Chrome"), listWidget);
new QListWidgetItem(QIcon(":/Firefox.png"), tr("Firefox"), listWidget);
listWidget->addItem(new QListWidgetItem(QIcon(":/IE.png"), tr("IE")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Netscape.png"), tr("Netscape")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Opera.png"), tr("Opera")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Safari.png"), tr("Safari")));
listWidget->addItem(new QListWidgetItem(QIcon(":/TheWorld.png"), tr("TheWorld")));
listWidget->addItem(new QListWidgetItem(QIcon(":/Traveler.png"), tr("Traveler")));
QListWidgetItem *newItem = new QListWidgetItem;
newItem->setIcon(QIcon(":/Maxthon.png"));
newItem->setText(tr("Maxthon"));
listWidget->insertItem(3, newItem);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(label);
layout->addWidget(listWidget);
setLayout(layout);
connect(listWidget, SIGNAL(currentTextChanged(QString)),
label, SLOT(setText(QString)));
|
QListWidget
是简单的列表组件。当我们不需要复杂的列表时,可以选择QListWidget
。QListWidget
中可以添加QListWidgetItem
类型作为列表项,QListWidgetItem
即可以有文本,也可以有图标。上面的代码显示了三种向列表中添加列表项的方法(实际是两种,后两种其实是一样的),我们的列表组件是listWidget
,那么,向listWidget
添加列表项可以:第一,使用下面的语句
1
|
new QListWidgetItem(QIcon(":/Chrome.png"), tr("Chrome"), listWidget);
|
第二,使用
// 或者
QListWidgetItem *newItem = new QListWidgetItem;
newItem->setIcon(QIcon(":/Maxthon.png"));
newItem->setText(tr("Maxthon"));
listWidget->insertItem(3, newItem);
1
2
3
4
5
6
|
listWidget->addItem(new QListWidgetItem(QIcon(":/IE.png"), tr("IE")));
// 或者
QListWidgetItem *newItem = new QListWidgetItem;
newItem->setIcon(QIcon(":/Maxthon.png"));
newItem->setText(tr("Maxthon"));
listWidget->insertItem(3, newItem);
|
注意这两种添加方式的区别:第一种需要在构造时设置所要添加到的QListWidget
对象;第二种方法不需要这样设置,而是要调用addItem()
或者insertItem()
自行添加。如果你仔细查阅QListWidgetItem
的构造函数,会发现有一个默认的type
参数。该参数有两个合法值:QListWidgetItem::Type
(默认)和QListWidgetItem::UserType
。如果我们继承QListWidgetItem
,可以设置该参数,作为我们子类的一种区别,以便能够在QListWidget
区别处理不同子类。
我们的程序的运行结果如下:
我们可以利用QListWidget
发出的各种信号来判断是哪个列表项被选择,具体细节可以参考文档。另外,我们也可以改变列表的显示方式。前面的列表是小图标显示,我们也可以更改为图标显示,只要添加一行语句:
1
|
listWidget->setViewMode(QListView::IconMode);
|
结果如下:
QTreeWidget
我们要介绍的第二个组件是QTreeWidget
。顾名思义,这是用来展示树型结构(也就是层次结构)的。同前面说的QListWidget
类似,这个类需要同另外一个辅助类QTreeWidgetItem
一起使用。不过,既然是提供方面的封装类,即便是看上去很复杂的树,在使用这个类的时候也是显得比较简单的。当不需要使用复杂的QTreeView
特性的时候,我们可以直接使用QTreeWidget
代替。
下面我们使用代码构造一棵树:
treeWidget.setColumnCount(1);
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget,
QStringList(QString("Root")));
new QTreeWidgetItem(root, QStringList(QString("Leaf 1")));
QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root, QStringList(QString("Leaf 2")));
leaf2->setCheckState(0, Qt::Checked);
QList<QTreeWidgetItem *> rootList;
rootList << root;
treeWidget.insertTopLevelItems(0, rootList);
treeWidget.show();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
QTreeWidget treeWidget;
treeWidget.setColumnCount(1);
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget,
QStringList(QString("Root")));
new QTreeWidgetItem(root, QStringList(QString("Leaf 1")));
QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root, QStringList(QString("Leaf 2")));
leaf2->setCheckState(0, Qt::Checked);
QList<QTreeWidgetItem *> rootList;
rootList << root;
treeWidget.insertTopLevelItems(0, rootList);
treeWidget.show();
|
首先,我们创建了一个QTreeWidget
实例。然后我们调用setColumnCount()
函数设定栏数。这个函数的效果我们会在下文了解到。最后,我们向QTreeWidget
添加QTreeWidgetItem
。QTreeWidgetItem
有很多重载的构造函数。我们在这里看看其中的一个,其余的请自行查阅文档。这个构造函数的签名如下:
1
|
QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type = Type);
|
这里有 3 个参数,第一个参数用于指定这个项属于哪一个树,类似前面的QListWidgetItem
,如果指定了这个值,则意味着该项被直接添加到树中;第二个参数指定显示的文字;第三个参数指定其类型,同QListWidgetItem
的type
参数十分类似。值得注意的是,第二个参数是QStringList
类型的,而不是QString
类型。我们会在下文了解其含义。
在这段代码中,我们创建了作为根的QTreeWidgetItem
root。然后添加了第一个叶节点,之后又添加一个,而这个则设置了可选标记。最后,我们将这个 root 添加到一个QTreeWidgetItem
的列表,作为QTreeWidget
的数据项。此时你应该想到,既然QTreeWidget
接受QList
作为项的数据,它就能够支持多棵树的一起显示,而不仅仅是单根树。下面我们来看看运行结果:
从代码来看,我们能够想象到这个样子,只是这个树的头上怎么会有一个 1?还记得我们跳过去的那个函数吗?下面我们修改一下代码看看:
QStringList headers;
headers << "Name" << "Number";
treeWidget.setHeaderLabels(headers);
QStringList rootTextList;
rootTextList << "Root" << "0";
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget, rootTextList);
new QTreeWidgetItem(root, QStringList() << QString("Leaf 1") << "1");
QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root,
QStringList() << QString("Leaf 2") << "2");
leaf2->setCheckState(0, Qt::Checked);
QList<QTreeWidgetItem *> rootList;
rootList << root;
treeWidget.insertTopLevelItems(0, rootList);
treeWidget.show();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
QTreeWidget treeWidget;
QStringList headers;
headers << "Name" << "Number";
treeWidget.setHeaderLabels(headers);
QStringList rootTextList;
rootTextList << "Root" << "0";
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget, rootTextList);
new QTreeWidgetItem(root, QStringList() << QString("Leaf 1") << "1");
QTreeWidgetItem *leaf2 = new QTreeWidgetItem(root,
QStringList() << QString("Leaf 2") << "2");
leaf2->setCheckState(0, Qt::Checked);
QList<QTreeWidgetItem *> rootList;
rootList << root;
treeWidget.insertTopLevelItems(0, rootList);
treeWidget.show();
|
这次我们没有使用setColumnCount()
,而是直接使用QStringList
设置了 headers,也就是树的表头。接下来我们使用的还是QStringList
设置数据。这样,我们实现的是带有层次结构的树状表格。利用这一属性,我们可以比较简单地实现类似 Windows 资源管理器的界面。
如果你不需要显示这个表头,可以调用setHeaderHidden()
函数将其隐藏。
QTableWidget
我们要介绍的最后一个是 QTableWidget
。QTableWidget
并不比前面的两个复杂到哪里去,这点我们可以从代码看出来:
tableWidget.setColumnCount(3);
tableWidget.setRowCount(5);
QStringList headers;
headers << "ID" << "Name" << "Age" << "Sex";
tableWidget.setHorizontalHeaderLabels(headers);
tableWidget.setItem(0, 0, new QTableWidgetItem(QString("0001")));
tableWidget.setItem(1, 0, new QTableWidgetItem(QString("0002")));
tableWidget.setItem(2, 0, new QTableWidgetItem(QString("0003")));
tableWidget.setItem(3, 0, new QTableWidgetItem(QString("0004")));
tableWidget.setItem(4, 0, new QTableWidgetItem(QString("0005")));
tableWidget.setItem(0, 1, new QTableWidgetItem(QString("20100112")));
tableWidget.show();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
QTableWidget tableWidget;
tableWidget.setColumnCount(3);
tableWidget.setRowCount(5);
QStringList headers;
headers << "ID" << "Name" << "Age" << "Sex";
tableWidget.setHorizontalHeaderLabels(headers);
tableWidget.setItem(0, 0, new QTableWidgetItem(QString("0001")));
tableWidget.setItem(1, 0, new QTableWidgetItem(QString("0002")));
tableWidget.setItem(2, 0, new QTableWidgetItem(QString("0003")));
tableWidget.setItem(3, 0, new QTableWidgetItem(QString("0004")));
tableWidget.setItem(4, 0, new QTableWidgetItem(QString("0005")));
tableWidget.setItem(0, 1, new QTableWidgetItem(QString("20100112")));
tableWidget.show();
|
这段代码运行起来是这样子的:
首先我们创建了QTableWidget
对象,然后设置列数和行数。接下来使用一个QStringList
,设置每一列的标题。我们可以通过调用setItem()
函数来设置表格的单元格的数据。这个函数前两个参数分别是行索引和列索引,这两个值都是从 0 开始的,第三个参数则是一个QTableWidgetItem
对象。Qt 会将这个对象放在第 row 行第 col 列的单元格中。有关QTableWidgetItem
的介绍完全可以参见上面的QListWidgetItem
和QTreeWidgetItem
。
Qt 学习之路 2(42):QListWidget、QTreeWidget 和 QTableWidget的更多相关文章
- Qt 学习之路 2(41):model/view 架构
Qt 学习之路 2(41):model/view 架构 豆子 2013年1月23日 Qt 学习之路 2 50条评论 有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应 ...
- 《Qt 学习之路 2》目录
<Qt 学习之路 2>目录 <Qt 学习之路 2>目录 豆子 2012年8月23日 Qt 学习之路 2 177条评论 <Qt 学习之路 2>目录 序 Qt ...
- Qt 学习之路 2(71):线程简介
Qt 学习之路 2(71):线程简介 豆子 2013年11月18日 Qt 学习之路 2 30条评论 前面我们讨论了有关进程以及进程间通讯的相关问题,现在我们开始讨论线程.事实上,现代的程序中,使用线程 ...
- Qt 学习之路 2(67):访问网络(3)
Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...
- Qt 学习之路 2(66):访问网络(2)
Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2) 豆子 2013年10月31日 Qt 学习之路 2 27条评论 上一 ...
- Qt 学习之路 2(61):使用 SAX 处理 XML
Qt 学习之路 2(61):使用 SAX 处理 XML 豆子 2013年8月13日 Qt 学习之路 2 没有评论 前面两章我们介绍了使用流和 DOM 的方式处理 XML 的相关内容,本章将介绍 ...
- Qt 学习之路 2(60):使用 DOM 处理 XML
Qt 学习之路 2(60):使用 DOM 处理 XML 豆子 2013年8月3日 Qt 学习之路 2 9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...
- Qt 学习之路 2(59):使用流处理 XML
Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...
- Qt 学习之路 2(53):自定义拖放数据
Qt 学习之路 2(53):自定义拖放数据 豆子 2013年5月26日 Qt 学习之路 2 13条评论上一章中,我们的例子使用系统提供的拖放对象QMimeData进行拖放数据的存储.比如使用QM ...
随机推荐
- 459. Repeated Substring Pattern 判断数组是否由重复单元构成
[抄题]: Given a non-empty string check if it can be constructed by taking a substring of it and append ...
- logistic growth model . 求解方法 (高斯牛顿法)
https://www.stat.tamu.edu/~jnewton/604/chap4.pdf http://www.metla.fi/silvafennica/full/sf33/sf334327 ...
- Luogu 3350 [ZJOI2016]旅行者
BZOJ 4456 听若干个大佬讲过$n$遍终于写掉了. 我把时限基本上跑满了2333…… 分治 + 最短路. 首先我们去分治这个矩形格子,找到一条长边把它对半切,对切开的边上的每一个点跑一遍最短路然 ...
- App测试从入门到精通之更新测试
我们都知道,app在使用一段时间,都会有更新,而且更新会不止一次.在实际测试中,关于更新的测试场景也是我们需要重点关注的,接下来我们就看一下关于App的更新测试有哪些测试点我们需要注意: APP更新测 ...
- JQuery解决事件动画重复问题
开发项目时,经常要写动画效果,有时候会遇到动画重复问题,例如:当鼠标移动到某个元素上时,执行某个动画,当我鼠标多次移动到该元素时,该动画就要连续执行,那么怎么去解决呢? 话不多说,直接添代码,简单明了 ...
- python 读取mysql存储的文件路径下载文件,内容解析,上传七牛云,内容入es
#!/usr/bin/env python # -*- coding: utf-8 -*- import ConfigParser import json import os import re fr ...
- laravel中get方式表单提交后, 地址栏数据重复的问题
csrf_field这个要放form表单下面第一行的位置
- kali linux之被动信息收集(dns信息收集,区域传输,字典爆破)
公开可获取的信息,不与目标系统产生交互,避免留下痕迹 下图来自美军方 pdf链接:http://www.fas.org/irp/doddir/army/atp2-22-9.pdf 信息收集内容(可利用 ...
- Jmeter_Beanshell_使用Java处理JSON块
版权声明:本文为博主原创文章,转载请注明出处. [环境] ①Jmeter版本:3.2,JDK:1.8 ②前置条件:将json.jar包置于..\apache-jmeter-3.2\lib\下,并将该j ...
- IO相关3(string流)
sstream 头文件定义了三个类型来支持内存 IO,这些类型可以向 string 写入数据,从 string 读取数据,就像 string 是一个 IO 流一样. istringstream 从 s ...