1. 程式人生 > >[ PyQt入門教程 ] PyQt5中資料表格控制元件QTableWidget使用方法

[ PyQt入門教程 ] PyQt5中資料表格控制元件QTableWidget使用方法

 如果你想讓你開發的PyQt5工具展示的資料顯得整齊、美觀、好看,顯得符合你的氣質,可以考慮使用QTableWidget控制元件。之前一直使用的是textBrowser文字框控制元件,資料展示還是不太美觀。其中QTableWidget是PyQt5程式中常用的顯示資料表格的控制元件,顯示的基本效果如下,有點素。。

  下面開始介紹QTableWidget常用的方法以及如何使用。既然是資料表格形式,經常使用的場景其實跟excel我覺得差不多。開始學習使用QTableWidget之前,我們帶著如下幾個問題再開始本文的閱讀。

  1、如何在GUI介面上建立QTableWidget表格?指定N行M列,列名稱等等

  2、如何在表格裡新增每一個單元格的資料?

  3、如何排版資料表格的資料,比如你想單元格內容居中、左對齊、右對齊等。

  4、如何設定文字顯示顏色、如何設定單元格背景色?

  5、如何合併指定單元格,讓排版更合理?

  基本上使用資料表格展示資料常見的問題就是這些,能夠熟練使用QTableWidget解決上述問題,QTableWidget基本使用方法應該就會了。下面開始學習本文內容。

QTableWidget常用方法

  setROwCount(int row)     設定QTableWidget表格控制元件的行數

  setColumnCount(int col)     設定QTableWidget表格控制元件的列數

  setHorizontalHeaderLabels()     設定QTableWidget表格控制元件的水平標籤

  setVerticalHeaderLabels()     設定QTableWidget表格控制元件的垂直標籤

  setItem(int ,int ,QTableWidgetItem)     在QTableWidget表格控制元件的每個選項的單元控制元件內新增控制元件

  horizontalHeader()     獲得QTableWidget表格控制元件的表格頭,以便執行隱藏

  rowCount()     獲得QTableWidget表格控制元件的行數

  columnCount()     獲得QTableWidget表格控制元件的列數

  setEditTriggers(EditTriggers triggers)     設定表格是否可以編輯,設定表格的列舉值

  setSelectionBehavior     設定表格的選擇行為

  setTextAlignment()     設定單元格內文字的對齊方式

  setSpan(int row,int column,int rowSpanCount,int columnSpanCount)     合併單元格,要改變單元格的第row行,column列,要合併rowSpancount行數和columnSpanCount列數。其中row表示要改變的行數, column表示要改變的列數,rowSpanCount表示需要合併的行數,columnSpanCount表示需要合併的列數。

  setShowGrid()     在預設情況下表格的顯示是有網格的,可以設定True或False用於是否顯示,預設True

  setColumnWidth(int column,int width)     設定單元格行的寬度

  setRowHeight(int row,int height)     設定單元格列的高度

  這裡的函式有些有點不好理解,比如setSpan()合併單元格函式,你可能一下不知道它的使用方法以及實現效果。沒關係,下面會通過例項講解以及效果演示展示這些函式的使用方法。

