前言
最近使用
Pyside2
编写了几个GUI工具,发现效果出奇的好。遂产生了分享它的念头。
接下来如果不出意外,大概没有意外,我会开始写这个专栏,介绍从零开始去编写一个实用的GUI工具。
这是Pyside2
第一篇:《总览》
本文对Pyside2在开发使用中进行了知识点的提炼,所以后面本专栏更新文章内容大致就是针对本文的每个小内容做一些拓展。
建议有需要的小伙伴通过官方文档去进行系统地学习!!
Pyside2 文档:https://doc.qt.io/qtforpython/
后面专栏新增文章时候,本文会做出相应修改!!
专栏整体大概在10篇以上,反正学了你就能使用Pyside2
编写自己的GUI工具了。
专栏脉络
专栏内容大体如下,会酌情增加一些使用技巧以及方法。
基本流程
- 布局(通过designer.exe 手动绘制
- 编写逻辑
- 将布局展示
前置操作
安装模块
pip install pyside2
文件转换
关于pyside2文件:https://doc.qt.io/qtforpython/tutorials/pretutorial/typesoffiles.html
- ui文件:布局文件,基于 XML 的格式
- qrc文件:Qt Recources file,是一个 XML 格式的资源配置文件
ui to py
pyside2-uic xxx.ui -o xxx.py
qrc to py
pyside2-rcc xxx.qrc -o xxx.py
默认模板
官方展示的案例
import sys
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QLabel
if __name__ == "__main__":
app = QApplication(sys.argv)
label = QLabel("Hello World", alignment=Qt.AlignCenter)
label.show()
sys.exit(app.exec_())
加载 ui 有两种方式,
- 一种是直接加载ui
- 一种是将ui转成py,然后再加载py
直接加载ui
- 不好用,不做展示。
加载py
from PySide2.QtWidgets import QApplication, QMainWindow
from demo_ui import Ui_Form
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())
设置焦点
鼠标点击某个组件就执行指定操作时候,可以用到这一步。结合 鼠标点击事件。
方法一:
在designer 中,选中对应的组件,
属性编辑器 -> focusPolicy -> ClickFocus
后面当鼠标点击在该组件时候,ui当前的焦点就在该组件上。
方法二:
self.QWidget.setFocusPolicy(Qt.ClickFocus)
固定界面大小
self.setFixedSize(self.width(), self.height())
TableWidget
设置行数
TableWidget.setRowCount(int()) # 输入int
不显示行号
TableWidget.verticalHeader().setVisible(False)
列可拖拽
TableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)
均分列的宽度
TableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
根据内容长度分配列宽
- 两句一起用,效果更好
TableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
# 指定第0列
TableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
# 也可以不指定列,作用于所有列
TableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
Table显示
from PySide2.QtWidgets import QTableWidgetItem
data = [('c1', 'c2', 'c3'), ('d1', 'd2', 'd3')...]
for row, row_data in enumerate(data):
for columns, columns_data in enumerate(row_data):
TableWidget.setItem(row, columns, QTableWidgetItem(str(columns_data)))
表格复制
def __init__(self):
# 剪切板
self.cb = QtWidgets.QApplication.clipboard()
...
# 单击表格单元格,即黏贴到剪切板
self.table_show.clicked.connect(lambda: self.cb.setText(self.QTableWidget.currentItem().text()))
def keyPressEvent(self, event):
""" Ctrl + C复制表格内容 """
if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_C:
# 获取表格的选中行
# 只取第一个数据块,其他的如果需要要做遍历,简单功能就不写得那么复杂了
selected_ranges = self.QTableWidget.selectedRanges()[0]
# 最后总的内容
text_str = ""
# 行(选中的行信息读取)
for _row in range(selected_ranges.topRow(), selected_ranges.bottomRow() + 1):
row_str = ""
# 列(选中的列信息读取)
for col in range(selected_ranges.leftColumn(), selected_ranges.rightColumn() + 1):
item = self.QTableWidget.item(_row, col)
# 制表符间隔数据
row_str += item.text() + '\t'
# 换行
text_str += row_str + '\n'
self.cb.setText(text_str)
QFileDialog
导入文件&文件夹
from PySide2.QtWidgets import QFileDialog
# 对应的,做一些格式的筛选
path = QFileDialog.getOpenFileName(self, '选择文件', '.py', 'Python Files (*.py)')[0]
# 选择多个文件
path = QFileDialog.getOpenFileNames(self, '选择文件', '.py', 'Python Files (*.py)')[0]
导出文件
QFileDialog.getSaveFileName(self, '保存文档', 'untitled.xlsx', 'excel文件 (*.xls *.xlsx)')[0]
QMessageBox
提示弹窗
from PySide2.QtWidgets import QFileDialog
QMessageBox.information(self, '提示', '这是提示弹窗')
可选提示弹窗
res = QMessageBox.question(self, 'Message', '确定要退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if res == QMessageBox.Yes:
print('你选择了是.')
else:
print('你选择了否.')
radioButton
清空选择
QRadioButton.setAutoExclusive(False)
QRadioButton.setChecked(False)
QRadioButton.setAutoExclusive(True)
事件监听
文件拖拽
# 设置文件支持拖拽
self.setAcceptDrops(True)
def dragEnterEvent(self, event) -> None:
"""文件拖拽事件"""
if event.mimeData().hasText():
# 获取拖拽进来的文件路径
file_path = event.mimeData().urls()[0].toLocalFile()
# 鼠标放开函数事件
event.accept()
# do something
else:
event.ignore()
关闭事件
def closeEvent(self, event) -> None:
"""关闭事件"""
res = QMessageBox.question(self, 'Message', '确定要退出吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if res == QMessageBox.Yes:
event.accept()
else:
event.ignore()
鼠标点击事件
def mousePressEvent(self, event) -> None:
"""鼠标点击事件"""
# 判定是左键点击
if event.button() == Qt.MouseButton.LeftButton:
time.sleep(1)
self.import_file()
return
self.focusWidget().objectName() == 'groupBox'
窗口可拖拽
- 重写3个函数,
from PySide2.QtCore import Qt, QPoint
def __init__(self):
# 窗口移动、设置鼠标动作位置
self._move = False
self.m_position = QPoint(0, 0)
# 鼠标点击事件产生
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self._move = True
self.m_position = event.globalPos() - self.pos()
event.accept()
# 鼠标移动事件
def mouseMoveEvent(self, QMouseEvent):
if Qt.LeftButton and self._move:
self.move(QMouseEvent.globalPos() - self.m_position)
QMouseEvent.accept()
# 鼠标释放事件
def mouseReleaseEvent(self, QMouseEvent):
self._move = False
隐藏边框、阴影效果
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QGraphicsDropShadowEffect
def __init__(self):
# 隐藏边框
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
# 阴影效果
effect = QGraphicsDropShadowEffect(self)
effect.setBlurRadius(30)
effect.setOffset(0, 0)
effect.setColor(Qt.gray)
self.setGraphicsEffect(effect)
状态栏图标
from ctypes import windll
# 这段代码放在前面即可
try:
myapp_id = 'mycompany.myproduct.subproduct.version'
windll.shell32.SetCurrentProcessExplicitAppUserModelID(myapp_id)
except ImportError:
pass
if __name__ == "__main__":
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication([])
# 指定状态栏和程序左上角的图标,需要绝对路径
app.setWindowIcon(QtGui.QIcon(r'C:\User\Desktop\icon.ico'))
window = MainWindow()
window.show()
sys.exit(app.exec_())
打包成 .exe
…
后话
本次分享远远未结束!!
建议关注本专栏,以获得文章更新的最新消息哦!!
🐱🏍🐱🏍