天天看點

第24天 | 28天學會PyQt5,進階控件之QTableView

進階元件不是說這個元件有多”進階”的意思,而是表示功能強大的意思。如要實作一個功能完整的表格功能,可能需要花上好幾天,編寫好多代碼才能實作,而直接調用wx.Grid元件,三兩下就搞定了,是以說這個元件很進階。

PyQt5常用的進階元件有表格視圖控件QTableView和QTableWidget、清單視圖QList

View和QListWidget,樹狀結構QTreeWidget和标簽視圖QTabWidget。

表格視圖控件QTableView需要和資料模型配套使用。表格的資料模型,需要填上每一行每一列的資料,就像execl表格一樣。

QTableView是基于MVC模式設計的,M(Model)是資料模型,V(view)是指QTableView視圖,用來顯示資料模型,C(controllor)是控制器,與View合并到一起了。通過setModel()方法綁定資料源。它常用方法如下表所示:

方法 描述
setSpan(int, int, int, int) 合并行列,4個參數分别是起始行、起始列、合并行數和清單;
clearSpans() 清除所有合并的單元格(取消合并);
setSelectionBehavior()

值為

QAbstractItemView.SelectRows時,将按行選中,而不是預設的可選中所有行;

setSelectionModel()

值為

QAbstractItemView.SingleSelection時,将按單元格選中,而不是預設的可選中所有行;

setEditTriggers() 值為QTableView.NoEditTriggers時,将單元格置為不可編輯;
hideColumn(int column) 隐藏指定的列;
showColumn(int column) 顯示指定的列;
hideRow(int row) 隐藏指定的行;
showRow(int row) 顯示指定的行;
horizontalHeader() 傳回水準表頭對象,調用setSectionResizeMode(QHeaderView.Stretch)時,所有列平均配置設定;調用setStretchLastSection(True)時,最後一列自動拉伸。
isColumnHidden(int column) 傳回bool值,表示列是否處于隐藏狀态;
isRowHidden(int row) 傳回bool值,表示行是否處于隐藏狀态;
resizeColumnToContents(int column) 根據内容調整指定列的列寬,column為列的下标,從0開始;
resizeColumnsToContents() 根據内容調整所有列的列寬;
resizeRowToContents(int row) 根據内容調整指定行的行高,row為行的下标,從0開始;
resizeRowsToContents() 根據内容調整所有行的行高;

sortByColumn(int column,

SortOrder order)

對column進行排序,排序方式由order指定, Qt.DescendingOrder降序,Qt.AscendingOrder升序;
setModel(QAbstractItemModel) 綁定模型資料。

表格視圖控件QTableView可以綁定的模型資料如下表所示:

模型名稱 描述
QStringListModel 儲存一組字元串;
QStandardItemModel 存儲任意層次結構的資料;
QDirModel 對檔案系統進行封裝;
QSqlQueryModel 對SQL的查詢結果集進行封裝;
QSqlTableModel 對SQL中的表格進行封裝;
QSqlRelationalTableModel 對帶有foreign key的SQL表格進行封裝。

模型的常用方法如下表所示:

方法 描述
setHorizontalHeaderLabels([str] labels) 用于一次性順序設定水準表頭多個節顯示的文本,該方法無傳回值。設定了标簽的節自動會建立該節對應的項;
setVerticalHeaderLabels([str] labels) 用于一次性順序設定垂直表頭多個節顯示的文本,該方法無傳回值。設定了标簽的節自動會建立該節對應的項;
setItem() 向模闆裡添加item;
appendRow() 添加QStandItem資料;

findItems(str,Qt.MatchExactly,

int column)

在指定列裡查找資料,傳回List;
removeRows(int row) 删除指定行的資料;
data(QModelIndex index) 擷取單元格的值;
columnCount() 擷取總列數;

程式清單:table.py

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget,
  QHBoxLayout, QTableView, QAbstractItemView
from PyQt5.QtGui import QStandardItemModel, QStandardItem, 
  QBrush, QColor
from PyQt5.QtCore import Qt


# 繼承QWidget
class TableViewWidget(QWidget):
    customer_list = [("張三", "男", "1981-06-02", "13888888888",
                      "南極路企鵝臨舍傍9号999路"),
                     ("李四", "男", "1988-08-08", "13999999999",
                      "北極熊店的下坡路中6号666路"),
                     ("李清照", "女", "1986-06-06", "13666666666",
                      "秦嶺古詩廟灣道8号888路")]
    itemModel = None

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 設定布局
        layout = QHBoxLayout()
        table_view = QTableView(self)
        # 資料層次結構,10行5列
        self.itemModel = QStandardItemModel(10, 5)
        # 表頭
        self.itemModel.setHorizontalHeaderLabels(["姓名", "性别", "生日", 
                                                  "手機号", "位址"])
        # 輸入内容
        for (row, customer) in enumerate(self.customer_list):
            for column in range(len(customer)):
                self.itemModel.setItem(row, column, 
                                       QStandardItem(customer[column]))
        # 綁定資料源
        table_view.setModel(self.itemModel)
        # 最後一列自動拉伸
        table_view.horizontalHeader().setStretchLastSection(True)
        items = self.itemModel.findItems("13666666666", 
                                         Qt.MatchExactly, 3)
        # 設定單元格的背脊顔色為紅
        if len(items) > 0:
            items[0].setForeground(QBrush(QColor(255, 0, 0)))
        layout.addWidget(table_view)
        # 合并行列
        table_view.setSpan(0, 1, 2, 1)
        # 單元格不可編輯
        table_view.setEditTriggers(QTableView.NoEditTriggers)
        # 選擇單行
        table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 單擊事件
        table_view.clicked.connect(self.table_click)
        # 輕按兩下事件
        table_view.doubleClicked.connect(self.double_click)
        self.setLayout(layout)
        # 調整視窗大小
        self.resize(900, 500)
        # 視窗居中
        self.center()
        # 視窗标題
        self.setWindowTitle("表格應用")
        # 顯示視窗
        self.show()
        # 擷取檔案夾路徑

    def table_click(self, model_index):
        # 選中行和列的下标
        row = model_index.row()
        column = model_index.column()
        item = self.itemModel.index(row, column).data()
        print("選中單元格的值:%s" % item)
        # 選中單元格的值
        column_data = self.itemModel.data(model_index)
        print("選中單元格的值:%s" % column_data)
        # 總列數
        column_count = self.itemModel.columnCount()
        for i in range(column_count):
            # 根據行列擷取單元格裡的值
            item = self.itemModel.index(row, i).data()
            print(item, end=" ")

    def double_click(self, model_index):
        # 選中單元格的值
        column_data = self.itemModel.data(model_index)
        print(column_data)

    # 實作居中
    def center(self):
        f = self.frameGeometry()
        c = QDesktopWidget().availableGeometry().center()
        f.moveCenter(c)
        self.move(f.topLeft())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = TableViewWidget()
    sys.exit(app.exec_())
           

運作程式之後,彈出的視窗如下:

第24天 | 28天學會PyQt5,進階控件之QTableView

好了,QTableView的内容就說到這了,關注我,下一節更精彩。

今日頭條:老陳說程式設計,到2021年國慶節,Python就全部分享完了,完整的課程有:

1.《12天搞定Python》

2.《16天搞定Python資料分析》

3.《10天搞定Python網絡爬蟲》

4. 《Django3.0項目實戰》

5. 《25天學會Wxpython》

6. 《28天學會PyQt5》釋出中

7. 《25天學會Seaborn資料分析》在csdn釋出完了

8. 《3天搞定Pyecharts資料分析》國慶期間釋出