QTableWidget使用例項

 1、使用designer實現一個包含QTableWidget資料展示控制元件的窗體。介面設計一般都會採用designer工具,因為要考慮控制元件間的佈局,純程式碼實現會增加難度。介面實現如下

 雙擊在窗體介面上的QTableWidget控制元件,分別選擇Edit Table Widget中Columns、Rows、Items進行編輯。可以分別完成行、列標題以及單元格內容的新增。

 完成後,效果圖如下

 2、使用pyuic5工具將.ui檔案轉換為.py檔案。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'cc.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_widget(object):
    def setupUi(self, widget):
        widget.setObjectName("widget")
        widget.resize(730, 574)
        self.tableWidget = QtWidgets.QTableWidget(widget)
        self.tableWidget.setGeometry(QtCore.QRect(10, 130, 701, 192))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(4)
        self.tableWidget.setRowCount(3)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        item.setTextAlignment(QtCore.Qt.AlignCenter)
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(2, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(2, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(2, 2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(2, 3, item)
        self.tableWidget.horizontalHeader().setCascadingSectionResizes(True)

        self.retranslateUi(widget)
        QtCore.QMetaObject.connectSlotsByName(widget)

    def retranslateUi(self, widget):
        _translate = QtCore.QCoreApplication.translate
        widget.setWindowTitle(_translate("widget", "員工資訊表"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("widget", "1"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("widget", "2"))
        item = self.tableWidget.verticalHeaderItem(2)
        item.setText(_translate("widget", "3"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("widget", "姓名"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("widget", "年齡"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("widget", "性別"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("widget", "基本資訊"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        item = self.tableWidget.item(0, 0)
        item.setText(_translate("widget", "張三"))
        item = self.tableWidget.item(0, 1)
        item.setText(_translate("widget", "23"))
        item = self.tableWidget.item(0, 2)
        item.setText(_translate("widget", "Male"))
        item = self.tableWidget.item(0, 3)
        item.setText(_translate("widget", "家裡有礦"))
        item = self.tableWidget.item(1, 0)
        item.setText(_translate("widget", "王八"))
        item = self.tableWidget.item(1, 1)
        item.setText(_translate("widget", "25"))
        item = self.tableWidget.item(1, 2)
        item.setText(_translate("widget", "Female"))
        item = self.tableWidget.item(1, 3)
        item.setText(_translate("widget", "拆二代"))
        item = self.tableWidget.item(2, 0)
        item.setText(_translate("widget", "趙四"))
        item = self.tableWidget.item(2, 1)
        item.setText(_translate("widget", "28"))
        item = self.tableWidget.item(2, 2)
        item.setText(_translate("widget", "Male"))
        item = self.tableWidget.item(2, 3)
        item.setText(_translate("widget", "勤奮努力的程式設計師"))
        self.tableWidget.setSortingEnabled(__sortingEnabled)

附designer工具設計完成的.ui檔案程式碼。不作展示,方便有需要的讀者下載使用。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>widget</class>
 <widget class="QWidget" name="widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>730</width>
    <height>286</height>
   </rect>
  </property>
  <property name="font">
   <font>
    <pointsize>10</pointsize>
   </font>
  </property>
  <property name="windowTitle">
   <string>員工資訊表</string>
  </property>
  <widget class="QTableWidget" name="tableWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>51</y>
     <width>701</width>
     <height>211</height>
    </rect>
   </property>
   <attribute name="horizontalHeaderCascadingSectionResizes">
    <bool>true</bool>
   </attribute>
   <row>
    <property name="text">
     <string>1</string>
    </property>
   </row>
   <row>
    <property name="text">
     <string>2</string>
    </property>
   </row>
   <row>
    <property name="text">
     <string>3</string>
    </property>
   </row>
   <column>
    <property name="text">
     <string>姓名</string>
    </property>
    <property name="textAlignment">
     <set>AlignCenter</set>
    </property>
   </column>
   <column>
    <property name="text">
     <string>年齡</string>
    </property>
   </column>
   <column>
    <property name="text">
     <string>性別</string>
    </property>
   </column>
   <column>
    <property name="text">
     <string>基本資訊</string>
    </property>
   </column>
   <item row="0" column="0">
    <property name="text">
     <string>張三</string>
    </property>
   </item>
   <item row="0" column="1">
    <property name="text">
     <string>23</string>
    </property>
   </item>
   <item row="0" column="2">
    <property name="text">
     <string>Male</string>
    </property>
   </item>
   <item row="0" column="3">
    <property name="text">
     <string>家裡有礦</string>
    </property>
   </item>
   <item row="1" column="0">
    <property name="text">
     <string>王八</string>
    </property>
   </item>
   <item row="1" column="1">
    <property name="text">
     <string>25</string>
    </property>
   </item>
   <item row="1" column="2">
    <property name="text">
     <string>Female</string>
    </property>
   </item>
   <item row="1" column="3">
    <property name="text">
     <string>拆二代</string>
    </property>
   </item>
   <item row="2" column="0">
    <property name="text">
     <string>趙四</string>
    </property>
   </item>
   <item row="2" column="1">
    <property name="text">
     <string>28</string>
    </property>
   </item>
   <item row="2" column="2">
    <property name="text">
     <string>Male</string>
    </property>
   </item>
   <item row="2" column="3">
    <property name="text">
     <string>勤奮努力的程式設計師</string>
    </property>
   </item>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>250</x>
     <y>20</y>
     <width>111</width>
     <height>21</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>YaHei Consolas Hybrid</family>
     <pointsize>10</pointsize>
    </font>
   </property>
   <property name="text">
    <string>員工資訊展示</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
View Code

 3、編寫主程式,呼叫介面.py檔案。使業介面和邏輯程式分離,這樣的好處就是後面介面任何改動程式邏輯幾乎不會有什麼大的影響。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'connect_me.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
#匯入程式執行必須模組
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QColor, QBrush
from cc import Ui_widget


class MyMainForm(QMainWindow, Ui_widget):
    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.setupUi(self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainForm()
    myWin.show()
    sys.exit(app.exec_())

 執行程式結果如下:

 4、程式執行可以正常顯示介面,但是介面並不是很美觀(比如行、列沒有鋪滿整個顯示視窗、列標題文字沒有加粗等)。下面通過QTableWidget相關函式的使用來實現優化。

QTableWidget函式使用方法

  上述基本例子實現了員工資訊表格展示的初始化,單元格內容手工新增其實在實現場景不合適,只是方便展示,下面講解如何通過程式碼實現方式新增單元格內容以及實現單元格內容顏色、字型變化的實現。說明,下述所有程式碼新增都在主程式中完成。目的是使程式實現更靈活,方便維護。

 (1)初始化QTableWidget資料展示視窗物件。一般來說該步驟通常是通過designer實現。

self.tableWidget = QtWidgets.QTableWidget(widget)
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(3)

  設定表格的行、列標題,如下:

self.tableWidget.setHorizontalHeaderLabels(['姓名','年齡'])
self.tableWidget.setVerticalHeaderLabels(['1','2'])

 當然也可以通過上面例子中的方式去新增,如下:

item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(1, item)

item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)

(2)設定表格頭的伸縮模式,也就是讓表格鋪滿整個QTableWidget控制元件。

self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
效果如下:

 (2)將表格變為禁止編輯。預設情況下表格中的字串是可以更改的,比如雙擊一個單元格,就可以修改運來的內容。如果想禁止這種操作,讓表格對使用者是隻讀的,可以新增如下程式碼。

self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

執行效果(雙擊單元格不可編輯,提前觀察一下滑鼠單擊選中的只是單元格):

(3)設定表格整行選中。表格預設選中的是單個單元格。通過下面程式碼可以設定成選中整行。新增程式碼如下

self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)

執行效果如下:

 (4)行、列標題的顯示與隱藏。

  對於列標題的顯示或隱藏設定,可以通過新增如下程式碼實現。預設是顯示的。

self.tableWidget.horizontalHeader().setVisible(False)

執行效果如下(行標題不再顯示):
對於行標題,可以使用如下程式碼進行隱藏或顯示設定。預設是顯示
self.tableWidget.verticalHeader().setVisible(

 (5)在表格中新增內容。程式碼如下:

        items = [['燕十三','21','Male','武林大俠'],['蕭十一郎','21','Male','武功好']]

        for i in range(len(items)):
            item = items[i]
            row = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row)
            for j in range(len(item)):
                item = QTableWidgetItem(str(items[i][j]))
                self.tableWidget.setItem(row,j,item)

執行結果如下:

(6) 設定表格標題字型加粗。新增程式碼如下:

font = self.tableWidget.horizontalHeader().font()
font.setBold(True)
self.tableWidget.horizontalHeader().setFont(font)

執行效果如下

(7) 設定表格指定列寬。新增程式碼如下:

self.tableWidget.horizontalHeader().resizeSection(0,100)
self.tableWidget.horizontalHeader().resizeSection(1,100)
self.tableWidget.horizontalHeader().resizeSection(1,100)
self.tableWidget.horizontalHeader().resizeSection(3,400)
#self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) 一定要註釋,否則上述設定不生效

說明,表頭的自適應模式要註釋,否則上述設定不生效。執行效果如下:

 (8)合併單元格,新增如下程式碼

self.tableWidget.setSpan(0,3,2,1)

執行結果如下:

 這裡再補充描述一下setSpan()函式。setSpan(0,3,2,1)函式中(0,3)會指定到單元格第1行第4列(下標都是從0開始計算),(2,1)分別表示合併2行(把下一行合併了),1列(1列,列其實沒有合併)。我們把程式碼修改為setSpan(1,2,3,2)。看效果如下(很直觀了吧):

(9)對齊單元格中的內容。新增程式碼如下:

for i in range(len(items)):
    each_item = items[i]
    row = self.tableWidget.rowCount()
    self.tableWidget.insertRow(row)
    for j in range(len(each_item)):
        item = QTableWidgetItem(str(items[i][j]))
        if j != len(each_item) -1:
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.tableWidget.setItem(row,j,item)

  關鍵程式碼就是item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)。前面3列居中顯示,最後一列靠左顯示。執行效果如下:

 (10)設定單元格字型顏色和背景顏色。新增程式碼如下:

for i in range(len(items)):
    each_item = items[i]
    row = self.tableWidget.rowCount()
    self.tableWidget.insertRow(row)
    for j in range(len(each_item)):
        item = QTableWidgetItem(str(items[i][j]))
        if j != len(each_item) -1:
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            item.setForeground(QBrush(QColor(255,0,0)))  #設定除最後一列外的文字顏色為紅色
        else:
            item.setBackground(QBrush(QColor(0,255,0)))  #設定最後一列的背景色為綠色
        self.tableWidget.setItem(row,j,item)

執行結果如下所示:

 QTableWidget控制元件的基本使用方法就到這裡,後續有其他更好的使用技巧會繼續更新,為方便自己及大家閱讀本文,附本文使用到的程式碼如下:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'connect_me.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!
#匯入程式執行必須模組
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QColor, QBrush
from PyQt5.QtCore import Qt
from cc import Ui_widget


class MyMainForm(QMainWindow, Ui_widget):
    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.setupUi(self)
        #self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        #self.tableWidget.horizontalHeader().setVisible(False)
        self.tableWidget.verticalHeader().setVisible(False)
        font = self.tableWidget.horizontalHeader().font()
        font.setBold(True)
        self.tableWidget.horizontalHeader().setFont(font)
        self.tableWidget.horizontalHeader().resizeSection(0,100)
        self.tableWidget.horizontalHeader().resizeSection(1,100)
        self.tableWidget.horizontalHeader().resizeSection(1,100)
        self.tableWidget.horizontalHeader().resizeSection(3,400)
        #self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        items = [['燕十三','21','Male','武林大俠'],['蕭十一郎','21','Male','武功好']]
        for i in range(len(items)):
            each_item = items[i]
            row = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row)
            for j in range(len(each_item)):
                item = QTableWidgetItem(str(items[i][j]))
                if j != len(each_item) -1:
                    item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                    item.setForeground(QBrush(QColor(255,0,0)))
                else:
                    item.setBackground(QBrush(QColor(0,255,0)))
                self.tableWidget.setItem(row,j,item)

        self.tableWidget.setSpan(1,2,3,2)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainForm()
    myWin.show()
    sys.exit(app.exec_())

 總結

  本文描述PyQt5的QTableWidget控制元件的基本使用方法和效果,介面實現建議還是desiger設計工具實現,同時使用業務和邏輯相分離的方式編寫程式,都揉在一塊後面程式就不好維護,畢竟沒有誰的工具實現是可以一蹴而就的,還是要考慮可維護性。讀完本文內容相信讀者就可以上手使用QTableWidget控制元件了