Pyqt5学习笔记七、PYQT5表格控件使用
七、PYQT5表格控件的使用
PyQt5提供了两种表格控件,分别是TableWidget和TableView,其中,TableView是基于模型的,它是TableWidget的父类,使用TableView时,首先需要建立模型,然后再保存数据;而TableWidget是TableView的升级版本,它已经内置了一个数据存储模型QTableWidgetItem,我们在使用时,不必自己建立模型,而直接使用setItem()方法即可添加数据。所以在实际开发时,推荐使用TableWidget控件作为表格。
QTableWidgetItem类表示QTableWidget中的单元格,一个表格就是由多个单元格组成的,QTableWidgetItem类的常用方法如表
1、在表格中显示数据库数据
使用TableWidget控件显示数据主要用到QTableWidgetItem类,使用该类创建表格中的单元格,并指定要显示的文本或者图标后,即可使用TableWidget对象的setItem()方法将其添加到表格中。
import sys
from PyQt5.QtWidgets import *
import pymysql
class demo(QTabWidget):
def __init__(self):
super(demo, self).__init__()
self.setupUi()
def setupUi(self):
self.setWindowTitle("使用表格显示数据库中数据")
self.resize(1240,380)
vhayout=QHBoxLayout() #S水平布局
#连接数据库
conn=pymysql.connect("localhost","ziyuan","841109","ziyuan")
cursor=conn.cursor()
sql="select * from `ziyuan`;"
cursor.execute(sql)
res=cursor.fetchall()
row=cursor.rowcount #在游标中获取行数
vol=len(res[0]) #通过第一个结果数量确定列数
cursor.close()
conn.close()
# 创建表格 并开始设置
table = QTableWidget() #创建
table.setRowCount(row) #设置行数
table.setColumnCount(vol) #设置列数
table.setHorizontalHeaderLabels(['id','单元','分类','标题','类型','描述','路径','作者'])
#循环写入数据 使用setitem
for i in range(row):
for j in range(vol):
data=QTableWidgetItem(str(res[i][j]))
table.setItem(i,j,data)
#这几项设置设置在数据写入之前无效。以后要都要写在数据写入之后
table.resizeColumnsToContents() #列宽跟随内容变化
table.resizeRowsToContents() #行高跟随内容变化而变化
table.setAlternatingRowColors(True) #表格颜色交错显示
vhayout.addWidget(table) #使表格添加到水平布局中
self.setLayout(vhayout)
if __name__=='__main__':
app=QApplication(sys.argv)
win=demo()
win.show()
sys.exit(app.exec_())
2、隐藏标题
表格在显示数据时,默认会以编号的形式自动形成一列垂直标题,如果需要隐藏,可以使用verticalHeader()获取垂直标题,然后使用setVisible()方法将其隐藏。
table.verticalHeader().setVisible(False) # 隐藏垂直标题
增加在数据之后
table.horizontalHeader().setVisible(False) #隐藏水平标题 也是添加在数据之后较为安全
3、设置最后一列自动填充容器
表格中的列默认会以默认宽度显示,但如果遇到窗口伸缩的情况,在放大窗口时,由于表格是固定的,就会造成窗口中可能会出现大面积的空白区域,影响整体的美观。在PyQt5中可以使用setstret-chlastSection( )方法将表格的最后一列设置为自动伸缩列,这样就可以自动填充整个容器。
table.horizontalHeader().setStretchLastSection(True) # 设置最后一列自动填充容器
#上面的代码将最后一列设置为了自动伸缩列,除此之外,还可以将整个表格设置为自动伸缩模式,这样,在放大或者缩小窗口时,整个表格的所有列都会按比例自动缩放。代码如下:
table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
最后一列自动伸缩
所有表格按比例自动伸缩。综合看 最后一列自动伸缩实用性更强。
4、禁止编辑单元格
当双击表格中的某个单元格时,表格中的数据在默认情况下是可以编辑的,但如果只需要查看数据,则可以使用表格对象的setEditTriggers()方法将表格的单元格设置为禁止编辑状态。
table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) # 禁止编辑单元格
5、设置单元格的文本颜色
使用QTableWidgetItem对象的setForeground()方法可以设置单元格内文本的颜色,其参数为一个QBrush对象,在该对象中可以使用颜色名或者RGB值来对颜色进行设置。
data.setForeground(QtGui.QBrush(QtGui.QColor("green"))) # 设置单元格文本颜色
运行效果如下:
如果需要设置单元格的背景颜色,可以使用setBackground()方法,例如,将单元格背景设置为黄色,代码如下:
data.setBackground(QtGui.QBrush(QtGui.QColor("yellow"))) # 设置单元格背景颜色
运行效果如下
6、设置指定列的排序方式
使用QTableWidget对象的sortItems()方法,可以设置表格中指定列的排序方式。代码同样放在数据之后
sortItems(column, order)
#column:一个整数数字,表示要进行排序的列索引。
#order:一个枚举值,指定排序方式,其中,Qt.DescendingOrder表示降序,Qt.AscendingOrder表示升序。
7、在指定列中显示图片
表格除了可以显示文字,还可以显示图片,显示图片可以在创建QTableWidgetItem对象时传入QIcon图标对象实现。
for j in range(vol):
if j==4:
data=QTableWidgetItem(QtGui.QIcon('haokan.ico'),str(res[i][j])) #这里在第四列加入图片
else:
data=QTableWidgetItem(str(res[i][j]))
8、向指定列中添加PyQt5标准控件
TableWidget表格不仅可以显示文字、图片,还可以显示PyQt5的标准控件,实现该功能需要使用setCellWidget()方法。
setCellWidget(row, column, QWidget)
#row:一个整数数字,表示要添加控件的单元格的行索引。
#column:一个整数数字,表示要添加控件的单元格的列索引。
#QWidget:PyQt5标准控件
9、合并单元格
在实际项目开发中,经常遇到合并单元格的情况。在PyQt5中合并表格的单元格,需要使用setSpan()方法。
setSpan(row, column, rowSpanCount,columnSpanCount)
#row:一个整数数字,表示要改变的单元格的行索引。
#column:一个整数数字,表示要改变的单元格的列索引。
#rowSpanCount:一个整数数字,表示需要合并的行数。
#columnSpanCount:一个整数数字,表示需要合并的列数。
比方把第八列合并
运行效果
10、获取单元格信息
pyqt中的QTableWigget获取点击单元格的内容,行,列。获取这些信息后可以对数据进行更高级别的操作。比如增删改查。
#信号
table.itemClicked.connect(self.showdata)
def showdata(self,item=None):
if item is None:
return
else:
row=item.row()
col=item.column()
text=item.text()
QMessageBox.information(self,"数据",f"行:{row};列;{col}内容{text}")
11、单元格右键菜单
信号:
self.table.setContextMenuPolicy(Qt.CustomContextMenu) # 右键菜单,如果不设为CustomContextMenu,无法使用customContextMenuRequested
self.table.customContextMenuRequested.connect(self.showContextMenu)
右键菜单函数:
def showContextMenu(self): # 创建右键菜单
self.table.contextMenu = QMenu(self)
self.actionA = self.table.contextMenu.addAction(u'动作a')
# self.actionA = self.view.contextMenu.exec_(self.mapToGlobal(pos)) # 1
self.table.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
self.actionA.triggered.connect(self.actionHandler) #菜单点击发射信号
# self.view.contextMenu.move(self.pos()) # 3
self.table.contextMenu.show() #显示菜单
def actionHandler(self):
print('yes') #菜单 动作a执行的动作函数
12、删除数据
self.table.removeRow(4) #移除第5行
self.table.removeColumn(7) #移除第8列
self.table.removeCellWidget(1,2) #移除第二行第三列的控件
运行效果:
如果要移除数据库中数据,还要配合数据库cursor.excute(SQL) SQL为删除语句
删除所有数据
self.tableWidget.setRowCount(0) #设置0行
self.tableWidget.clearContents() #清空所有内容
13、信号
QTableWidget非继承自父类的信号如下
cellActivated(int row, int column):对应项获得了焦点时发射本信号
cellChanged(int row, int column):对应项的各种角色数据发生了变化时发射本信号
cellClicked(int row, int column):对应项鼠标点击时发射本信号
cellDoubleClicked(int row, int column):对应项鼠标双击时发射本信号
cellEntered(int row, int column):鼠标光标进入到对应项范围内时发射本信号
cellPressed(int row, int column):鼠标在对应项范围内按下时发射本信号
currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn):当前项发生切换时触发
currentItemChanged(QTableWidgetItem current, QTableWidgetItem previous):当前项发生切换时触发
itemActivated(QTableWidgetItem item):项获得了焦点时触发
itemChanged(QTableWidgetItem item):对应项的各种角色数据发生了变化时发射本信号
itemClicked(QTableWidgetItem item):对应项鼠标点击时发射本信号
itemDoubleClicked(QTableWidgetItem item):对应项鼠标双击时发射本信号
itemEntered(QTableWidgetItem item):鼠标光标进入到对应项范围内时发射本信号
itemPressed(QTableWidgetItem item):鼠标在对应项范围内按下时发射本信号
itemSelectionChanged():当选中的项发生变化时发射本信号,选中的项通过selectedItems() 方法获取
以上信号很多都是同样的条件触发,只是信号签名不同,具体看应用需要的数据来确认选择哪个信号来处理。
本章节案例完整代码
import sys
from PyQt5 import QtWidgets,QtGui,QtCore
from PyQt5.QtGui import QCursor
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import pymysql
class demo(QTabWidget):
def __init__(self):
super(demo, self).__init__()
self.setupUi()
def setupUi(self):
self.setWindowTitle("使用表格显示数据库中数据")
self.resize(1240,380)
vhayout=QHBoxLayout() #S水平布局
#连接数据库
conn=pymysql.connect("localhost","ziyuan","841109","ziyuan")
cursor=conn.cursor()
sql="select * from `ziyuan`;"
cursor.execute(sql)
res=cursor.fetchall()
row=cursor.rowcount #在游标中获取行数
vol=len(res[0]) #通过第一个结果数量确定列数
cursor.close()
conn.close()
# 创建表格 并开始设置
self.table = QTableWidget() #创建
self.table.setRowCount(row) #设置行数
self.table.setColumnCount(vol) #设置列数
self.table.setHorizontalHeaderLabels(['id','单元','分类','标题','类型','描述','路径','作者'])
#循环写入数据 使用setitem
for i in range(row):
for j in range(vol):
if j==4:
data=QTableWidgetItem(QtGui.QIcon('haokan.ico'),str(res[i][j]))
elif j==2:
comobox=QComboBox() #定义一个选择框
comobox.addItems(['1','2','3','4','5','6'])
comobox.setCurrentIndex(res[i][j]-1) #默认选择数据库数字,因为索引从0开始 所以减1
self.table.setCellWidget(i,2,comobox) #设置控件
else:
data=QTableWidgetItem(str(res[i][j]))
data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))
self.table.setItem(i,j,data)
# 这几项设置设置在数据写入之前无效。以后要都要写在数据写入之后x
self.table.sortItems(4,QtCore.Qt.DescendingOrder) #设置第五列降序
self.table.setSpan(0,8,row,1) #将第八列合并
self.table.setSpan(0,9,row,1) #将第九列合并
self.table.resizeColumnsToContents() #列宽跟随内容变化
self.table.resizeRowsToContents() #行高跟随内容变化而变化
self.table.setAlternatingRowColors(True) #表格颜色交错显示
self.table.verticalHeader().setVisible(False) #隐藏垂直标题
self.table.horizontalHeader().setVisible(False) #隐藏水平标题
self.table.horizontalHeader().setStretchLastSection(True) #设置最后一列自动伸缩
# table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) #所有项目 按比例自动伸缩
self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) #禁止编辑单元格
vhayout.addWidget(self.table) #使表格添加到水平布局中
self.setLayout(vhayout)
#信号
self.table.itemClicked.connect(self.showdata)
self.table.setContextMenuPolicy(Qt.CustomContextMenu) # 右键菜单,如果不设为CustomContextMenu,无法使用customContextMenuRequested
self.table.customContextMenuRequested.connect(self.showContextMenu)
self.table.removeRow(4)
self.table.removeColumn(7)
self.table.removeCellWidget(1,2)
self.table.cell
def showdata(self,item=None):
if item is None:
return
else:
row=item.row()
col=item.column()
text=item.text()
QMessageBox.information(self,"数据",f"行:{row};列;{col}内容{text}")
def showContextMenu(self): # 创建右键菜单
self.table.contextMenu = QMenu(self)
self.actionA = self.table.contextMenu.addAction(u'动作a')
# self.actionA = self.view.contextMenu.exec_(self.mapToGlobal(pos)) # 1
self.table.contextMenu.popup(QCursor.pos()) # 2菜单显示的位置
self.actionA.triggered.connect(self.actionHandler)
# self.view.contextMenu.move(self.pos()) # 3
self.table.contextMenu.show()
def actionHandler(self):
print('yes')
if __name__=='__main__':
app=QApplication(sys.argv)
win=demo()
win.show()
sys.exit(app.exec_())
其他未尽知识点其他文章在补充。
评论列表
发表评论