Qt 学习之路 2(42):QListWidget、QTreeWidget 和 QTableWidget

http://www.devbean.net/2013/02/qt-study-road-2-qlistwidget-qtreewidget-qtablewidget/

上一章我们了解了 model/view 架构的基本概念。现在我们从最简单的QListWidgetQTreeWidgetQTableWidget三个类开始了解最简单的 model/view 的使用。这部分内容的确很难组织。首先,从最标准的 model/view 开始,往往会纠结于复杂的代码;但是,如果从简单的 QListWidgetQTreeWidgetQTableWidget开始,由于这三个类都是继承自各自的 view 类,很难避免 model/view 的相关内容。于是,我们这部分的组织是,首先进行简单的数据显示,更复杂的设置则放在后面的章节。

QListWidget

我们要介绍的第一个是QListWidget。先来看下面的代码示例:

12345678910111213141516171819202122232425262728

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是简单的列表组件。当我们不需要复杂的列表时,可以选择QListWidgetQListWidget中可以添加QListWidgetItem类型作为列表项,QListWidgetItem即可以有文本,也可以有图标。上面的代码显示了三种向列表中添加列表项的方法(实际是两种,后两种其实是一样的),我们的列表组件是listWidget,那么,向listWidget添加列表项可以:第一,使用下面的语句

1

new QListWidgetItem(QIcon(":/Chrome.png"), tr("Chrome"), listWidget);

第二,使用

123456

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代替。

下面我们使用代码构造一棵树:

1234567891011121314

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添加QTreeWidgetItemQTreeWidgetItem有很多重载的构造函数。我们在这里看看其中的一个,其余的请自行查阅文档。这个构造函数的签名如下:

1

QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type = Type);

这里有 3 个参数,第一个参数用于指定这个项属于哪一个树,类似前面的QListWidgetItem,如果指定了这个值,则意味着该项被直接添加到树中;第二个参数指定显示的文字;第三个参数指定其类型,同QListWidgetItemtype参数十分类似。值得注意的是,第二个参数是QStringList类型的,而不是QString类型。我们会在下文了解其含义。

在这段代码中,我们创建了作为根的QTreeWidgetItemroot。然后添加了第一个叶节点,之后又添加一个,而这个则设置了可选标记。最后,我们将这个 root 添加到一个QTreeWidgetItem的列表,作为QTreeWidget的数据项。此时你应该想到,既然QTreeWidget接受QList作为项的数据,它就能够支持多棵树的一起显示,而不仅仅是单根树。下面我们来看看运行结果:

从代码来看,我们能够想象到这个样子,只是这个树的头上怎么会有一个 1?还记得我们跳过去的那个函数吗?下面我们修改一下代码看看:

1234567891011121314151617181920

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

我们要介绍的最后一个是 QTableWidgetQTableWidget并不比前面的两个复杂到哪里去,这点我们可以从代码看出来:

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的介绍完全可以参见上面的QListWidgetItemQTreeWidgetItem

上一章我们了解了 model/view 架构的基本概念。现在我们从最简单的QListWidgetQTreeWidgetQTableWidget三个类开始了解最简单的 model/view 的使用。这部分内容的确很难组织。首先,从最标准的 model/view 开始,往往会纠结于复杂的代码;但是,如果从简单的 QListWidgetQTreeWidgetQTableWidget开始,由于这三个类都是继承自各自的 view 类,很难避免 model/view 的相关内容。于是,我们这部分的组织是,首先进行简单的数据显示,更复杂的设置则放在后面的章节。

QListWidget

我们要介绍的第一个是QListWidget。先来看下面的代码示例:

12345678910111213141516171819202122232425262728

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是简单的列表组件。当我们不需要复杂的列表时,可以选择QListWidgetQListWidget中可以添加QListWidgetItem类型作为列表项,QListWidgetItem即可以有文本,也可以有图标。上面的代码显示了三种向列表中添加列表项的方法(实际是两种,后两种其实是一样的),我们的列表组件是listWidget,那么,向listWidget添加列表项可以:第一,使用下面的语句

