百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python入坑系列:桌面GUI开发之Pyside6

itomcoil 2025-06-24 14:28 13 浏览

阅读本章之后,你可以掌握这些内容:

  1. Pyside6的Signals and Slots、Envents的作用,如何使用?
  2. PySide6的Window、Dialogs and Alerts、Widgets、layouts 、Toolbars and Menus都是些什么,有哪些效果?
  3. 通过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)

效果图:

相关推荐

selenium(WEB自动化工具)

定义解释Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7,8,9,10,11),MozillaF...

开发利器丨如何使用ELK设计微服务中的日志收集方案?

【摘要】微服务各个组件的相关实践会涉及到工具,本文将会介绍微服务日常开发的一些利器,这些工具帮助我们构建更加健壮的微服务系统,并帮助排查解决微服务系统中的问题与性能瓶颈等。我们将重点介绍微服务架构中...

高并发系统设计:应对每秒数万QPS的架构策略

当面试官问及"如何应对每秒几万QPS(QueriesPerSecond)"时,大概率是想知道你对高并发系统设计的理解有多少。本文将深入探讨从基础设施到应用层面的解决方案。01、理解...

2025 年每个 JavaScript 开发者都应该了解的功能

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.Iteratorhelpers开发者...

JavaScript Array 对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

Gemini 2.5编程全球霸榜,谷歌重回AI王座,神秘模型曝光,奥特曼迎战

刚刚,Gemini2.5Pro编程登顶,6美元性价比碾压Claude3.7Sonnet。不仅如此,谷歌还暗藏着更强的编程模型Dragontail,这次是要彻底翻盘了。谷歌,彻底打了一场漂亮的翻...

动力节点最新JavaScript教程(高级篇),深入学习JavaScript

JavaScript是一种运行在浏览器中的解释型编程语言,它的解释器被称为JavaScript引擎,是浏览器的一部分,JavaScript广泛用于浏览器客户端编程,通常JavaScript脚本是通过嵌...

一文看懂Kiro,其 Spec工作流秒杀Cursor,可移植至Claude Code

当Cursor的“即兴编程”开始拖累项目质量,AWS新晋IDEKiro以Spec工作流打出“先规范后编码”的系统工程思维:需求-设计-任务三件套一次生成,文档与代码同步落地,复杂项目不...

「晚安·好梦」努力只能及格,拼命才能优秀

欢迎光临,浏览之前点击上面的音乐放松一下心情吧!喜欢的话给小编一个关注呀!Effortscanonlypass,anddesperatelycanbeexcellent.努力只能及格...

JavaScript 中 some 与 every 方法的区别是什么?

大家好,很高兴又见面了,我是姜茶的编程笔记,我们一起学习前端相关领域技术,共同进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力在JavaScript中,Array.protot...

10个高效的Python爬虫框架,你用过几个?

小型爬虫需求,requests库+bs4库就能解决;大型爬虫数据,尤其涉及异步抓取、内容管理及后续扩展等功能时,就需要用到爬虫框架了。下面介绍了10个爬虫框架,大家可以学习使用!1.Scrapysc...

12个高效的Python爬虫框架,你用过几个?

实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...

pip3 install pyspider报错问题解决

运行如下命令报错:>>>pip3installpyspider观察上面的报错问题,需要安装pycurl。是到这个网址:http://www.lfd.uci.edu/~gohlke...

PySpider框架的使用

PysiderPysider是一个国人用Python编写的、带有强大的WebUI的网络爬虫系统,它支持多种数据库、任务监控、项目管理、结果查看、URL去重等强大的功能。安装pip3inst...

「机器学习」神经网络的激活函数、并通过python实现激活函数

神经网络的激活函数、并通过python实现whatis激活函数感知机的网络结构如下:左图中,偏置b没有被画出来,如果要表示出b,可以像右图那样做。用数学式来表示感知机:上面这个数学式子可以被改写:...