PyQt5 表格控件(QTableWidget)

本篇介绍PyQt5的表格控件QTableWidget。QTableWidget类似于Excel的表,适用于显示结构化的数据。它的单元格是QTableWidgetItem实例,可以精准的控制每个单元格的文本和外观。

表格控件QTableWidget主要由三大部分组成:

  1. 水平表头,可用来设置每列的名称和列宽。可隐藏。
  2. 竖直表头,可用来设置每行的名称和行高。可隐藏。
  3. 各单元格,可设置文本,图标,或者设置为控件。

单元格的行数和列数可以在表格初始化时指定:

table = QTableWidget(2,3) #2行,3 列

也可以用setRowCount() 和 setColumnCount()指定:

table = QTableWidget()
table.setRowCount(2)
table.setColumnCount(3)

可隐藏表头

table.horizontalHeader().hide()
table.verticalHeader().hide()

设置水平表头的标签

table.setHorizontalHeaderLabels(["列1","列2","列2"])#表头标签默认从"1"开始,"1","2"...

设置竖直表头的标签

table.setVerticalHeaderLabels(["行1","行2"])#表头标签默认"1","2"...

注意,QTableWidget中行和列的索引都是从0开始。

其实,各表头项也是QTableWidgetItem实例,可通过更改属性精确设定字体,颜色,图标等外观行为。

设置列宽:

table.setColumnWidth (0,50) #第0列,宽50

设置行高:

table.setRowHeight (1,30) #第1行,高30

可禁止用户更改行高或列宽

table.verticalHeader().setDisabled(True) #不让用户改行高
table.horizontalHeader().setDisabled(True) #不让用户改列宽

也可设置为随窗口大小自动调整列宽:

table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

随窗口大小自动调整行高:

table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)

设置表格的编辑规则

table.setEditTriggers(QAbstractItemView.AllEditTriggers)

有以下规则可选:

第0项是禁止用户编辑表格,表格只用来显示可读的数据。

设置表格的选择模式:

table.setSelectionBehavior(QAbstractItemView.SelectItems)#默认

设定可自动排序(点击水平表头时,各行按该列数据自动排序):

table.setSortingEnabled (True)  #默认为False

设定单元格(QTableWidgetItem实例)的文本

item = QTableWidgetItem()
item.setText("数据xx")

也可以在初始化时给定

item = QTableWidgetItem("数据xx")

其它的一些可选的单元格属性:

设定单元格的图标:

item.setIcon(QIcon(":ICON/ICON/next.png"))#设置Item的图标

设定单元格的背景色:

item.setBackground(QColor(rgb[0],rgb[1],rgb[2])) # 或用常见的颜色QColor("red")

设定单元格的字体:

item.setFont()

设定单元格的文本的对齐:

item.setTextAlignment(Qt.AlignHCenter |Qt.AlignVCenter)

设定单元格的前景色(字体颜色):

item.setForeground(QColor("red"))

指定单元格的item:

table.setItem(1, 2, item1)#第1行,第2列,为item1

甚至可以指定单元格以控件显示:

table.setCellWidget (0,2, QSpinBox())
table.setCellWidget (1,2, QCheckBox("知否知否"))

表格的各种信号(以C++描述,PyQt中为同名信号):

完整的示例代码如下:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QColor, QFont, QIcon,QPixmap
from PyQt5.QtCore import Qt, QSize
import random
import resource
#self.setTextAlignment(Qt.AlignHCenter |  Qt.AlignVCenter)
def x2RGB(x, min_ =0, max_=1): #浮点数到RGB颜色的一种映射
    r=(x-min_)/(max_-min_)
    if r>=0.75:
        return (255,int(255*(1-r)*4),0)
    elif r>=0.5:
        return (int(255*(r-0.5)*4),255,0)
    elif r>=0.25:
        return (0,255,int(255*(0.5-r)*4))
    elif r>=0:
        return (0,int(255*r*4),255)
    #else:
        #return(255,255,255)# white
    
