PySide6 GUI 学习笔记——用代码定义界面

用代码定义界面

用过javaswing来设计界面的朋友对这种方式一定不陌生,通过函数(方法)、类或模块(包)来定义界面,并将界面与要执行的函数(方法)绑定。

用函数定义界面

通过一个函数定义界面,如setupUI()函数,定义界面中的各个控件。开发时可参照Qt的PySide6官方文档,例如程序中关于PySide6.QtCore.Qt的相关描述

from functools import partial
import sys  
import PySide6.QtCore
from PySide6.QtWidgets import QApplication,QWidget,QLabel,QPushButton,QMessageBox

def showInfo(window):
    QMessageBox.information(window, "提示信息", "这是用函数定义的界面。")

def setupUi(window):   #形参window是一个窗口实例对象
    window.setWindowTitle('用函数定义界面')  #设置窗口标题
    window.resize(300, 150)  #设置窗口尺寸

    label = QLabel(window)   #在窗口上创建标签
    label.setText('使用函数定义界面中的控件!')
    label.setGeometry(80, 50, 150, 20)  #设置标签在窗口中的位置和标签的宽度和高度

    dlgButton = QPushButton(window)    #创建一个弹窗按钮
    dlgButton.setText("弹 框")  #定义按钮文字
    dlgButton.setGeometry(80, 100, 50, 20)  #设置按钮在窗口中的位置(x, y坐标)和宽度、高度
    dlgButton.clicked.connect(partial(showInfo, window)) #关联按钮事件,使用偏函数(functools.partial)传参
    # dlgButton.clicked.connect(lambda: showInfo(window)) #关联按钮事件,使用lambda表达式传参


    button = QPushButton(window)  #在窗口上创建按钮
    button.setText("关 闭")
    button.setGeometry(170, 100, 50, 20) #设置按钮在窗口中的位置和按钮的宽度和高度
    button.clicked.connect(window.close)  #按钮事件与窗口事件的关联
if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = QWidget()
    myWindow.setWindowFlags(myWindow.windowFlags() & ~PySide6.QtCore.Qt.WindowMaximizeButtonHint 
                            | PySide6.QtCore.Qt.WindowCloseButtonHint)   #禁用最大化按钮
    setupUi(myWindow)   #调用setupUi()函数,并把窗口作为实参传递给setupUi()函数
    myWindow.show()
    sys.exit(app.exec())

在这里插入图片描述
在这里插入图片描述

用类定义界面

通过一个类来定义窗体界面,控件是类的属性,setupUI()则作为其中一个函数(实例方法)存在。

实例方法(instance method)、类方法(class method)与静态方法(static method)


实例方法:没有前置装饰器,其第一个参数应该是self,引用对象本身;


类方法:前置装饰器为@classmethod,其第一个参数应该是cls(或者其它,只要不是保留字class就行),引用类本身;


静态方法:前置装饰器为@staticmethod,其第一个参数不能是对象或类。

import sys 
from PySide6.QtWidgets import QApplication,QWidget,QLabel,QPushButton, QMessageBox

class MyUi():  #定义MyUi类
    def setupUi(self, window):  # 定义方法,形参window是一个窗口实例对象
        window.setWindowTitle('用类定义界面')
        window.resize(300, 150)

        self.label = QLabel(window)  # 在窗口上创建标签
        self.label.setText('使用类定义界面中的控件!')
        self.label.setGeometry(80, 50, 150, 20)

        self.dlgButton = QPushButton(window)    #创建一个弹窗按钮
        self.dlgButton.setText("弹 框")  #定义按钮文字
        self.dlgButton.setGeometry(80, 100, 50, 20)  #设置按钮在窗口中的位置(x, y坐标)和宽度、高度

        self.button = QPushButton(window)  # 在窗口上创建按钮
        self.button.setText("关 闭")
        self.button.setGeometry(170, 100, 50, 20)
        #self.button.clicked.connect(window.close)

    def showInfo(self, window):
        QMessageBox.information(window, "提示信息", "这是用类定义的界面。")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = QWidget()

    ui = MyUi()  # 用MyUi类创建实例ui
    ui.setupUi(myWindow)  # 调用ui的方法setupUi(),并以窗口实例对象作为实参
    ui.button.setText("Close")  # 重新设置按钮上显示的文字
    ui.button.clicked.connect(myWindow.close)  # 窗口上的按钮事件与窗口事件关联
    ui.dlgButton.clicked.connect(lambda: ui.showInfo(myWindow)) # 与showInfo方法关联,采用lambda表达式传参

    myWindow.show()
    sys.exit(app.exec())

