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

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

bigegpt 2024-10-12 05:25 4 浏览

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

  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)

效果图:

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...