目錄
一,關于多元素控件
?二,QListWidget
2.1 主要方法
2.2 實現新增刪除
三,Table Widget
3.1 主要方法
3.2 代碼演示
四,Tree Widget
4.1 主要方法
4.2 代碼演示
一,關于多元素控件
多元素控件就是一個控件里面包含了很多的元素,可能是字符串,也可能是復雜的數據結構、圖片等等,多元素控件有很多,典型的有6個:
- 列表:QListWidget,QListView
- 表格:QTableWidget,QTableView
- 樹形:QTreeWidget,QTreeView
可以發現,說是6個控件,其實是3個,只是兩兩一組而已
問題:xxWidget 和 xxView 是什么關系?
解答:
- 可以理解為 xxView 是很底層的實現,然后 xxWidget 是基于 xxView 的封裝而來
- xxView 是 MVC 結構的一種典型實現,但 xxView 只負責實現了食物,不負責數據如何存儲顯示,也不負責數據和視圖之間的交互
- 因此程序猿需要自動實現 model 和 controller 部分來使用 xxView,比較麻煩
- 所以Qt 為我們提供了 xxWidget,為我們實現好了 model 和 controller 并提供了功能很方便的 API,我們直接用就好
問題:什么是MVC?
解答: MVC 全稱 “Model-View-Controller”,是一種軟件涉及典范,是軟件開發中非常經典的一種軟件結構
- M:model,表示模型,或者叫數據,負責存取數據,并在數據變化時更新控制器
- V:view,表示視圖,或者叫界面,負責展示模型中的數據,并提供用戶界面
- C:Controller,表示控制器,是處理模型和視圖之間的業務流程,接收用戶輸入,并調用模型和視圖去完成用戶的需求
?二,QListWidget
2.1 主要方法
QListWidget 能夠顯示一個縱向的列表,并且每個選項都可以被選中, 和下拉按鈕行為類似
主要屬性:
屬性 | 說明 |
---|---|
currentRow | 當前被選中的是第幾行 |
count | 一共多少行 |
sortingEnabled | 是否允許排序 |
isWrapping | 是否允許換行 |
itemAlignment | 元素的對齊方式 |
selectRectVisible | 被選中的元素矩陣是否可見(默認背景藍色) |
spacing | 元素之間的間隔 |
常用的函數如下:
函數 | 說明 |
---|---|
addItem(const QString& label) addItem(QListWidgetItem* item) | 列表中添加元素 列表中的每一項稱為一個item,具體的說通過 QListWidgetgetItme 類表示的 |
currentItem() | 返回 QListWidgetgetItem* 表示當前選中的元素 |
setCurrentItem(QListWidgetItem* item) | 設置選中哪個元素 |
setCurrentRow(int row) | 設置選中第幾行元素 |
insertItem(const QString& label, int row) insertItem(QListWidgetItem* item, int row) | 在指定位置插入元素,插在指定位置之前 |
item(int row) | 返回 QListWidgetItem*,表示第 row 行的元素 |
takeItem(int row) | 刪除指定行的元素,返回 QListWidgetItem* ,表示是哪個元素被刪除了 |
常用的信號如下:
信號 | 說明 |
---|---|
currentItemChanged(QListWidgetItem* current, QListWidgetItem* old) | 選中不同元素時觸發,參數是當前選中的元素和之前選中的元素 |
currentRowChanged(int) | 選中不同元素時觸發,參數是當前選中元素的行數 |
itemClicked(QListWidgetItem* item) | 點擊某個元素時觸發 |
itemDoubleClicked(QListWidgetItem* item) | 雙擊某個元素時觸發 |
itemEntered(QListWidgetItem* item)鼠標進入元素時觸發 | 鼠標進入元素時觸發 |
上面說到了QListWidgetItem 類,這個類是負責表示 QListWidget 中的一個元素,本質上由“文本 + 圖標”構成,常用方法如下:
方法 | 說明 |
---|---|
setFont | 設置字體 |
setIcon | 設置圖標 |
setHidden | 設置隱藏 |
setSizeHint | 設置尺寸 |
setSelected | 設置是否選中 |
setText | 設置文本 |
setTextAlignment | 設置文本對齊方式 |
2.2 實現新增刪除
先創建下列控件:
兩個都可以,因為可以轉換,如下:
代碼如下:
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QShortcut>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// ui->listWidget->addItem("C++");
// ui->listWidget->addItem("Pyhton");
// ui->listWidget->addItem("Java");ui->listWidget->addItem(new QListWidgetItem("C++"));ui->listWidget->addItem(new QListWidgetItem("Python"));ui->listWidget->addItem(new QListWidgetItem("Java"));//兩種方式都可以添加,也可以直接在ui界面例右鍵編輯項目添加//QListWidgetItem 也可以設置字體屬性,圖標,大小等等
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_insert_clicked()
{const QString& text = ui->lineEdit->text(); //先獲取輸入框的內容ui->listWidget->addItem(text); //將內容添加到表格里
}void Widget::on_pushButton_delete_clicked()
{int row = ui->listWidget->currentRow(); //先獲取被選中的元素if(row < 0) return;ui->listWidget->takeItem(row);
}
效果如下:
三,Table Widget
3.1 主要方法
這個表示一個表格控件,簡單來說就是就是類似二維數組的結構,表格中的每個單元格是一個 QTableWidgetItem 對象,常用方法如下:
方法 | 說明 |
---|---|
item(int row, int column) | 根據行數列數獲取指定的 QtableWidgetItem* |
item(int row, int column) | 根據行數列數設置表格中的元素 |
currentItem() | 返回被選中的元素 QTableWidgetItem* |
currentRow() | 返回被選中的元素是第幾行 |
currentColumn() | 返回被選中的元素第幾列 |
row(QTableWidgetItem*) | 獲取指定 item 是第幾行 |
column(QTableWidgetItem*) | 獲取指定 item 是第幾列 |
rowCount() | 獲取行數 |
columnCount() | 獲取列數 |
insertRow(int row) | 在第 row 行處插入新行 |
insertColumn(int column) | 在第 column 行處插入新列 |
removeRow(int row) | 刪除第 row 行 |
removeColumn(int column) | 刪除第 column 行 |
setHorizontalHeaderItem(int column,? QTableWidget*) | 設置指定列的表頭 |
setVerticalHeaderItem(introw, QTableWidget*) | 設置指定行的表頭 |
主要的信號如下:
信號 | 說明 |
---|---|
cellClicked(int row, int column) | 點擊單元格時觸發 |
cellDoubleClicked(int row, int column) | 雙擊單元格時觸發 |
cellEntered(int row, int column) | 鼠標進入單元格時觸發 |
currentCellChanged(int row, int column, int previousRow, int? previousColumn) | 選中不同單元格時觸發 |
關于 QTableWidgetItem 和上面的 QListWidgetItem 類似,主要方法如下:
方法 | 說明 |
---|---|
row() | 獲取當前是第幾行 |
column() | 獲取當前是第幾列 |
setText(const QString&) | 設置文本 |
setTextAlignment(int) | 設置文本對齊 |
setIcon(const QIcon&) | 設置圖標 |
setSelected(bool) | 設置被選中 |
setSizeHints(const QSize&) | 設置尺寸 |
setFont(const QFont&) | 設置字體 |
3.2 代碼演示
先創建下列控件:
我們先往表格里添加部分元素,在代碼添加太麻煩,所以我們這里直接右鍵編輯項目添加:
所以下面我們也使用文件來進行初始化數據,通過代碼初始化表格:
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->tableWidget->insertRow(0);ui->tableWidget->insertRow(1);ui->tableWidget->insertRow(2);ui->tableWidget->insertColumn(0);ui->tableWidget->insertColumn(1);ui->tableWidget->insertColumn(2);//給列設置列名,行名同理ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("學號"));ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("姓名"));ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("年齡"));//給表格添加數據ui->tableWidget->setItem(0, 0, new QTableWidgetItem("1001"));ui->tableWidget->setItem(0, 1, new QTableWidgetItem("張三"));ui->tableWidget->setItem(0, 2, new QTableWidgetItem("20"));ui->tableWidget->setItem(1, 0, new QTableWidgetItem("1002"));ui->tableWidget->setItem(1, 1, new QTableWidgetItem("李四"));ui->tableWidget->setItem(1, 2, new QTableWidgetItem("21"));ui->tableWidget->setItem(2, 0, new QTableWidgetItem("1003"));ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五"));ui->tableWidget->setItem(2, 2, new QTableWidgetItem("19"));
}
四個槽函數實現如下:
void Widget::on_pushButton_addRow_clicked()
{int rowCount = ui->tableWidget->rowCount(); //獲取總行數ui->tableWidget->insertRow(rowCount); //在最后一行新增行,這個參數是下標,所以不需要 + 1
}void Widget::on_pushButton_subRow_clicked()
{int subRow = ui->tableWidget->currentRow(); //獲取到選中的行號ui->tableWidget->removeRow(subRow); //刪除這一行
}void Widget::on_pushButton_addColumn_clicked()
{int columnCount = ui->tableWidget->columnCount(); //獲取總列數ui->tableWidget->insertColumn(columnCount); //在最后一列添加列const QString& text = ui->lineEdit->text(); //獲取輸入框里的列名ui->tableWidget->setHorizontalHeaderItem(columnCount, new QTableWidgetItem(text)); //給新增列添加列名
}void Widget::on_pushButton_subColumn_clicked()
{int subColumn = ui->tableWidget->currentColumn(); //獲取選中的列號ui->tableWidget->removeColumn(subColumn);
}
效果如下:
默認情況下表格內容是可編輯的,但是如果不想讓用戶編輯,可以設置下列屬性:
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
四,Tree Widget
4.1 主要方法
QTreeWidget 表示一個樹形控件,里面的每個元素都是一個 QTreeWidgetItem,這個類可以包含多個文本和圖標,每個文本/圖標為一個列?
構建一顆樹是先給 QTreeWidget 設置主節點,然后再添加子節點,就和二叉樹或者多叉樹那樣
QTreeWidget 常用的方法如下:
方法 | 說明 |
---|---|
clear | 清空所有子節點 |
addTopLevelItem(QTreeWidgetItem* item) | 新增頂層節點 |
topLevelItem(int index) | 獲取指定下標的頂層節點 |
topLevelItemCount() | 獲取頂層節點個數 |
indexOfTopLevelItem(QTreeWidgetItem* item) | 查詢指定節點是頂層節點中的下標 |
takeTopLevelItem(int index) | 刪除指定的頂層節點 返回QTreeWidgetItem*表示被刪除的元素 |
currentItem() | 獲取到當前選中的節點,返回QTreeWidgetItem* |
setCurrentItem(QTreeWidgetItem* item) | 選中指定節點 |
setExpanded(bool) | 展開/關閉節點 |
setHeaderLabel(constQString& text) | 設置TreeWidget 的 header 名稱 |
關于頂層節點:
上面的頂層節點,并不是單指根節點,因為QTreeWidget 的樹形結構,沒有體現出根節點,是從根節點的下一層子節點開始計算的,如下圖:
QTreeWidget 主要信號:
信號 | 說明 |
---|---|
currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old) | 切換選中元素時觸發 |
itemClicked(QTreeWidgetItem* item, int col) | 點擊元素時觸發 |
itemDoubleClicked(QTreeWidgetItem* item, int col) | 雙擊元素時觸發 |
itemEntered(QTreeWidgetItem* item, int col) | 鼠標進入時觸發 |
itemExpanded(QTreeWidgetItem* item) | 元素被展開時觸發 |
itemCollapsend(QTreeWidgetItem* item) | 元素被折疊時觸發 |
QTreeWidgetItem類的核心屬性如下:
屬性 | 說明 |
---|---|
text | 持有的文本 |
textAlignment | 文本對齊方式 |
icon | 持有的圖表 |
font | 文本字體 |
hidden | 是否隱藏 |
disabled | 是否禁用 |
expand | 是否展開 |
sizeHint | 尺寸大小 |
selected | 是否選中 |
QTreeWidgetItem 核心方法:
方法 | 說明 |
---|---|
addChild(QTreeWidgetItem* child) | 新增子節點 |
childCount() | 子節點的個數 |
child(int index) | 獲取指定下標的子節點.返回QTreeWidgetItem* |
takeChild(int index) | 刪除對應下標的子節點 |
removeChild(QTreeWidgetItem* child) | 刪除對應的子節點 |
parent() | 獲取該元素的父節點 |
4.2 代碼演示
先創建下列控件:
初始化數據我們可以通過 ui界面右鍵編輯項目直接添加,也可以通過代碼添加,和上面的表格是一樣的,下面是通過代碼初始化元素的代碼:
//篇幅原因這里也只添加部分元素
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->treeWidget->setHeaderLabel("動物"); //設置根節點名稱//添加頂層節點QTreeWidgetItem* item1 = new QTreeWidgetItem();item1->setText(0, "貓"); //每個節點都可設置多個列,為了方便演示就只設置一列ui->treeWidget->addTopLevelItem(item1); //添加進頂層節點QTreeWidgetItem* item2 = new QTreeWidgetItem();item2->setText(0, "狗");ui->treeWidget->addTopLevelItem(item2);QTreeWidgetItem* item3 = new QTreeWidgetItem();item3->setText(0, "鳥");ui->treeWidget->addTopLevelItem(item3);//添加子節點QTreeWidgetItem* item4 = new QTreeWidgetItem();item4->setText(0, "黑貓");item1->addChild(item4);QTreeWidgetItem* item5 = new QTreeWidgetItem();item5->setText(0, "貍花貓");item1->addChild(item5);QTreeWidgetItem* item6 = new QTreeWidgetItem();item6->setText(0, "橘貓");item1->addChild(item6);
}
下面是三個按鈕的槽函數實現:
void Widget::on_pushButton_insertTopLevelItem_clicked()
{const QString& text = ui->lineEdit->text(); //獲取輸入框內容QTreeWidgetItem* item = new QTreeWidgetItem();//構造 QTreeWidget 對象item->setText(0, text);ui->treeWidget->addTopLevelItem(item); //添加進頂層節點中
}void Widget::on_pushButton__insertItem_clicked()
{QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); //獲取當前選中的節點if(currentItem == nullptr) return;const QString& text = ui->lineEdit->text(); //獲取輸入框內容QTreeWidgetItem* item = new QTreeWidgetItem();//構造 QTreeWidget 對象item->setText(0, text);currentItem->addChild(item); //插入到選中節點的子節點中
}void Widget::on_pushButton_deleteItem_clicked()
{QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); //獲取當前選中的節點if(currentItem == nullptr) return;QTreeWidgetItem* parent = currentItem->parent(); //要先獲取父節點if(parent == nullptr) //如果父元素為空,那么說明這是一個頂層元素{int index = ui->treeWidget->indexOfTopLevelItem(currentItem); //要先獲取頂層元素的下標ui->treeWidget->takeTopLevelItem(index); //通過頂層元素進行刪除}else //普通元素{parent->removeChild(currentItem); //普通元素直接刪除即可}
}
上述幾個控件相關的操作,數據都是在內存中保存的,重新運行程序后,數據都會重置
所以要想數據不被丟失,就得需要和“學生管理系統”一樣,實現一個“保存數據到文件”和“從文件讀取數據”的兩個操作,每次運行程序時讀取文件數據,每次關閉程序時,在析構函數里添加保存文件的操作?