PySide6开发日记(一)
阅读时间: 8 min
PySide6 开发日记(一)
前言
今年早些时候,为国产读书书摘记录软件做了一个 api 导入程序,第一版发布后有两个用户,但后面就没关注这个程序了,半个月之前其中一位用户向我询问能否为程序增加一些新的功能,就此我开始程序 v0.2 版本的开发。
程序名字是《merpyzf_pyside6》,顾名思义,技术栈是 PySide6,于是继续一边学习一边写新功能,目前来看新版本开发会持续几周,索性就当作周记,每周记录自己的学习心得。
笔记一:程序的顶部状态栏
1. 隐藏系统状态栏
虽然暂时没有打算做 Mac OS 和 Linux 版本,但是 Windows 的系统 UI 已经让我大为不爽了,于是开始研究无边框模式,搜到了许多教程,但实测下来能用的确实都有各种各样的问题。
最后连带 AI 和各种资料总算是写出了我需要的代码。
from PySide6.QtCore import *from PySide6.QtGui import *from PySide6.QtWidgets import *
if __name__ == '__main__': app = QApplication([])
window = QMainWindow() window.setWindowTitle('隐藏系统状态栏') window.resize(400, 300)
layout = QVBoxLayout(window) label = QLabel('这是一个无状态栏示例') layout.addWidget(label)
5 collapsed lines
# 隐藏状态栏 window.setWindowFlag(Qt.WindowType.FramelessWindowHint)
window.show() app.exec()核心部分就是setWindowFlag。起初我在网络上查找相关代码时看到了许多教程,但是当我尝试导入 Qt 时,显示在 QtCore、QtGui 类下都存在 Qt 库,便一直没能成功,最后索性使用* 进行导入。
2. 设置最大化,最小化以及关闭程序按钮,并放置在合适的位置
三个按钮很好搞定,QPushbutton+icon 属性就搞定了。
我想到可以用菜单栏用于放置它们,PySide6 中当然也有相关的功能,QToolBar 组件。
于是第一版程序很快就写出来了:
from PySide6.QtGui import *from PySide6.QtWidgets import *
def window_max(): ...
if __name__ == "__main__": app = QApplication([])
window = QMainWindow() window.setWindowTitle("隐藏系统状态栏") window.resize(400, 300)
widget_center = QWidget()42 collapsed lines
layout = QVBoxLayout(widget_center) label = QLabel("这是一个无状态栏示例") layout.addWidget(label)
# 隐藏状态栏 window.setWindowFlag(Qt.WindowType.FramelessWindowHint)
toolbar = QToolBar() # 设置工具栏不可移动 toolbar.setMovable(False)
# 填充工具栏左侧,让三个按钮被放置到最右侧 widget_fill = QWidget() toolbar.addWidget(widget_fill) layout_toolbar = QHBoxLayout(widget_fill) layout_toolbar.addStretch()
# 设置三个按钮,并将其设置为图片形式 btn_min = QPushButton(icon=QIcon("assets/min.svg")) btn_max = QPushButton(icon=QIcon("assets/icon-max.svg")) btn_close = QPushButton(icon=QIcon("assets/close.svg"))
# 去除按钮边框 btn_min.setFlat(True) btn_max.setFlat(True) btn_close.setFlat(True)
# 将按钮放置在toolbar上 toolbar.addWidget(btn_min) toolbar.addWidget(btn_max) toolbar.addWidget(btn_close)
# 为按钮增加功能,其中最大化按钮需要额外函数进行修饰 btn_min.clicked.connect(window.showMinimized) btn_max.clicked.connect(lambda: window_max()) btn_close.clicked.connect(window.close)
# 将toolbar放置到window上 window.addToolBar(toolbar) window.setCentralWidget(widget_center) window.show() app.exec()运行效果:
3 窗口拖动
隐藏窗口一时爽,隐藏以后动不了,当我发现窗口开始变得不能移动后人都傻掉了,只好开始寻找方法。
处理方法也不难,当我发现 PySide6 中存在三个函数(mousePressEvent、mouseMoveEvent、mouseReleaseEvent)后,这件事就变得简单起来。
from PySide6.QtGui import *from PySide6.QtWidgets import *
class QMainWindow(QMainWindow): def __init__(self): super().__init__()
def mousePressEvent(self, event): # 当鼠标按钮被按下时调用此函数 if event.button() == Qt.LeftButton: self._move_drag = True self.cursor_win_pos = event.globalPosition() - self.pos() event.accept()
def mouseMoveEvent(self, event): # 当鼠标移动时调用此函数73 collapsed lines
# 如果鼠标左键被按下并且可以拖动窗口 if Qt.LeftButton and self._move_drag: m_Point = ( event.globalPosition() - self.cursor_win_pos ) # 计算新的鼠标全局坐标与初始位置的差值 self.move(int(m_Point.x()), int(m_Point.y())) # 根据差值移动窗口到新的位置 event.accept() # 接受事件,不再传递
def mouseReleaseEvent(self, event): # 鼠标按键释放时,取消移动 self._move_drag = False event.accept()
def window_max(self): if self.isMaximized(): self.showNormal()
else: self.showMaximized()
if __name__ == "__main__": app = QApplication([])
window = QMainWindow() window.setWindowTitle("隐藏系统状态栏") window.resize(400, 300)
window._move_drag = False
widget_center = QWidget() layout = QVBoxLayout(widget_center) label = QLabel("这是一个无状态栏示例") layout.addWidget(label)
# 隐藏状态栏 window.setWindowFlag(Qt.WindowType.FramelessWindowHint)
toolbar = QToolBar() # 设置工具栏不可移动 toolbar.setMovable(False)
# 填充工具栏左侧,让三个按钮被放置到最右侧 widget_fill = QWidget() toolbar.addWidget(widget_fill) layout_toolbar = QHBoxLayout(widget_fill) layout_toolbar.addStretch()
# 设置三个按钮,并将其设置为图片形式 btn_min = QPushButton(icon=QIcon("assets/min.svg")) btn_max = QPushButton(icon=QIcon("assets/icon-max.svg")) btn_close = QPushButton(icon=QIcon("assets/close.svg"))
# 去除边框 btn_min.setFlat(True) btn_max.setFlat(True) btn_close.setFlat(True)
# 将按钮放置在toolbar上 toolbar.addWidget(btn_min) toolbar.addWidget(btn_max) toolbar.addWidget(btn_close)
# 为按钮增加功能,其中最大化按钮需要额外函数进行修饰 btn_min.clicked.connect(window.showMinimized) btn_max.clicked.connect(lambda: window.window_max()) btn_close.clicked.connect(window.close)
# 将toolbar放置到window上 window.addToolBar(toolbar) window.setCentralWidget(widget_center)
window.show() app.exec()不过今天在写博客时,我发现了一个新的办法,不需要重写这三个方法,看起来更加的简洁实用:
from PySide6.QtGui import *from PySide6.QtWidgets import *
class QMainWindow(QMainWindow): def __init__(self): super().__init__()
def window_max(self): if self.isMaximized(): self.showNormal()
else: self.showMaximized()
59 collapsed lines
def move_title_bar(self, event): self.windowHandle().startSystemMove()
if __name__ == "__main__": app = QApplication([])
window = QMainWindow() window.setWindowTitle("隐藏系统状态栏") window.resize(400, 300)
window._move_drag = False
widget_center = QWidget() layout = QVBoxLayout(widget_center) label = QLabel("这是一个无状态栏示例") layout.addWidget(label)
# 隐藏状态栏 window.setWindowFlag(Qt.WindowType.FramelessWindowHint)
toolbar = QToolBar() # 设置工具栏不可移动 toolbar.setMovable(False)
# 填充工具栏左侧,让三个按钮被放置到最右侧 widget_fill = QWidget() toolbar.addWidget(widget_fill) layout_toolbar = QHBoxLayout(widget_fill) layout_toolbar.addStretch()
# 设置三个按钮,并将其设置为图片形式 btn_min = QPushButton(icon=QIcon("assets/min.svg")) btn_max = QPushButton(icon=QIcon("assets/icon-max.svg")) btn_close = QPushButton(icon=QIcon("assets/close.svg"))
# 去除边框 btn_min.setFlat(True) btn_max.setFlat(True) btn_close.setFlat(True)
# 将按钮放置在toolbar上 toolbar.addWidget(btn_min) toolbar.addWidget(btn_max) toolbar.addWidget(btn_close)
# 为按钮增加功能,其中最大化按钮需要额外函数进行修饰 btn_min.clicked.connect(window.showMinimized) btn_max.clicked.connect(lambda: window.window_max()) btn_close.clicked.connect(window.close)
# 将toolbar放置到window上 window.addToolBar(toolbar) window.setCentralWidget(widget_center)
toolbar.mouseMoveEvent = window.move_title_bar
window.show() app.exec()其实核心部分只有以下两点:
def move_title_bar(self, event): self.windowHandle().startSystemMove() toolbar.mouseMoveEvent = window.move_title_bar不仅实现了移动,而且只有光标在 toolbar 上时才会执行,更加符合使用习惯了吧哈哈哈。
未完事项
- 实现拖动边框进行窗口的大小设置;