文章目录- 1. 表格与树
- 1.1 QTableView
- 1.2 QListView
- 1.3 QListWidget
- 1.4 QTableWidget
- 表根据界面宽度自动伸缩
- 禁止编辑
- 单击某单元,使之默认选中整行
- 设置宽高度与内容相匹配
- 是否显示表头
- 单元格中放置`控件`
- 输入行号,快速定位行
- 设置颜色
- 加粗字体
- 排序
- 文本对齐
- 合并单元格
- 设置单元格大小
- 显示网格线
- 设置图片、更改图片大小
- 获取单元格内容
- 右键菜单
- 1.5 QTreeView
- 点击事件
- 系统定制模式
- 2. 容器:装载更多控件
- QTabWidget
- QStackedWidget
- QDockWidget
- 多文档界面 QMdiArea
- QScrollBar
- 1.1 QTableView
- 1.2 QListView
- 1.3 QListWidget
- 1.4 QTableWidget
- 表根据界面宽度自动伸缩
- 禁止编辑
- 单击某单元,使之默认选中整行
- 设置宽高度与内容相匹配
- 是否显示表头
- 单元格中放置`控件`
- 输入行号,快速定位行
- 设置颜色
- 加粗字体
- 排序
- 文本对齐
- 合并单元格
- 设置单元格大小
- 显示网格线
- 设置图片、更改图片大小
- 获取单元格内容
- 右键菜单
- 1.5 QTreeView
- 点击事件
- 系统定制模式
- QTabWidget
- QStackedWidget
- QDockWidget
- 多文档界面 QMdiArea
- QScrollBar
learn from 《PyQt5 快速开发与实战》 https://doc.qt.io/qtforpython/index.html https://www.riverbankcomputing.com/static/Docs/PyQt5
1. 表格与树
1.1 QTableView
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/9 9:44
# @Author : Michael
# @File : tableview1.py
# @desc :
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget, QTableView, QVBoxLayout, QApplication, QHeaderView
class table_view(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("table_view")
self.resize(500, 300)
self.model = QStandardItemModel()
self.model.setHorizontalHeaderLabels(["姓名", "年龄", "性别", "地址"])
for r in range(4):
for c in range(4):
item = QStandardItem("row %s, col %s" % (r, c))
self.model.setItem(r, c, item)
# 添加数据
self.model.appendRow([
QStandardItem("张三"), QStandardItem("20"),
])
self.model.appendRow([
QStandardItem('李四'), QStandardItem("21"),
])
self.tableview1 = QTableView()
self.tableview1.setModel(self.model)
self.tableview1.horizontalHeader().setStretchLastSection(True)
self.tableview1.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 表格填满窗口
# 删除数据
indexs = self.tableview1.selectionModel().selection().indexes()
print(indexs)
if len(indexs) > 0:
index = indexs[0]
self.model.removeRows(index.row(), 2) # 删除两行
index = self.tableview1.currentIndex()
print(index, index.row(), index.column())
self.model.removeRow(index.row() 1)
layout = QVBoxLayout()
layout.addWidget(self.tableview1)
self.setLayout(layout)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
win = table_view()
win.show()
sys.exit(app.exec_())
1.2 QListView
- 用于展示数据
# _*_ coding: utf-8 _*_
# @Time : 2022/5/9 21:08
# @Author : Michael
# @File : list_view1.py
# @desc :
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QListView, QMessageBox, QApplication
class listViewDemo(QWidget):
def __init__(self):
super(listViewDemo, self).__init__()
self.setWindowTitle("ListView例子")
self.resize(300, 300)
layout = QVBoxLayout()
listview = QListView()
str_list_model = QStringListModel()
self.qList = ['Item 1', 'Item 2', 'Item 3', 'Item 4']
str_list_model.setStringList(self.qList)
listview.setModel(str_list_model)
listview.clicked.connect(self.clicked)
layout.addWidget(listview)
self.setLayout(layout)
def clicked(self, qModelIndex):
QMessageBox.information(self, "title", "text:你选择了 " self.qList[qModelIndex.row()])
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
main = listViewDemo()
main.show()
sys.exit(app.exec_())
1.3 QListWidget
用于从列表中添加删除条目,升级版QListView,可以调用函数直接添加数据
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/9 21:20
# @Author : Michael
# @File : listWidgetDemo.py
# @desc :
from PyQt5.QtWidgets import QListWidget, QMessageBox, QApplication
class ListWidgetDemo(QListWidget):
def clicked(self, item):
QMessageBox.information(self, "ListWidget", "You clicked: " item.text())
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
listwidget = ListWidgetDemo()
listwidget.resize(300, 200)
listwidget.addItem("item 1")
listwidget.addItem("item 2")
listwidget.addItem("item 3")
listwidget.addItem("item 4")
listwidget.setWindowTitle("ListWidget Demo")
listwidget.itemClicked.connect(listwidget.clicked)
listwidget.show()
sys.exit(app.exec_())
1.4 QTableWidget
是 QTableView
的子类
# _*_ coding: utf-8 _*_
# @Time : 2022/5/9 21:39
# @Author : Michael
# @File : tablewidgetDemo.py
# @desc :
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QTableWidget, QTableWidgetItem, QApplication
class TableWidgetDemo(QWidget):
def __init__(self):
super(TableWidgetDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("TableWidget例子")
self.resize(500, 300)
layout = QHBoxLayout()
tablewidget = QTableWidget(4, 3) # 行,列
# tablewidget.setRowCount(4)
# tablewidget.setColumnCount(3)
layout.addWidget(tablewidget)
tablewidget.setHorizontalHeaderLabels(["姓名", "性别", "体重(kg)"])
tablewidget.setVerticalHeaderLabels(["1行", "2行", "3行", "4行哦"])
tablewidget.setItem(0, 0, QTableWidgetItem("张三"))
tablewidget.setItem(0, 1, QTableWidgetItem("男"))
tablewidget.setItem(0, 2, QTableWidgetItem("150"))
self.setLayout(layout)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = TableWidgetDemo()
main.show()
sys.exit(app.exec_())
表根据界面宽度自动伸缩
tablewidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
禁止编辑
tablewidget.setEditTriggers(QTableWidget.NoEditTriggers)
单击某单元,使之默认选中整行
tablewidget.setSelectionBehavior(QTableWidget.SelectRows)
设置宽高度与内容相匹配
代码语言:javascript复制tablewidget.resizeColumnsToContents()
tablewidget.resizeRowsToContents()
是否显示表头
代码语言:javascript复制tablewidget.horizontalHeader().setVisible(False)
tablewidget.verticalHeader().setVisible(False)
单元格中放置控件
代码语言:javascript复制# 添加控件
combox = QComboBox()
combox.addItem("男")
combox.addItem("女")
combox.setStyleSheet("QComboBox{margin:3px width:80px;}")
tablewidget.setCellWidget(1, 1, combox)
btn = QPushButton("保存")
btn.setDown(True)
btn.setStyleSheet("QPushButton{margin:20px width:20px;}")
tablewidget.setCellWidget(1, 2, btn)
输入行号,快速定位行
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/10 9:48
# @Author : Michael
# @File : table_position.py
# @desc :
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QTableWidget, QTableWidgetItem, QApplication
from PyQt5.QtCore import Qt
class table_position(QWidget):
def __init__(self):
super(table_position, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Table Position")
self.resize(300, 200)
layout = QHBoxLayout()
tablewidget = QTableWidget()
tablewidget.setRowCount(30)
tablewidget.setColumnCount(4)
layout.addWidget(tablewidget)
for i in range(30):
for j in range(4):
itemContent = f'{i},{j}'
tablewidget.setItem(i, j, QTableWidgetItem(itemContent))
self.setLayout(layout)
# 遍历表格查找指定内容
text = '10,1'
items = tablewidget.findItems(text, Qt.MatchExactly)
item = items[0]
# 选中单元格
item.setSelected(True)
# 设置背景颜色
item.setForeground(QBrush(QColor(255, 0, 0)))
row = item.row()
# 鼠标滚轮定位到第11行
tablewidget.verticalScrollBar().setSliderPosition(row)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = table_position()
window.show()
sys.exit(app.exec_())
设置颜色
代码语言:javascript复制# 设置颜色
newitem = QTableWidgetItem('new')
newitem.setForeground(QBrush(QColor(0, 255, 0)))
tablewidget.setItem(10, 1, newitem)
加粗字体
代码语言:javascript复制# 加粗字体
newitem = QTableWidgetItem("new")
newitem.setFont(QFont("Times", 20, QFont.Bold))
tablewidget.setItem(10, 2, newitem)
排序
代码语言:javascript复制tablewidget.sortItems(2, Qt.DescendingOrder) # 2 列,降序
文本对齐
代码语言:javascript复制# 文本对齐方式
newitem = QTableWidgetItem("michael")
newitem.setTextAlignment(Qt.AlignRight | Qt.AlignBottom)
tablewidget.setItem(10, 3, newitem)
合并单元格
代码语言:javascript复制# 合并单元格
tablewidget.setSpan(0, 0, 3, 1) # 0,0 位置 占据 3行 1列
tablewidget.setItem(0, 0, QTableWidgetItem("michael"))
tablewidget.setItem(1, 0, QTableWidgetItem("hello")) # 被占了,无效
设置单元格大小
代码语言:javascript复制# 设置单元格大小
tablewidget.setColumnWidth(0, 300) # 0列 300宽
tablewidget.setRowHeight(0, 150) # 0行 150高
显示网格线
代码语言:javascript复制# 不显示分割线
tablewidget.setShowGrid(False)
设置图片、更改图片大小
代码语言:javascript复制## 放置图片,调整大小
newitem = QTableWidgetItem(QIcon('../store.png'), "微软商店")
tablewidget.setItem(10, 3, newitem)
tablewidget.setIconSize(QSize(100, 100))
获取单元格内容
代码语言:javascript复制# 获取单元格内容
tablewidget.itemClicked.connect(self.handleItemClicked)
def handleItemClicked(self, item):
print('你点击了' item.text())
右键菜单
代码语言:javascript复制def generateMenu(pos):
row_num = -1
for i in tablewidget.selectionModel().selection().indexes():
row_num = i.row()
menu = QMenu()
item1 = menu.addAction("删除")
item2 = menu.addAction("修改")
item3 = menu.addAction("添加")
action = menu.exec_(tablewidget.mapToGlobal(pos))
if action == item1:
print(f"选中了删除,行号:{row_num}")
elif action == item2:
print(f"选中了修改,行号:{row_num}")
elif action == item3:
print(f"选中了添加,行号:{row_num}")
# 允许右键菜单
tablewidget.setContextMenuPolicy(Qt.CustomContextMenu)
tablewidget.customContextMenuRequested.connect(generateMenu)
1.5 QTreeView
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 20:26
# @Author : Michael
# @File : treewidget01.py
# @desc :
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QBrush
from PyQt5.QtWidgets import QApplication, QWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QMainWindow, QStyle
class TreeWidgetDemo(QMainWindow):
def __init__(self):
super(TreeWidgetDemo, self).__init__()
self.setWindowTitle("TreeWidget Demo")
self.tree = QTreeWidget()
self.tree.setColumnCount(2)
self.tree.setHeaderLabels(['Key', 'Value'])
root = QTreeWidgetItem(self.tree)
root.setText(0, 'group1')
root.setIcon(0, self.style().standardIcon(QStyle.SP_DirIcon))
self.tree.setColumnWidth(0, 150)
## 设置节点的背景颜色
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("../store.png"))
child1.setCheckState(0, Qt.Checked)
# 设置子节点2
child2 = QTreeWidgetItem(root)
child2.setText(0, 'child2')
child2.setText(1, '')
# 设置子节点3
child3 = QTreeWidgetItem(child2)
child3.setText(0, 'child3')
child3.setText(1, 'android')
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_())
点击事件
代码语言:javascript复制 self.tree.clicked.connect(self.on_tree_clicked)
def on_tree_clicked(self):
item = self.tree.currentItem()
print(item.text(0), item.text(1))
系统定制模式
- 使用
QTreeView
,setModel
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
if __name__ == '__main__':
app = QApplication(sys.argv)
# Window系统提供的模式
model = QDirModel()
# 创建一个QtreeView部件
tree = QTreeView()
# 为部件添加模式
tree.setModel(model)
tree.setWindowTitle("QTreeView 例子")
tree.resize(640, 480)
tree.show()
sys.exit(app.exec_())
2. 容器:装载更多控件
QTabWidget
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 21:01
# @Author : Michael
# @File : qtab_demo.py
# @desc :
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QTabWidget, QPushButton, QHBoxLayout, QVBoxLayout, QFormLayout,
QLineEdit, QRadioButton, QLabel, QCheckBox
class tab_demo(QTabWidget):
def __init__(self):
super().__init__()
self.tab1 = QWidget()
self.tab2 = QWidget()
self.tab3 = QWidget()
self.addTab(self.tab1, 'Tab1')
self.addTab(self.tab2, 'Tab2')
self.addTab(self.tab3, QIcon('../store.png'), 'Tab3')
self.tab1UI()
self.tab2UI()
self.tab3UI()
self.setWindowTitle('QTabWidget')
def tab1UI(self):
layout = QFormLayout()
layout.addRow("姓名", QLineEdit())
layout.addRow("地址", QLineEdit())
self.setTabText(0, "联系方式")
self.tab1.setLayout(layout)
def tab2UI(self):
layout = QFormLayout()
sex = QHBoxLayout()
sex.addWidget(QRadioButton("男"))
sex.addWidget(QRadioButton("女"))
layout.addRow(QLabel("性别"), sex)
layout.addRow("生日", QLineEdit())
self.setTabText(1, "个人详细信息")
self.tab2.setLayout(layout)
def tab3UI(self):
layout = QHBoxLayout()
layout.addWidget(QLabel("科目"))
layout.addWidget(QCheckBox("物理"))
layout.addWidget(QCheckBox("高数"))
self.setTabText(2, "教育程度")
self.tab3.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = tab_demo()
demo.show()
sys.exit(app.exec_())
QStackedWidget
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 21:16
# @Author : Michael
# @File : qstackedwidget.py
# @desc :
import sys
from PyQt5.QtWidgets import QWidget, QListWidget, QStackedWidget, QHBoxLayout, QApplication, QLabel, QCheckBox,
QLineEdit, QRadioButton, QFormLayout
class qstackedwidget_demo(QWidget):
def __init__(self):
super(qstackedwidget_demo, self).__init__()
self.setWindowTitle("QStackedWidget控件")
self.setGeometry(100, 100, 800, 600)
self.leftlist = QListWidget()
self.leftlist.insertItem(0, "联系方式")
self.leftlist.insertItem(1, "个人信息")
self.leftlist.insertItem(2, "教育经历")
self.stack1 = QWidget()
self.stack2 = QWidget()
self.stack3 = QWidget()
self.stack1UI()
self.stack2UI()
self.stack3UI()
self.stack = QStackedWidget()
self.stack.addWidget(self.stack1)
self.stack.addWidget(self.stack2)
self.stack.addWidget(self.stack3)
hbox = QHBoxLayout()
hbox.addWidget(self.leftlist)
hbox.addWidget(self.stack)
self.setLayout(hbox)
self.leftlist.currentRowChanged.connect(self.display)
def stack1UI(self):
layout = QFormLayout()
layout.addRow("姓名", QLineEdit())
layout.addRow("地址", QLineEdit())
self.stack1.setLayout(layout)
def stack2UI(self):
layout = QFormLayout()
sex = QHBoxLayout()
sex.addWidget(QRadioButton("男"))
sex.addWidget(QRadioButton("女"))
layout.addRow(QLabel("性别"), sex)
layout.addRow("生日", QLineEdit())
self.stack2.setLayout(layout)
def stack3UI(self):
layout = QHBoxLayout()
layout.addWidget(QLabel("科目"))
layout.addWidget(QCheckBox("物理"))
layout.addWidget(QCheckBox("高数"))
self.stack3.setLayout(layout)
def display(self, i):
self.stack.setCurrentIndex(i)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = qstackedwidget_demo()
demo.show()
sys.exit(app.exec_())
QDockWidget
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 21:40
# @Author : Michael
# @File : qdock_demo.py
# @desc :
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QHBoxLayout, QDockWidget, QListWidget, QApplication, QTextEdit
class qock_demo(QMainWindow):
def __init__(self):
super().__init__()
layout = QHBoxLayout()
bar = self.menuBar()
file = bar.addMenu('File')
file.addAction('New')
file.addAction('Open')
file.addAction('Save')
self.setCentralWidget(QTextEdit())
self.items = QDockWidget('Dockable', self)
self.listWidget = QListWidget()
self.listWidget.addItems(['Item 1', 'Item 2', 'Item 3'])
self.items.setWidget(self.listWidget)
self.items.setFloating(False)
self.addDockWidget(Qt.RightDockWidgetArea, self.items)
self.setLayout(layout)
self.setWindowTitle('Dock例子')
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
main = qock_demo()
main.show()
sys.exit(app.exec_())
多文档界面 QMdiArea
- 可以有效节省内存
QMdiArea
# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 23:20
# @Author : Michael
# @File : qmultiDocInterface.py
# @desc :
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class qmultiDocInterface(QMainWindow):
count = 0
def __init__(self, parent=None):
super(qmultiDocInterface, self).__init__(parent)
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")
file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
file.triggered[QAction].connect(self.windowaction)
self.setWindowTitle("MDI demo")
def windowaction(self, q):
print("triggered")
if q.text() == "New":
qmultiDocInterface.count = qmultiDocInterface.count 1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("子窗口" str(qmultiDocInterface.count))
self.mdi.addSubWindow(sub)
sub.show()
if q.text() == "cascade":
self.mdi.cascadeSubWindows() # 层叠
if q.text() == "Tiled":
self.mdi.tileSubWindows() # 平铺
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = qmultiDocInterface()
demo.show()
sys.exit(app.exec_())
QScrollBar
代码语言:javascript复制# _*_ coding: utf-8 _*_
# @Time : 2022/5/29 23:27
# @Author : Michael
# @File : qscrollbar.py
# @desc :
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
self.l1 = QLabel("拖动滑动条去改变颜色")
self.l1.setFont(QFont("Arial", 16))
hbox.addWidget(self.l1)
self.s1 = QScrollBar()
self.s1.setMaximum(255)
self.s1.sliderMoved.connect(self.sliderval)
self.s2 = QScrollBar()
self.s2.setMaximum(255)
self.s2.sliderMoved.connect(self.sliderval)
self.s3 = QScrollBar()
self.s3.setMaximum(255)
self.s3.sliderMoved.connect(self.sliderval)
hbox.addWidget(self.s1)
hbox.addWidget(self.s2)
hbox.addWidget(self.s3)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('QScrollBar 例子')
self.setLayout(hbox)
def sliderval(self):
print(self.s1.value(), self.s2.value(), self.s3.value())
palette = QPalette()
c = QColor(self.s1.value(), self.s2.value(), self.s3.value(), 255)
palette.setColor(QPalette.Foreground, c)
self.l1.setPalette(palette)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Example()
demo.show()
sys.exit(app.exec_())