上一章咱們瞭解了 model/view 架構的基本概念。如今咱們從最簡單的QListWidget
、QTreeWidget
和QTableWidget
三個類開始瞭解最簡單的 model/view 的使用。這部份內容的確很難組織。首先,從最標準的 model/view 開始,每每會糾結於複雜的代碼;可是,若是從簡單的 QListWidget
、QTreeWidget
和QTableWidget
開始,因爲這三個類都是繼承自各自的 view 類,很難避免 model/view 的相關內容。因而,咱們這部分的組織是,首先進行簡單的數據顯示,更復雜的設置則放在後面的章節。架構
QListWidget
咱們要介紹的第一個是QListWidget
。先來看下面的代碼示例:函數
label = new QLabel(this); label->setFixedWidth(70); listWidget = new QListWidget(this); new QListWidgetItem(QIcon(":/images/Baidu"), tr("Baidu"), listWidget); new QListWidgetItem(QIcon(":/images/Chrome"), tr("Chrome"), listWidget); listWidget->addItem(new QListWidgetItem(QIcon(":/images/IE"), tr("IE"))); listWidget->addItem(new QListWidgetItem(QIcon(":/images/Firefox"),tr("Firefox"))); listWidget->addItem(new QListWidgetItem(QIcon(":/images/Opera"), tr("Opera"))); QListWidgetItem *newItem = new QListWidgetItem; newItem->setIcon(QIcon(":/images/UC")); newItem->setText(tr("UC")); listWidget->insertItem(3, newItem); listWidget->setViewMode(QListView::IconMode); 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
添加列表項能夠:第一,使用下面的語句this
new QListWidgetItem(QIcon(":/images/Chrome"), tr("Chrome"), listWidget);
第二,使用spa
listWidget->addItem(new QListWidgetItem(QIcon(":/images/IE"), tr("IE"))); // 或者 QListWidgetItem *newItem = new QListWidgetItem; newItem->setIcon(QIcon(":/images/UC")); newItem->setText(tr("UC")); listWidget->insertItem(3, newItem);
注意這兩種添加方式的區別:第一種須要在構造時設置所要添加到的QListWidget
對象;第二種方法不須要這樣設置,而是要調用addItem()
或者insertItem()
自行添加。若是你仔細查閱QListWidgetItem
的構造函數,會發現有一個默認的type
參數。該參數有兩個合法值:QListWidgetItem::Type
(默認)和QListWidgetItem::UserType
。若是咱們繼承QListWidgetItem
,能夠設置該參數,做爲咱們子類的一種區別,以便可以在QListWidget
區別處理不一樣子類。code
咱們的程序的運行結果以下:對象
咱們能夠利用QListWidget
發出的各類信號來判斷是哪一個列表項被選擇,具體細節能夠參考文檔。另外,咱們也能夠改變列表的顯示方式。前面的列表是小圖標顯示,咱們也能夠更改成圖標顯示,只要添加一行語句:繼承
listWidget->setViewMode(QListView::IconMode);
結果以下:索引
QTreeWidget
咱們要介紹的第二個組件是QTreeWidget
。顧名思義,這是用來展現樹型結構(也就是層次結構)的。同前面說的QListWidget
相似,這個類須要同另一個輔助類QTreeWidgetItem
一塊兒使用。不過,既然是提供方面的封裝類,即使是看上去很複雜的樹,在使用這個類的時候也是顯得比較簡單的。當不須要使用複雜的QTreeView
特性的時候,咱們能夠直接使用QTreeWidget
代替。資源
下面咱們使用代碼構造一棵樹:文檔
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
有不少重載的構造函數。咱們在這裏看看其中的一個,其他的請自行查閱文檔。這個構造函數的簽名以下:
QTreeWidgetItem(QTreeWidget *parent, const QStringList &strings, int type = Type);
這裏有 3 個參數,第一個參數用於指定這個項屬於哪個樹,相似前面的QListWidgetItem
,若是指定了這個值,則意味着該項被直接添加到樹中;第二個參數指定顯示的文字;第三個參數指定其類型,同QListWidgetItem
的type
參數十分相似。值得注意的是,第二個參數是QStringList
類型的,而不是QString
類型。咱們會在下文了解其含義。
在這段代碼中,咱們建立了做爲根的QTreeWidgetItem
root。而後添加了第一個葉節點,以後又添加一個,而這個則設置了可選標記。最後,咱們將這個 root 添加到一個QTreeWidgetItem
的列表,做爲QTreeWidget
的數據項。此時你應該想到,既然QTreeWidget
接受QList
做爲項的數據,它就可以支持多棵樹的一塊兒顯示,而不只僅是單根樹。下面咱們來看看運行結果:
從代碼來看,咱們可以想象到這個樣子,只是這個樹的頭上怎麼會有一個 1?還記得咱們跳過去的那個函數嗎?下面咱們修改一下代碼看看:
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
並不比前面的兩個複雜到哪裏去,這點咱們能夠從代碼看出來:
QTableWidget tableWidget; tableWidget.setColumnCount(4); 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
。