在这里插入图片描述
在这里插入图片描述

用模块定义界面

显然,对于界面设计,我们往往需要多种的控件,那么,这时候就需要采用模块的方式定义界面,举个例子,from PySide6.QtWidgets import QApplication,QWidget,QLabel,QPushButton, QMessageBox就是引用PySide的QtWidgets模块来定义一个界面。我们可以将上述的的MyUI类作为一个模块中的类引用。

我们把`MyUI`类定义到`my_ui.py`文件中:
from PySide6.QtWidgets import QApplication,QWidget,QLabel,QPushButton, QMessageBox

class MyUi():  # 定义MyUi类,对于python 3,类默认继承object,对于python 2,若需要类继承object,则要显式声明,即MyUI(object)
    def setupUi(self, window):  # 定义方法,形参window是一个窗口实例对象
        window.setWindowTitle('用模块定义界面')
        window.resize(300, 150)

        self.label = QLabel(window)  # 在窗口上创建标签
        self.label.setText('使用模块定义界面中的控件!')
        self.label.setGeometry(80, 50, 150, 20)

        self.dlgButton = QPushButton(window)    # 创建一个弹窗按钮
        self.dlgButton.setText("弹 框")  # 定义按钮文字
        self.dlgButton.setGeometry(80, 100, 50, 20)  # 设置按钮在窗口中的位置(x, y坐标)和宽度、高度

        self.button = QPushButton(window)  # 在窗口上创建按钮
        self.button.setText("关 闭")
        self.button.setGeometry(170, 100, 50, 20)

    def showInfo(self, window):
        QMessageBox.information(window, "提示信息", "这是用模块定义的界面。")

值得注意的是,python的版本会影响到类继承关系和模块定义的方式方法。以python 3为例,类默认继承自object,但对于python 2,若要求类继承object对象,需要在类中显式继承,如:

from PySide6.QtWidgets import QApplication,QWidget,QLabel,QPushButton, QMessageBox

class MyUi(object):  # 定义MyUi类
    def setupUi(self, window):  # 定义方法,形参window是一个窗口实例对象
        window.setWindowTitle('用模块定义界面')
        window.resize(300, 150)

        self.label = QLabel(window)  # 在窗口上创建标签
        self.label.setText('使用模块定义界面中的控件!')
        self.label.setGeometry(80, 50, 150, 20)

        self.dlgButton = QPushButton(window)    # 创建一个弹窗按钮
        self.dlgButton.setText("弹 框")  # 定义按钮文字
        self.dlgButton.setGeometry(80, 100, 50, 20)  # 设置按钮在窗口中的位置(x, y坐标)和宽度、高度

        self.button = QPushButton(window)  # 在窗口上创建按钮
        self.button.setText("关 闭")
        self.button.setGeometry(170, 100, 50, 20)

    def showInfo(self, window):
        QMessageBox.information(window, "提示信息", "这是用模块定义的界面。")

为了使Python程序更具伸缩性,可将模块组织成文件和模块层次,这就是package)。包就是含有.py文件的子目录,可以有多个层级。而对于python 3.3之前的版本,要将目录识别成包,还需要加一个名为__init__.py的文件,该文件可以为空。