1

new QListWidgetItem(QIcon(":/Chrome.png"), tr("Chrome"), listWidget);

第二,使用

123456

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代替。

下面我们使用代码构造一棵树:

1234567891011121314

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添加QTreeWidgetItemQTreeWidgetItem有很多重载的构造函数。我们在这里看看其中的一个,其余的请自行查阅文档。这个构造函数的签名如下:

1

QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type = Type);

这里有 3 个参数,第一个参数用于指定这个项属于哪一个树,类似前面的QListWidgetItem,如果指定了这个值,则意味着该项被直接添加到树中;第二个参数指定显示的文字;第三个参数指定其类型,同QListWidgetItemtype参数十分类似。值得注意的是,第二个参数是QStringList类型的,而不是QString类型。我们会在下文了解其含义。

在这段代码中,我们创建了作为根的QTreeWidgetItemroot。然后添加了第一个叶节点,之后又添加一个,而这个则设置了可选标记。最后,我们将这个 root 添加到一个QTreeWidgetItem的列表,作为QTreeWidget的数据项。此时你应该想到,既然QTreeWidget接受QList作为项的数据,它就能够支持多棵树的一起显示,而不仅仅是单根树。下面我们来看看运行结果:

从代码来看,我们能够想象到这个样子,只是这个树的头上怎么会有一个 1?还记得我们跳过去的那个函数吗?下面我们修改一下代码看看:

1234567891011121314151617181920

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

我们要介绍的最后一个是 QTableWidgetQTableWidget并不比前面的两个复杂到哪里去,这点我们可以从代码看出来:

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的介绍完全可以参见上面的QListWidgetItemQTreeWidgetItem

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java成神之路

Java微信公众平台开发_03_消息管理之被动回复消息

上一节,我们启用服务器配置的时候,填写了一个服务器地址(url),如下图,这个url就是回调url,是开发者用来接收微信消息和事件的接口URL 。也就是说,用户...

1.2K5
来自专栏Seebug漏洞平台

“盲”逆向:iOS 应用 Blind 寻踪

原文地址:《"BLIND" Reversing - A Look At The Blind iOS App》

3817
来自专栏码匠的流水账

聊聊spring cloud gateway的RetryGatewayFilter

本文主要研究一下spring cloud gateway的RetryGatewayFilter

1692
来自专栏菩提树下的杨过

Lucene 2.0最基本的入门代码

public void Test1()         {             //建立一个内存目录             Lucene.Net.S...

2195
来自专栏Spring相关

SocketIo+SpringMvc实现文件的上传下载

socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示:

932
来自专栏BinarySec

一些pwn题目的解题思路[pwnable.kr] II

目录 以下是solution的目录 #mistake #shellshock #coin1 #blackjack #lotto #cmd1 Other 一些pw...

3895
来自专栏向治洪

react native 调用原生UI组件

在React Native开发过程中,有时我们想要使用原生的一个UI组件或者是js比较难以实现的功能时,我们可以在react Naitve应用程序中封装和植入已...

62110
来自专栏向治洪

将图库的图片剪切并保存

最近有些用户反映保存图片之后在系统图库找不到保存的图片,遂决定彻底查看并解决下。 Adnroid中保存图片的方法可能有如下两种: 第一种是自己写方法,如下代...

23610
来自专栏草根专栏

使用angular4和asp.net core 2 web api做个练习项目(一)

这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net一样. 我用的是wind...

6975
来自专栏web开发

登录验证码demo-java

在一些类似于管理系统的项目中,我们在登录时经常会用到图片验证码。这里把我自己写的一个小系统(后台是java语言)的验证码部分摘出来。 总体思路是后端有一个生成验...

83810

扫码关注云+社区

领取腾讯云代金券