Pyside使用Qt Designer和uic工具的基本框架的demo

         搞了多年的工控,年过半百突然想要学习编程,单打独斗在黑暗中摸索,每获得一分收获都要付出几倍的艰辛。学习python一年有余,陆续做过了几个小工程,初步建立了适合自己的应用框架。阶段总结,备忘。同时虚心接受高手指点。

Pyside的基本框架,主要特点:

1、尽量使用Qt Designer组态界面,这符合工控人的使用习惯,从wincc、组态王等过来的,很容易接受。

2、功能代码和界面媒体前后端分离。

3、结构简单清晰,容易嫁接复制。

4、尽量使用较少的编程知识,避免陷入学习深渊。

实施过程:

1、按个人习惯创建文件夹目录,本次demo的结构为:

        这里的UIS是按照软件包创建的,软件包文件夹和普通文件夹的区别在于软件包文件夹的根目录下有__init__.py文件,即使__init__.py是空的。 

2、在Qt Designer里创建两个窗口画面,并存盘。命名为demo.ui和demo_2.ui.保存在UIS文件夹内。

3、使用pyuic工具将demo.ui和demo_2.ui转换为.py文件,得到了两个文件demo_rc.py和demo_2_rc.py。

4、修改UIS文件夹内__init__.py文件,内容如下:

from .demo_rc import *
from .demo_2_rc import *

 这个的含义是:我们已经把UIS创建为一个软件包,当在主脚本里通过from UIS import *时,__init__.py中列出的内容会被导入

5、创建主脚本main.py文件,调用。

main.py代码:

# encoding: utf-8
import os
import sys
from functools import partial

from PySide6.QtCore import Signal, QTimer

# 获取当前脚本的目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 将 UIS 文件夹的路径添加到 sys.path 中
uis_dir = os.path.join(current_dir, 'UIS')
sys.path.append(uis_dir)
from UIS import *


