Python入坑系列:桌面GUI开发之Pyside6
bigegpt 2024-10-12 05:25 7 浏览
阅读本章之后,你可以掌握这些内容:
- Pyside6的Signals and Slots、Envents的作用,如何使用?
- PySide6的Window、Dialogs and Alerts、Widgets、layouts 、Toolbars and Menus都是些什么,有哪些效果?
- 通过CSS类似样式文件怎么控制PySide6的组件样式?
安装Pyside6
- 环境版本
python | 3.10.6 |
pip | 22.3.1 |
- 直接安装
pip install pyside6
- 指定版本安装
pip install pyside6==6.6.2
Pyside6核心介绍
每个Qt应用程序的核心是QApplication类,每个应用程序都需要一个(且只有一个)QApplication对象来运行。QApplication对象保存应用程序的事件循环—控制所有用户与GUI交互的核心循环,与应用程序的每次交互—无论是按下键、单击鼠标还是移动鼠标—都会生成一个事件,该事件被放置在事件队列中。在事件循环中,在每次迭代时检查队列,如果发现等待事件,则将事件和控制传递给该事件的特定事件处理程序。事件处理程序处理事件,然后将控制传递回事件循环以等待更多事件。
制作一个简单桌面程序,只需要五步:
第一步:引入模块,如果偷懒,可以将import内容改成*
from PySide6.QtWidgets import QApplication, QWidget
第二步:创建QApplication对象,可以将sys.argv改成[],不接收命令行参数
app = QApplication(sys.argv)
第三步:构建QWidget对象或者QMainWindow对象
window = QMainWindow()
第四步:显示控件
window = QWidget()
window.show()
第五步:执行
app.exec()
1、Signals and Slots
信号(Signals)和插槽(Slots)是实现对象间通信的关键机制,这一机制允许对象在发生特定事件时通知其他对象,是一种事件驱动编程的核心概念,广泛应用于Qt应用程序中,特别是在GUI开发中。
信号(Signals):信号是组件在发生某些事情时发出的通知。比如从按下按钮,到输入框的文本改变,到窗口的文本改变。许多信号是由用户的动作发起的,但这不是一个规则。除了通知发生的事情外,信号还可以发送数据以提供有关发生的事情的额外上下文
插槽(Slots):用于信号接收器的名称。在Python中,应用程序中的任何函数(或方法)都可以用作插槽——只需将信号连接到它。如果信号发送数据,那么接收函数也将接收该数据。许多Qt小部件也有自己的内置插槽,这意味着您可以直接将Qt小部件连接在一起
2、Events
在Qt应用程序中,用户与应用程序的每一次交互都是一个事件。事件有很多种类型,每种类型代表不同类型的交互。Qt使用事件对象来表示这些事件,这些对象封装了发生了什么的信息。这些事件被传递给发生交互的小部件上的特定事件处理器。通过定义自定义的或扩展的事件处理器,你可以改变你的小部件对这些事件的响应方式。事件处理器就像定义其他方法一样,但名称是针对它们处理的事件类型的。小部件接收的主要事件之一是QMouseEvent。QMouseEvent事件为小部件上的每一次鼠标移动和按钮点击创建。
以下是可用于处理鼠标事件的事件处理器:
- mousePressEvent(event): 当鼠标按钮被按下时调用。
- mouseReleaseEvent(event): 当鼠标按钮被释放时调用。
- mouseDoubleClickEvent(event): 当鼠标按钮被双击时调用。
- mouseMoveEvent(event): 当鼠标移动时调用,但只有当至少一个鼠标按钮被按下时才会触发
3、Widget
部件(Widgets)是构建图形用户界面(GUI)的基本元素。小部件可以是一个按钮、文本框、标签、窗口等等。PySide提供了一系列预定义的小部件,允许开发者创建丰富的桌面应用程序。Pyside所有组件都继承自QWidget。
4、Layouts
在PySide(Qt for Python)中,布局是管理窗口或对话框中小部件位置和大小的对象。布局不仅可以自动调整小部件的大小以适应窗口,还可以在用户调整窗口大小时保持小部件之间的相对位置不变。使用布局是创建具有良好组织和可适应不同屏幕尺寸的图形用户界面(GUI)的关键。以下是几种可用基础布局:
- QVBoxLayout:将小部件垂直排列。
- QHBoxLayout:将小部件水平排列。
- QGridLayout:在一个网格中排列小部件。这是一种更灵活的布局方式,允许你在行和列中精确地放置小部件
- QFormLayout:用于表单布局,将标签与字段水平排列。
- QStackedLayout:允许你在相同的空间内堆叠多个小部件,每次只显示一个
小部件示例
以下展示的是几个简单的示例
1、Window
- 源代码:
import sys
from PySide6.QtCore import QSize
from PySide6.QtWidgets import QApplication, QMainWindow
def start():
app = QApplication(sys.argv)
window = QMainWindow()
window.setFixedSize(QSize(400, 300))
window.show()
app.exec()
if __name__ == '__main__':
start()
- 效果图:
2、Dialogs and Alerts
- 源代码:
import sys
from PySide6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QMainWindow, QApplication, QPushButton
class CustomDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("HELLO!")
QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
self.buttonBox = QDialogButtonBox(QBtn)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
self.layout = QVBoxLayout()
message = QLabel("Something happened, is that OK?")
self.layout.addWidget(message)
self.layout.addWidget(self.buttonBox)
self.setLayout(self.layout)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My App")
button = QPushButton("Press me for a dialog!")
button.clicked.connect(self.button_clicked)
self.setCentralWidget(button)
def button_clicked(self, s):
print("click", s)
dlg = CustomDialog(self)
if dlg.exec():
print("Success!")
else:
print("Cancel!")
def start():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
start()
- 效果图:
3、Widgets
- 源代码:
import sys
from PySide6.QtWidgets import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Widgets App")
layout = QVBoxLayout()
widgets = [QCheckBox,QComboBox,QDateEdit,QDateTimeEdit,QDial,QDoubleSpinBox,
QFontComboBox,QLCDNumber,QLabel,QLineEdit,QProgressBar,QPushButton,
QRadioButton,QSlider,QSpinBox,QTimeEdit,QTextEdit]
for widget in widgets:
widget_instance = widget() # 创建widget的实例
if isinstance(widget_instance, QDateEdit):
# 如果widget是QDateEdit类型,则启用日历弹出窗口
widget_instance.setCalendarPopup(True)
layout.addWidget(widget_instance) # 将widget实例添加到布局中
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
def start():
"""组件的例子:https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/QFontComboBox.html#qfontcombobox"""
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
start()
- 效果:
4、Layouts
- 源代码:
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout
from PySide6.QtGui import QPalette, QColor
class Color(QWidget):
def __init__(self, color):
super(Color, self).__init__()
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("My App")
layout = QGridLayout()
layout.addWidget(Color('red'), 0, 0)
layout.addWidget(Color('green'), 1, 0)
layout.addWidget(Color('blue'), 1, 1)
layout.addWidget(Color('purple'), 2, 1)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def start():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
start()
- 效果图:
4、Toolbars and Menus
- 源代码:
import sys
from PySide6.QtCore import QSize, Qt
from PySide6.QtGui import QAction, QIcon
from PySide6.QtWidgets import QMainWindow, QApplication, QLabel, QToolBar, QCheckBox, QStatusBar
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("My App")
label = QLabel("Hello!")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
toolbar = QToolBar("My main toolbar")
toolbar.setIconSize(QSize(16, 16))
self.addToolBar(toolbar)
button_action = QAction(QIcon("icons/bug.png"), "&Your button", self)
button_action.setStatusTip("This is your button")
button_action.triggered.connect(self.onMyToolBarButtonClick)
button_action.setCheckable(True)
toolbar.addAction(button_action)
toolbar.addSeparator()
button_action2 = QAction(QIcon("icons/bug.png"), "Your &button2", self)
button_action2.setStatusTip("This is your button2")
button_action2.triggered.connect(self.onMyToolBarButtonClick)
button_action2.setCheckable(True)
toolbar.addAction(button_action2)
toolbar.addWidget(QLabel("Hello"))
toolbar.addWidget(QCheckBox())
self.setStatusBar(QStatusBar(self))
menu = self.menuBar()
file_menu = menu.addMenu("&File")
file_menu.addAction(button_action)
file_menu.addSeparator()
file_menu.addAction(button_action2)
def onMyToolBarButtonClick(self, s):
print("click", s)
def start():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
if __name__ == '__main__':
start()
- 效果图:
如果需要图标的可以免费下载:
https://p.yusukekamiyamane.com/icon/downloads/fugue-icons-3.5.6.zip
QSS样式使用
QSS全称是 Qt Style Sheets(Qt 样式表),适用于小部件样式,语法几乎与html的css相同,功能上要弱一些。Pyside的样式支持两种方式:
1、代码直接引用
定义样式字符串,然后通过设置setStyleSheet来引用样式。
- 源代码:
import sys
from PySide6.QtCore import Slot, QSize
from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QMainWindow, QWidget
def start():
app = QApplication(sys.argv)
window = QMainWindow()
window.setFixedSize(QSize(300,200))
layout = QVBoxLayout()
button = QPushButton("Click me")
btn_style = """ QPushButton {
background-color: red;
color: blue;
}
"""
button.setFixedSize(QSize(100,50))
button.setStyleSheet(btn_style)
button.clicked.connect(say_hello)
layout.addWidget(button)
widget = QWidget()
widget.setLayout(layout)
window.setCentralWidget(widget)
window.show()
app.exec()
@Slot()
def say_hello():
print("Button clicked, Hello!")
if __name__ == '__main__':
start()
- 效果图:
2、通过*.qss样式文件引用
1)定义样式文件,如btn_style.qss
/*匹配QLineEdit及其子类控件*/
QLineEdit{
color:yellow;
}
/*匹配QPushButton,QLineEdit,QTextEdit控件及其子控件,多个用逗号分隔*/
QPushButton,QLineEdit,QTextEdit{
color:yellow;
background-color:red;
}
/*匹配QLineEdit控件,但不匹配其子类控件*/
.QLineEdit{
color:yellow;
}
/*匹配所有object name为text的QLineEdit控件*/
QLineEdit#text{
color:yellow;
}
/*匹配QMainWindow内部 所有QLineEdit控件*/
QMainWindow QLineEdit{
color:yellow;
}
/*匹配QMainWindow内部 直接子节点上的 QLineEdit控件*/
QMainWindow > QLineEdit{
color:yellow;
}
/*匹配QLineEdit中具备属性input且值为'text'的控件*/
QLineEdit[input='text']{
color:yellow;
}
/*匹配QMenuBar菜单中的子项*/
QMenuBar::item{
color:yellow;
}
2)引用样式文件-全局方式
app = QApplication(sys.argv)
#全局引用
with open("btn_style.qss", "r") as f:
btn_style = f.read()
app.setStyleSheet(btn_style)
3)引用样式文件-局部引用
button = QPushButton("Click me")
button.setFixedSize(QSize(100,50))
#局部引用
with open("btn_style.qss", "r") as f:
btn_style = f.read()
button.setStyleSheet(btn_style)
button.clicked.connect(say_hello)
效果图:
相关推荐
- Linux 命令 ncftp(文件传输)——想玩转linux就请一直看下去
-
我是IT悟道,点击右上方“关注”,每天分享IT、科技、数码方面的干货。Linuxncftp命令Linux命令大全Linuxncftp命令用于传输文件。FTP让用户得以下载存放于服务器主机的文件,...
- 玩转 Linux 之:磁盘分区、挂载知多少?
-
今天来聊聊linux下磁盘分区、挂载的问题,篇幅所限,不会聊的太底层,纯当科普!!1、Linux分区简介1.1主分区vs扩展分区硬盘分区表中最多能存储四个分区,但我们实际使用时一般只分为两...
- 一文带你了解 Linux 文件权限,从基础到高级
-
在Linux中,每个文件和目录都关联了一组权限,定义了不同用户对其的访问能力。权限分为三类:读取(read,r)、写入(write,w)和执行(execute,x),分别用字母r、w、x...
- Linux 使用 socat 让云服务器作为跳板机的方法
-
概念三台机器:客户端A(192.168.1.11)服务器B(192.168.1.88)跳板机C(192.168.1.32)实现A与B的双向数据传输,本该这样:A<...
- Linux启动流程之ROM-CODE(linux启动详解)
-
1.从哪里开始?下图是AM335X核心板和功能框图:AM335X核心板的存储信息如下:AM335X核心板运行linux系统,在这里提出一个问题:上电后指令从哪里开始执行?DDRorEMMC?2....
- 「Linux」——select和epoll详解(linux epoll详解)
-
select和epoll详解select和epoll的区别(面试常考)select一、什么是select1.select函数原型2.参数解释3.参数timeout取值4.返回值5.监控原理二、sele...
- Linux中使用输入输出和错误重定向, 赶紧收藏!
-
Linux中的每个进程都提供三个打开的文件(通常称为文件描述符),分别是标准的输入、输出和错误文件。StandardInput是键盘,抽象为文件,使编写脚本和程序更容易。StandardOut...
- 「正点原子Linux连载」第七十一章Linux 4G通信实验
-
1)实验平台:正点原子Linux开发板2)摘自《正点原子I.MX6U嵌入式Linux驱动开发指南》关注官方微信号公众号,获取更多资料:正点原子第七十一章Linux4G通信实验前面我们学习了如何在Li...
- LSM Oops 内存错误根因分析与解决
-
作者简介:吴文涵,图形算法出身,同时热爱linux内核开发的工程师,喜欢推导并乐于分享。版权声明:本文最先发表于“泰晓科技”微信公众号,欢迎转载,转载时请在文章的开头保留本声明。Oops是...
- 连你家电器的算力都不放过,新发现Linux恶意软件用IoT设备挖矿
-
萧箫发自凹非寺量子位|公众号QbitAI继电脑和手机后,挖矿病毒也盯上了IoT设备。无论是智能冰箱、彩电还是洗衣机,但凡有点算力的(物联网和端侧)设备都可能被这种病毒感染,用于挖掘加密货币等...
- 苹果iOS 26锁屏大升级:更个性更沉浸 有五大亮点
-
【CNMO科技消息】CNMO注意到,苹果近日在iOS26开发者预览版中推出了多项锁屏界面创新功能,可以大幅提升用户个性化设置与操作便捷性。这些更新不仅优化了视觉体验,还通过技术手段增强了交互效率,为...
- 福彩 3D 第 2025178 期:心水407 !大小奇偶双平衡 + 跨度适配,速收藏
-
福彩3D第2025178期:497后和值回落!五维分析+形态调整策略福彩3D2025177期开奖号码497,组六形态,大小比2:1,奇偶比1:2,和值20,跨度5。面对大...
- 一加 Ace5 至尊版手机首发适配和平精英手游
-
7月8日消息,据用户反馈,一加Ace5至尊版手机开启新版本系统推送,升级包大小约6.83MB、版本号为15.0.2.215(CN01),适配了腾讯《和平精英》手游144Hz高刷。IT...
- 外媒称苹果今年秋季将推出超15款新品 远不止iPhone 17
-
【CNMO科技消息】2025年已过半程,有外媒指出苹果计划在今年秋季推出超过15款新产品,涵盖iPhone革新、M5芯片设备迭代、可穿戴设备升级及智能家居布局等。苹果1.iPhone17系列:产品...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)