表格和树的作用就是在一个控件中有规律得呈现更多的数据,因此 PyQt5 提供了表格结构和树形结构的控件类。
1、QTableView
QTableView 用于将数据(数组、列表)以表格的形式呈现在界面中;QTableView 类中可以使用自定义数据模型来显示内容,通过 setModel 绑定数据源。
QTableWidget 继承自 QTableView,区别在于 QTableView 可以使用自定义数据模型来显示内容,而 QTableWidget 只能使用标准的数据模型,并且单元格数据是人通过 QTableWidgetItem 对象来实现的。
QTable 控件可以绑定一个模型数据来更新控件上的内容,可用的模式如下表:
名称 含义
QStringListModel :存储一组字符串
QStandardItemModel :存储任意层次结构的数据
QDirModel :对文件系统进行封装
QSqlQueryModel ;对 SQL 的查询结果集进行封装
QSqlTableModel :对 SQL 中的表格进行封装
QSqlRelationTableModel :对带有 foreign key 的 SQL 表格进行封装
QSortFilterProxyModel :对模型中的数据进行排序或过滤
rom PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Table(QWidget):
def __init__(self, arg=None):
super(Table, self).__init__(arg)
self.setWindowTitle("QTableView表格视图控件的例子")
self.resize(500,300);
self.model=QStandardItemModel(4,4);
self.model.setHorizontalHeaderLabels(['标题1','标题2','标题3','标题4'])
#添加数据
for row in range(4):
for column in range(4):
item = QStandardItem("row %s, column %s"%(row,column))
self.model.setItem(row, column, item)
self.tableView=QTableView()
self.tableView.setModel(self.model)
#下面代码让表格100填满窗口
#self.tableView.horizontalHeader().setStretchLastSection(True)
#self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
dlgLayout=QVBoxLayout();
dlgLayout.addWidget(self.tableView)
self.setLayout(dlgLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
table = Table()
table.show()
sys.exit(app.exec_())
删除当前选中的数据,有下面两种方法:
indexs = self.tableView.selectionModel().selection().indexes()
if len(indexs)>0:
index = indexs[0]
self.model.removeRows(index.row(), 1)
index = self.tableView.currentIndex()
self.model.removeRow(index.row())
2、QListView
QListView 类用于展示数据,子类是 QListWidget。 QListView 是基于模型的。
QListWidget 是 QListView 的升级版,此类已经建立了数据存储模型(QListWidgetItem),直接调用 addItem() 函数添加条目。
QListView 常用方法如下表
方法 | 描述 |
---|---|
setModel() | 用来设置 View 所关联的 Model,可以使用 Python 原生的 list 作为数据源 Model |
selectedItem() | 选中 Model 中的条目 |
isSelected() | 判断 Model 中的条目是否被选中 |
常用信号
信号 | 描述 |
---|---|
clicked | 当单击某项时,触发该信号 |
doubleClicked | 当双击某项时,触发该信号 |
from PyQt5.QtWidgets import QApplication, QWidget , QVBoxLayout , QListView, QMessageBox
from PyQt5.QtCore import QStringListModel
import sys
class ListViewDemo(QWidget):
def __init__(self, parent=None):
super(ListViewDemo, self).__init__(parent)
self.setWindowTitle("QListView 例子")
self.resize(300, 270)
layout = QVBoxLayout()
listView = QListView()
slm = QStringListModel();#字符list
self.qList = ['Item 1','Item 2','Item 3','Item 4' ]
slm.setStringList(self.qList)
listView.setModel(slm )
listView.clicked.connect(self.clicked)
layout.addWidget( listView )
self.setLayout(layout)
def clicked(self, qModelIndex):
QMessageBox.information(self, "QListView", "你选择了: "+ self.qList[qModelIndex.row()])
if __name__ == "__main__":
app = QApplication(sys.argv)
win = ListViewDemo()
win.show()
sys.exit(app.exec_())
3、QListWidget
常用方法
方法 | 描述 |
---|---|
addItem() | 在列表中添加QListWidgetItem对象或字符串 |
addItems() | 添加列表中的每个条目 |
insertItem() | 在指定地索引处插入条目 |
clear() | 删除列表的内容 |
setCurrentItem() | 设置当前所选的条目 |
sortItems() | 按升序重新排列条目 |
常用信号
方法 | 描述 |
---|---|
currentItemChanged | 当列表中的条目发生改变时发射此信号 |
itemClicked | 当点击列表中的条目时发射此信号 |
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ListWidget(QListWidget):
def clicked(self,item):
QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
listWidget = ListWidget()
c=['item5','item6']
listWidget.resize(300,120)
listWidget.addItem("Item 1");
listWidget.addItem("Item 2");
listWidget.addItem("Item 3");
listWidget.addItem("Item 4");
listWidget.addItems(c)
listWidget.setWindowTitle('QListwidget 例子')
listWidget.itemClicked.connect(listWidget.clicked)
listWidget.show()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView )
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(430,230);
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
conLayout.addWidget(tableWidget )
tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])
newItem = QTableWidgetItem("张三")
tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男")
tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("160")
tableWidget.setItem(0, 2, newItem)
# 将表格变为禁止编辑
#tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 设置表格为整行选择
#tableWidget.setSelectionBehavior( QAbstractItemView.SelectRows)
# 将行和列的大小设为与内容相匹配
#tableWidget.resizeColumnsToContents()
#tableWidget.resizeRowsToContents()
#表格表头的显示与隐藏
#tableWidget.verticalHeader().setVisible(False)
#tableWidget.horizontalHeader().setVisible(False)
# 不显示表格单元格的分割线
#tableWidget.setShowGrid(False)
# 不显示垂直表头
tableWidget.verticalHeader().setVisible(False)
self.setLayout(conLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = Table()
example.show()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication , QTableWidgetItem, QHeaderView)
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget demo")
self.resize(500,300);
conLayout = QHBoxLayout()
tableWidget= QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
conLayout.addWidget(tableWidget )
tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])
#tableWidget.setVerticalHeaderLabels(['行1','行2','行3','行4' ])
tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
newItem = QTableWidgetItem("张三")
tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男")
tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("160")
tableWidget.setItem(0, 2, newItem)
self.setLayout(conLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = Table()
example.show()
sys.exit(app.exec_())
# -*- coding: utf-8 -*-
'''
【简介】
PyQT5中 单元格里面放控件
'''
import sys
from PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView ,QComboBox, QPushButton )
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(430,300);
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(4)
tableWidget.setColumnCount(3)
conLayout.addWidget(tableWidget )
tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])
newItem = QTableWidgetItem("张三")
tableWidget.setItem(0, 0, newItem)
comBox = QComboBox()
comBox.addItem("男")
comBox.addItem("女")
comBox.setStyleSheet("QComboBox{margin:3px};")
tableWidget.setCellWidget(0,1,comBox)
searchBtn = QPushButton("修改")
searchBtn.setDown( True )
searchBtn.setStyleSheet("QPushButton{margin:3px};")
tableWidget.setCellWidget(0, 2, searchBtn)
self.setLayout(conLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = Table()
example.show()
sys.exit(app.exec_())
# -*- coding: utf-8 -*-
'''
【简介】
PyQT5的表格控件选中单元格
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
from PyQt5.QtGui import QColor , QBrush
class Table(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QTableWidget 例子")
self.resize(600,800);
conLayout = QHBoxLayout()
tableWidget = QTableWidget()
tableWidget.setRowCount(30)
tableWidget.setColumnCount(4)
conLayout.addWidget(tableWidget )
for i in range(30):
for j in range(4):
itemContent = '(%d,%d)'% (i,j)
tableWidget.setItem(i,j, QTableWidgetItem( itemContent ) )
self.setLayout(conLayout)
#遍历表查找对应的item
text = "(10,1)"
items = tableWidget.findItems(text, QtCore.Qt.MatchExactly)
item = items[0]
# 选中单元格
#item.setSelected( True)
# 设置单元格的背景颜色为红色
item.setForeground(QBrush(QColor(255, 0, 0)))
row = item.row()
#滚轮定位过去,快速定位到第17行
tableWidget.verticalScrollBar().setSliderPosition(row)
if __name__ == '__main__':
app = QApplication(sys.argv)
example = Table()
example.show()
sys.exit(app.exec_())
QTreeWidget常用方法
方法 | 描述 |
---|---|
setColumnWidth(int column,int width) | 将指定列的宽度设置为给定的值 |
insertTopLevelItems() | 在视图的顶层索引中引入项目的列表 |
expandAll() | 展开所有节点的树形节点 |
invisibleRootItem() | 返回树形控件中不可见的根选项(Root Item) |
selectionItems() | 返回所有选定的非隐藏项目的列表内 |
QTreeWidgetItem类中常用的方法
方法 | 描述 |
---|---|
addChild() | 将子项追加到子列表中 |
setText() | 设置显示的节点文本 |
Text() | 返回显示的节点文本 |
setCheckState(column.state) | 设置指定列的选中状态: |
- | Qt.Checked:节点选中 |
- | Qt.Unchecked:节点没有选中 |
setIcon(column,icon) | 在指定的列中显示图标 |
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QBrush, QColor
from PyQt5.QtCore import Qt
class TreeWidgetDemo(QMainWindow):
def __init__(self, parent=None):
super(TreeWidgetDemo, self).__init__(parent)
self.setWindowTitle('TreeWidget 例子')
self.tree = QTreeWidget()
# 设置列数
self.tree.setColumnCount(2)
# 设置头的标题
self.tree.setHeaderLabels(['Key', 'Value'])
# 设置根节点
root = QTreeWidgetItem(self.tree)
root.setText(0, 'root')
root.setIcon(0, QIcon("./images/root.png"))
# 设置列宽
self.tree.setColumnWidth(0, 160)
### 设置节点的背景颜色
# brush_red = QBrush(Qt.red)
# root.setBackground(0, brush_red)
# brush_green = QBrush(Qt.green)
# root.setBackground(1, brush_green)
# 设置子节点1
child1 = QTreeWidgetItem(root)
child1.setText(0, 'child1')
child1.setText(1, 'ios')
child1.setIcon(0, QIcon("./images/IOS.png"))
child1.setCheckState(0, Qt.Checked)
# 设置子节点2
child2 = QTreeWidgetItem(root)
child2.setText(0, 'child2')
child2.setText(1, '')
child2.setIcon(0, QIcon("./images/android.png"))
# 设置子节点3
child3 = QTreeWidgetItem(child2)
child3.setText(0, 'child3')
child3.setText(1, 'android')
child3.setIcon(0, QIcon("./images/music.png"))
self.tree.addTopLevelItem(root)
# 结点全部展开
self.tree.expandAll()
self.setCentralWidget(self.tree)
if __name__ == '__main__':
app = QApplication(sys.argv)
tree = TreeWidgetDemo()
tree.show()
sys.exit(app.exec_())
节点绑定方法
child2 = QTreeWidgetItem(root)
括号里有root
优化一:设置节点的状态
这里添加了child1的选中状态
child1.setCheckState(0,Qt.Checked)
优化二:设置节点的背景颜色
这里设置了根节点的背景颜色
brush_red=QBrush(Qt.red)
root.setBackground(0,brush_red)
brush_blue=QBrush(Qt.blue)
root.setBackground(1,brush_blue)
优化3 :添加响应事件
self.tree.clicked.connect( self.onTreeClicked )
def onTreeClicked(self, qmodelindex):
item = self.tree.currentItem()
print("key=%s ,value=%s" % (item.text(0), item.text(1)))