目录
一.显示二维表数据
二.显示列数据
三.扩展的列表控件
四.扩展的表格控件
五.在单元格中放置控件
六.在表格中搜索Cell和行定位
七.设置单元格字体和颜色
八.按表格的某一列排序
从本讲开始学习复杂控件。加油!
显示二维表数据(QTableVi ew控件)
数据源 Model
需要创建QTableView实例和一个数据源(Model) ,然后将两者关联,这个体系类似于MVC模式。
一个QTableView实例可以存放不同的数据源,一个数据源也可以对应不同的QTableView实例。
MVC: Model Viewer Controller 即将数据Model和前端视图Viewer分离,通过控制器Controller 来控制。
MVC的目的是将后端的数据和前端页面的耦合度降低。
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class TableView(QWidget):
def __init__(self):
super(TableView, self).__init__()
self.setWindowTitle('QTableView表格视图控件演示')
self.resize(500,300)
self.model=QStandardItemModel(4,3)#二维表4行3列
#数据表的字段
self.model.setHorizontalHeaderLabels(['id','name','age'])
self.tableView=QTableView()
#关联QTableView控件和Model
self.tableView.setModel(self.model)
#添加数据
item11=QStandardItem('1') #一个QStandardItem就是一个单元格
item12 = QStandardItem('Kobe')
item13 = QStandardItem('24')
self.model.setItem(0,0,item11)
self.model.setItem(0, 1, item12)
self.model.setItem(0, 2, item13)
#可跳行添加数据
item31 = QStandardItem('7')
item32 = QStandardItem('Durant')
item33 = QStandardItem('35')
self.model.setItem(2, 0, item31)
self.model.setItem(2, 1, item32)
self.model.setItem(2, 2, item33)
#垂直布局
layout=QVBoxLayout()
layout.addWidget(self.tableView)
self.setLayout(layout)
if __name__=='__main__':
app=QApplication(sys.argv)
main=TableView()
main.show()
sys.exit(app.exec_())
运行结果:
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QStringListModel
class ListView(QWidget):
def __init__(self):
super(ListView, self).__init__()
self.setWindowTitle('ListView例子')
self.resize(300,270)
layout=QVBoxLayout()
listView=QListView()
#数据源
listModel=QStringListModel()
self.list=['列表项1','列表项2','列表项3']
listModel.setStringList(self.list)
#关联视图与数据源
listView.setModel(listModel)
listView.clicked.connect(self.clicked)
layout.addWidget(listView)
self.setLayout(layout)
def clicked(self,item):
QMessageBox.information(self,'QListView','您选择了:'+self.list[item.row()])
if __name__=='__main__':
app=QApplication(sys.argv)
main=ListView()
main.show()
sys.exit(app.exec_())
运行结果:
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QStringListModel
'''
QListWidget是QListView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''
class ListWidget(QMainWindow):
def __init__(self):
super(ListWidget, self).__init__()
self.setWindowTitle('ListWidget例子')
self.resize(300,270)
#直接添加的方式适合少量的数据的时候
self.listWidget=QListWidget()
#self.listWidget.resize(300,120)
self.listWidget.addItem('item1')
self.listWidget.addItem('item2')
self.listWidget.addItem('item3')
self.listWidget.addItem('item4')
self.listWidget.addItem('item5')
self.listWidget.itemClicked.connect(self.clicked)
#设置中心控件之后,会铺满整个屏幕,无需再单独设置listWidget尺寸
self.setCentralWidget(self.listWidget)
def clicked(self,index):
QMessageBox.information(self,'ListWidget','您选择了:'+self.listWidget.item(self.listWidget.row(index)).text())
if __name__=='__main__':
app=QApplication(sys.argv)
main=ListWidget()
main.show()
sys.exit(app.exec_())
运行结果:
每一个Cell (单元格) 是一个QTableWidgetItem
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
'''
QTableWidget是QTableView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''
class TableWidget(QWidget):
def __init__(self):
super(TableWidget, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QTableWidget演示')
self.resize(430, 230)
layout = QHBoxLayout()
tablewidget = QTableWidget()
# 4行3列
tablewidget.setRowCount(4)
tablewidget.setColumnCount(3)
tablewidget.setHorizontalHeaderLabels(['name','age','address'])
nameItem=QTableWidgetItem('小明')
tablewidget.setItem(0,0,nameItem)
ageItem = QTableWidgetItem('24')
tablewidget.setItem(0, 1, ageItem)
addressItem = QTableWidgetItem('北京')
tablewidget.setItem(0, 2, addressItem)
#禁止编辑
tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
#整行选择
tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)
#调整列和行
tablewidget.resizeColumnsToContents()
tablewidget.resizeRowsToContents()
#隐藏表格头
tablewidget.horizontalHeader().setVisible(False) #隐藏水平方向的表格头
#tablewidget.verticalHeader().setVisible(False) #隐藏垂直方向的表格头
#设置表格头内容
tablewidget.setVerticalHeaderLabels(['a','b']) #垂直方向表格头前两个设为a,b
#隐藏表格线
tablewidget.setShowGrid(False)
layout.addWidget(tablewidget)
self.setLayout(layout)
if __name__=='__main__':
app=QApplication(sys.argv)
main=TableWidget()
main.show()
sys.exit(app.exec_())
运行结果:
在单元格中放置控件
setItem:将文本放到单元格中
setCellWidget:将控件放到单元格中
setStyleSheet设置控件的样式(QSS)
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
'''
QTableWidget是QTableView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''
class TableWidget(QWidget):
def __init__(self):
super(TableWidget, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('在单元格中放置控件')
self.resize(430, 300)
layout = QHBoxLayout()
tableWidget = QTableWidget()
# 4行3列
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
tableWidget.setHorizontalHeaderLabels(['name','age','weigh(kg)'])
textItem=QTableWidgetItem('小明')
#setItem:将文本放到单元格中
tableWidget.setItem(0,0,textItem)
#下拉框
combox=QComboBox()
combox.addItem('男')
combox.addItem('女')
#setStyleSheet设置控件的样式(QSS)(类似于web中的CSS),即Qt StyleSheet(n.样式表)
combox.setStyleSheet('QComboBox{margin:3px};')#设置控键距离上下左右的单元格的距离(距离)
#setCellWidget:将控件放到单元格中
tableWidget.setCellWidget(0,1,combox)
modifyButton=QPushButton('修改')
#默认是按下的状态
modifyButton.setDown(True)
modifyButton.setStyleSheet('QPushButton{margin:3px};')
tableWidget.setCellWidget(0,2,modifyButton)
layout.addWidget(tableWidget)
self.setLayout(layout)
if __name__=='__main__':
app=QApplication(sys.argv)
main=TableWidget()
main.show()
sys.exit(app.exec_())
运行结果:
在表格中快速定位到特定的行
1.数据的定位: findItems ,返回一个列表
2.如果找到了满足条件的单元格,会定位到单元格所在的行: setSliderPosition(row)
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class DataLocation(QWidget):
def __init__(self):
super(DataLocation, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('在表格中搜索Cell和行定位')
self.resize(600, 800)
layout = QHBoxLayout()
tableWidget=QTableWidget()
tableWidget.setRowCount(40)
tableWidget.setColumnCount(4)
for i in range(40):
for j in range(4):
itemContent='(%d,%d)'%(i,j)
tableWidget.setItem(i,j,QTableWidgetItem(itemContent))
self.setLayout(layout)
#搜索满足条件的Cell
text='(13,1)'
text1='(1,'
#参数一:要匹配的文本 ; 参数二:搜索模式,返回一个列表
#items=tableWidget.findItems(text,Qt.MatchExactly)#搜索模式设为精确匹配,必须一模一样才行
items = tableWidget.findItems(text1, Qt.MatchStartsWith)#搜索模式为匹配以...为开头的字符串,这里看text1,即以(1,开头的的字符串
length=len(items)
if length>0:
print('匹配项个数:',len(items))
for i in range(length):
item = items[i]
# 背景色
item.setBackground(QBrush(QColor(0, 255, 0))) # rgb
# 前景色,即文字的颜色
item.setForeground(QBrush(QColor(255, 0, 0)))
# 当前项所在的行
row = item.row()
# 定位到指定的行
tableWidget.verticalScrollBar().setSliderPosition(row)
layout.addWidget(tableWidget)
self.setLayout(layout)
if __name__=='__main__':
app=QApplication(sys.argv)
main=DataLocation()
main.show()
sys.exit(app.exec_())
运行结果:
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class CellFontAndColor(QWidget):
def __init__(self):
super(CellFontAndColor, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('设置单元格字体和颜色')
self.resize(430, 230)
layout = QHBoxLayout()
tableWidget=QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
tableWidget.setHorizontalHeaderLabels(['name','sex','weigh(kg)'])
newItem=QTableWidgetItem('小明')#单元格的数据项
newItem.setFont(QFont('Times',14,QFont.Black))#字体,字号,颜色
newItem.setForeground(QBrush(QColor(255,0,0)))
tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('女')
newItem.setForeground(QBrush(QColor(255, 255, 0)))
newItem.setBackground(QBrush(QColor(0,0,255)))#rgb
tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem('100')
newItem.setFont(QFont('Times', 20, QFont.Black))
newItem.setForeground(QBrush(QColor(0, 0, 255)))
tableWidget.setItem(0, 2, newItem)
layout.addWidget(tableWidget)
self.setLayout(layout)
if __name__=='__main__':
app=QApplication(sys.argv)
main=CellFontAndColor()
main.show()
sys.exit(app.exec_())
运行结果:
按列排序
1.按哪一列排序
2.排序类型:升序或降序
sortItems( columnIndex,orderType)
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class CellFontAndColor(QWidget):
def __init__(self):
super(CellFontAndColor, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('设置单元格字体和颜色')
self.resize(540, 230)
layout = QHBoxLayout()
self.tableWidget=QTableWidget()#表格对象
self.tableWidget.setRowCount(4)
self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(['name','sex','weigh(kg)'])
#添加数据
newItem=QTableWidgetItem('张三')
self.tableWidget.setItem(0,0,newItem)
newItem = QTableWidgetItem('男')
self.tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem('165')
self.tableWidget.setItem(0, 2, newItem)
newItem = QTableWidgetItem('李四')
self.tableWidget.setItem(1, 0, newItem)
newItem = QTableWidgetItem('女')
self.tableWidget.setItem(1, 1, newItem)
newItem = QTableWidgetItem('120')
self.tableWidget.setItem(1, 2, newItem)
newItem = QTableWidgetItem('王五')
self.tableWidget.setItem(2, 0, newItem)
newItem = QTableWidgetItem('男')
self.tableWidget.setItem(2, 1, newItem)
newItem = QTableWidgetItem('130')
self.tableWidget.setItem(2, 2, newItem)
#点击按钮排序
self.btn=QPushButton('升序')
self.btn.clicked.connect(self.order)
#常量
self.orderType=Qt.DescendingOrder
layout.addWidget(self.tableWidget)
layout.addWidget(self.btn)
self.setLayout(layout)
#升降序来回切换
def order(self):
if self.orderType == Qt.DescendingOrder:
self.orderType=Qt.AscendingOrder
self.btn.setText('降序')#重命名按钮名,setText设置按钮显示文本
else:
self.orderType = Qt.DescendingOrder
self.btn.setText('升序')
#print(Qt.DescendingOrder)
#print(self.orderType)
self.tableWidget.sortItems(2,self.orderType)#按照第三列的数据项排序
#self.tableWidget.sortItems(2, Qt.DescendingOrder)
if __name__=='__main__':
app=QApplication(sys.argv)
main=CellFontAndColor()
main.show()
sys.exit(app.exec_())
运行结果:
点击排序每次是升序和降序依次切换。