接下来,我们调用这个自定义类:

import sys  
from PySide6.QtWidgets import QApplication, QWidget
from my_ui import MyUi  # 导入my_ui.py文件中的MyUi类

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = QWidget()

    ui = MyUi()  # 用MyUi类创建实例ui
    ui.setupUi(myWindow)  # 调用ui的方法setupUi(),并以窗口实例作为实参
    ui.button.setText("Close")  # 重新设置按钮上显示的文字
    ui.button.clicked.connect(myWindow.close)  # 窗口上的按钮事件与窗口事件关联
    ui.dlgButton.clicked.connect(lambda: ui.showInfo(myWindow))

    myWindow.show()
    sys.exit(app.exec())

运行效果如下:
在这里插入图片描述
在这里插入图片描述

界面与逻辑分离

与Web的前后端分离类似,定义界面的代码可以作为界面代码,实现控件动作的代码称为逻辑或业务代码。我们也可以采用函数、类的继承等方式将它们分离。

  • 用函数将界面代码和业务代码分离
import sys 
from PySide6.QtWidgets import QApplication, QWidget

from my_ui import MyUi  # 导入my_ui.py文件中的MyUi类

def myWidget(parent = None):
    widget = QWidget(parent) # 创建QWidget类的对象,调用QWidget类的__init__()函数
    ui = MyUi()  # 实例化myUi.py文件中的MyUi类
    ui.setupUi(widget)  # 调用MyUi类的setupUi(),以widget为实参传递给形参window
    ui.button.setText("Close")  # 重新设置按钮上显示的文字
    ui.button.clicked.connect(widget.close)  # 窗口上的按钮事件与窗口事件关联
    ui.dlgButton.clicked.connect(lambda: ui.showInfo(widget))

    return widget   # 函数的返回值是窗口实例对象
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = myWidget()  # 调用myWidget()函数,返回值是窗口实例对象
    myWindow.show()
    sys.exit(app.exec())
  • 用类的单继承方式实现界面代码和业务代码的分离
import sys 
from PySide6.QtWidgets import QApplication, QWidget
from my_ui import MyUi  # 导入my_ui.py文件中的MyUi类

class MyWidget(QWidget):  # 创建MyWindget类,父类是QWidget
    def __init__(self,parent = None):
        super().__init__(parent) # 初始化父类QWidget,self将是QWidget的窗口对象
        ui = MyUi()  # 实例化myUi.py文件中的MyUi类
        ui.setupUi(self)  # 调用MyUi的setupUi(),以self为实参传递给形参window
        ui.button.setText("Close")  # 重新设置按钮的显示文字
        ui.button.clicked.connect(self.close)  # 窗口上的按钮事件与窗口事件关联
        ui.dlgButton.clicked.connect(lambda: ui.showInfo(self))
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = MyWidget()  # 用MyWidget类创建窗口对象myWindow
    myWindow.show()
    sys.exit(app.exec())
  • 用类的多重继承方式实现界面代码和义务代码的分离
import sys  
from PySide6.QtWidgets import QApplication, QWidget
from my_ui import MyUi  # 从my_ui.py文件中导入MyUi类

class MyWidget(QWidget,MyUi):  # 创建MyWindget类,父类是QWidget和MyUi
    def __init__(self,parent = None):
        super().__init__(parent)  # 初始化父类QWidget,self是QWidget的窗口对象
        self.setupUi(self)  # 调用MyUi的setupUi(),以self为实参传递给形参window
        self.button.setText("Close")  # 重新设置按钮的显示文字
        self.button.clicked.connect(self.close)  # 窗口上的按钮事件与窗口事件关联
        self.dlgButton.clicked.connect(lambda: self.showInfo(self))
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWindow = MyWidget()  # 用MyWidget类创建窗口对象myWindow
    myWindow.show()
    sys.exit(app.exec())
  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Humbunklung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值