class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.setWindowTitle("表格控件示例")
        self.create_table()
        self.create_map()
        self.setup_centralWidget()
        self.statusBar().showMessage("ready")
        #self.setWindowIcon(QIcon(":ICON/ICON/retest.png"))
        self.resize(500,500)
    def create_table(self):
        self.table = QTableWidget()
        #self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        #SelectedClicked #AllEditTriggers
        self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        
        HorizontalHeaderLabels = ["Input",
                                  "Good\nQty.","Yield","SpecFail\nQty.", "SpecFail\n%",
                                  "TotalFail\nQty.", "TotalFail\n%","单元格控件"]#\n换行
        columns = len(HorizontalHeaderLabels)
        self.table.setRowCount(3)
        self.table.setColumnCount(columns)
        self.table.setHorizontalHeaderLabels(HorizontalHeaderLabels)
        self.table.setVerticalHeaderLabels(["显示文本颜色","显示图标","空空如也"])
        headItem = self.table.horizontalHeaderItem(2)
        headItem.setIcon(QIcon(":ICON/ICON/retest.png"))#设置headItem的图标
        self.headerWidth = (40,40,50,52,54,52,54,70)
        
        #.setSortingEnabled (self, bool enable)
        
        for i in range(columns-1):
            self.table.setColumnWidth (i,self.headerWidth[i])
            item = QTableWidgetItem("示例数据%d" % i)
            item.setTextAlignment(Qt.AlignHCenter |Qt.AlignVCenter)#设置文本的对齐
            # 设置QTableWidgetItem 的前景色(字体颜色)
            item.setForeground(QColor("red"))
            self.table.setItem(0,i, item)
            item1 = QTableWidgetItem()
            item1.setIcon(QIcon(":ICON/ICON/next.png"))#设置Item的图标
            self.table.setItem(1,i, item1)
        
        #setCellWidget (self, int row, int column, QWidget widget)
        self.table.setCellWidget (0,columns-1, QSpinBox())
        self.table.setCellWidget (1,columns-1, QCheckBox("知否知否"))
        cb =QComboBox()
        cb.addItems(["绿肥","红瘦"])
        self.table.setCellWidget (2,columns-1, cb)
    def create_map(self):
        self.map = QTableWidget()
        rows, cols = 10,10
        self.map.setRowCount(rows)
        self.map.setColumnCount(cols)
        #self.map.verticalHeader().hide() # 隐藏表头
        #self.map.horizontalHeader().setDisabled(True) #不让用户改列宽
        #设置表格为自适应的伸缩模式,即可根据窗口的大小来改变网格的大小
        self.map.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.map.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
        #self.map.verticalHeader().setDisabled(True) #不让用户改行高
        self.map.setEditTriggers(QAbstractItemView.NoEditTriggers)#禁止修改内容
        
        self.map.cellClicked[int,int].connect(self.map_cellClicked)#连接单元格点击信号和槽
        for i in range(rows):
            for j in range(cols):
                x = random.random()
                rgb = x2RGB(x)
                item = QTableWidgetItem()
                item.setBackground(QColor(rgb[0],rgb[1],rgb[2]))
                self.map.setItem(i,j,item)
    def map_cellClicked(self,i,j):
        #item = self.map.item(i,j) 或
        item = self.map.currentItem()
        bgColor =item.background().color()
        r,g,b = bgColor.red(), bgColor.green(), bgColor.blue(), 
        self.statusBar().showMessage("行:%d, 列:%d  RGB:(%d,%d,%d)"
                                     % (i+1, j+1, r,g,b),1000) #状态栏在3000ms内显示信息
            
    def setup_centralWidget(self):
        #设置主窗口中心部件
        self.tabWidget = QTabWidget()
        self.tabWidget.addTab(self.table,"Table ")
        self.tabWidget.addTab(self.map," Map   ")
        self.setCentralWidget(self.tabWidget)#指定主窗口中心部件 
    def clean(self):
        self.table.clearContents()#清除内容
        self.map.clear()#清除内容和格式
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

原文发布于微信公众号 - Python编程 pyqt matplotlib(wsplovePython)

原文发表时间:2019-04-05

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

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券