# 主画面类
class MainWindow(QMainWindow, demo_rc.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.run()   # 初始化

    # 主画面的初始化
    def run(self):
        self.move(200, 200)
        self.show()  # 显示画面
        self.btn_station = self.btn_group.children()  # 按钮站
        self.label_1.setText('0')
        self.label_2.setText('0')
        self.label_second.setText('0')
        self.btn_all.setProperty('activated', True)
        self.btn_all.setStyleSheet(self.btn_all.styleSheet())
        self.signal_slot()  # 信号和槽

    # 画面层面的信号和槽
    def signal_slot(self):
        # 按钮站的槽函数
        def buttons_clicked(button):  # 回调
            def one_btn_clicked():  # 闭包
                # 设置各个按钮的显示外观
                def set_styleSheet():
                    for b in self.btn_station:

                        if b != button:
                            b.setProperty('activated', False)
                        else:
                            b.setProperty('activated', True)
                        b.setStyleSheet(b.styleSheet())  # 刷新显示
                set_styleSheet()
                # 每个按钮的功能函数
                if button is self.btn_1:
                    self.frame_1.show()
                    self.frame_2.hide()
                elif button is self.btn_2:
                    self.frame_2.show()
                    self.frame_1.hide()
                elif button is self.btn_none:
                    self.frame_1.hide()
                    self.frame_2.hide()
                elif button is self.btn_all:
                    self.frame_1.show()
                    self.frame_2.show()
            return one_btn_clicked
        # 按钮站的信号连接
        for btn in self.btn_station:
            btn.clicked.connect(partial(buttons_clicked(btn)))

        # 滑块改变数值的槽函数
        def slider_1_valueChanged(value):
            ui.value_slider1.emit(value)  # 当滑块改变数值,项目级别的信号ui.Signal1发射
        # 滑块值改变的信号连接
        self.slider_1.valueChanged.connect(slider_1_valueChanged)

        # label_1的文字内容的槽函数
        def label_1_setText(x):
            self.label_1.setText(str(x))
        # label_1的文字内容信号连接
        ui.value_slider1.connect(label_1_setText)

        # label_2的文字内容的槽函数
        def label_2_setText(x):
            self.label_2.setText(str(x))
        # label_2的文字内容信号连接
        ui.value_slider1.connect(label_2_setText)

        # label_second的文字内容的槽函数
        def label_second_setText():
            self.label_second.setText(Jobs.Job_todo_2())
        # label_second的文字内容信号连接
        ui.secondSignal.connect(label_second_setText)

        # frame1的overFlow特性设定槽函数
        def frame1_set_overFlow(x):
            this = self.frame_1
            if x > 200:
                this.setProperty('overFlow', True)
            else:
                this.setProperty('overFlow', False)
            this.setStyleSheet(this.styleSheet())
        # frame1的overFlow特性设定信号连接
        ui.value_slider1.connect(frame1_set_overFlow)

        # 退出系统的槽函数
        def quit_system():
            Jobs.before_quit()
        self.btn_exit.clicked.connect(quit_system)


# Window2的画面类
class Window2(QMainWindow, demo_2_rc.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.run()

    # 初始化
    def run(self):
        self.move(500, 500)
        self.show()  # 显示画面
        self.label_1.setText('0')
        self.signal_slot()

    # 画面层面的信号和槽
    def signal_slot(self):
        def label_1_setText(x):
            self.label_1.setText(Jobs.Job_todo_1(x))
        ui.value_slider1.connect(label_1_setText)


# 一些作业函数和功能函数
class Jobs:
    @staticmethod
    def Job_todo_1(var):
        return str(var * 2)

    @staticmethod
    def Job_todo_2():
        ui.seconds += 1
        if ui.seconds == 60:
            ui.seconds = 0
        return str(ui.seconds)

    # 退出系统前的保存、清理、释放等操作
    @staticmethod
    def before_quit():
        if ui.windows:
            for w in ui.windows:
                w.close()


# 项目的定义
class UI(QObject):  # 将项目定义为QObject,用来管理项目级别的信号和变量
    value_slider1 = Signal(int)  # 这是一个项目级别的信号,对应于主窗口的滑块_slider1的值
    secondSignal = Signal()  # 这是一个项目级别的信号,每秒发出一个信号

    def __init__(self):
        super().__init__()
        self.timer = QTimer()   # 一个项目级别的定时器
        self.seconds = 0        # 读秒数
        self.run()              # 初始化

    # 项目的初始化
    def run(self):
        self.timer.start(1000)

        # 项目层面的信号和槽
        def signal_slot():
            # 秒信号的发射槽函数
            def secondSignal_emit():
                self.secondSignal.emit()
            # 秒信号的连接
            self.timer.timeout.connect(secondSignal_emit)

            # 退出系统之前的操作
            app.aboutToQuit.connect(Jobs.before_quit)
        signal_slot()


# #############################主程序##################################
if __name__ == '__main__':
    app = QApplication(sys.argv)
    # 项目的实例化
    ui = UI()
    ui.windows = []    # 所有用到的窗口

    # 初始化画面
    mainWindow = MainWindow()  # 主画面实例化
    ui.windows.append(mainWindow)
    window2 = Window2()        # window2画面实例化
    ui.windows.append(window2)

    sys.exit(app.exec())

另一个小demo

import sys
from functools import partial

from PySide6.QtCore import Signal, QObject
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QGroupBox


class MainWindow(QMainWindow):
    function_signal = Signal(object)

    def __init__(self):
        super().__init__()

        self.setFixedSize(300, 400)
        # 按钮群
        self.btn_group = QGroupBox(self)
        self.btn_group.setGeometry(50, 50, 200, 300)

        # 创建按钮
        self.button1 = QPushButton('功能1', self.btn_group)
        self.button1.setCheckable(True)
        self.button1.setGeometry(50, 50, 100, 50)
        self.button2 = QPushButton('功能2', self.btn_group)
        self.button2.setCheckable(True)
        self.button2.setGeometry(50, 120, 100, 50)
        self.button3 = QPushButton('功能3', self.btn_group)
        self.button3.setCheckable(True)
        self.button3.setGeometry(50, 190, 100, 50)
        # 槽和信号
        self.slot_signal()

    # 槽和信号
    def slot_signal(self):
        # 按钮站的定义
        self.btnStation = self.btn_group.children()

        # 按钮站的槽函数
        def slot_btn(btn):
            def set_check():
                for b in self.btnStation:
                    if b != btn:
                        b.setChecked(False)
                    else:
                        b.setChecked(True)
                if btn == self.button1:
                    self.function_signal.emit('功能1')
                    print('btn1 is clicked')
                elif btn == self.button2:
                    self.function_signal.emit('功能2')
                    print('btn2 is clicked')
                elif btn == self.button3:
                    self.function_signal.emit('功能3')
                    print('btn3 is clicked')

            return set_check

        for b in self.btnStation:
            b.clicked.connect(partial(slot_btn(b)))  # 连接信号到槽函数


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()



    sys.exit(app.exec())

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深蓝海拓

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

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

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

打赏作者

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

抵扣说明:

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

余额充值