Bootstrap

试试用pyqt做一个上位机软件,但愿不会烂尾(六):使用“提升为”来实现自定义部件

前面的从模板页面拖动部件到新页面的方法还是有缺陷,在主函数里面还是要对部件进行单独的功能定义,而且如果有多个相同部件,就有可能需要重复多个相同的代码。查阅了pyqt教程以后,用“提升为”就可以实现自定义部件的功能。

1、打开pycharm,新建工程scada1,新建主函数project1.py

1、打开QTdesigner,新建test1.ui。拖入一个灰色指示灯,命名为lamp

 2、pycharm新建lamp.py文件,输入以下代码:

from PyQt5.QtWidgets import QLabel


class lamp(QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.blink = False
        self.style = ''        

    def set_color(self, color):     # 设置颜色
        if not self.blink:
            self.style = 'border-radius:{rad}px;background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, ' \
                         'radius:0.5, fx:0.369, fy:0.382, stop:0 rgba(255, 255, 255, 255), stop:0.238636 {colour});' \
                         'border:1px solid black;'.format(rad=str(round(self.width() / 2)), colour=color)
            self.setStyleSheet(self.style)

    def set_blink(self):       # 启动闪烁
        self.style = self.styleSheet()
        self.blink = True

    def reset_blink(self):    # 停止闪烁
        self.blink = False
        self.setStyleSheet(self.style)

    def blinker(self, color1, color2, bool_in):      # 执行闪烁
        if not self.blink:
            return False
        if bool_in:
            self.setStyleSheet('border-radius:{rad}px;background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.369, fy:0.382, stop:0 rgba(255, 255, 255, 255), stop:0.238636 {colour}); border:1px solid black;'.format(rad=str(round(self.width() / 2)), colour=color1))
        else:
            self.setStyleSheet( 'border-radius:{rad}px;background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.369, fy:0.382, stop:0 rgba(255, 255, 255, 255), stop:0.238636 {colour}); border:1px solid black;'.format(rad=str(round(self.width() / 2)), colour=color2))



3、回到QTdesigner,右键点击指示灯lamp:“提升为”

 4、输入自定义的lamp的头文件和类名称,点击“添加”、“提升”:这里的文件名是小写字母,大写会出错。

 5、新建几个按钮,分别命名为:btnr、btng、btnk

 6、回到主函数project1.py,输入以下代码:

# 这个是主函数
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import uic
from ClockPulse import Clocker  # 自定义的周期脉冲函数,默认参数下周期为1s


class UiObject(QObject):  # 定义一个Object
    def __init__(self):
        super().__init__()
        self.form1 = uic.loadUi('test1.ui')  # 导入ui
        self.StartToDo.do1(self.form1)  # 初始化
        self.connections()   # 动作连接

    # 各种信号的连接
    def connections(self):
        # 周期时钟的连接
        timer_05s.timeout.connect(self.JobEvents.timer_05s_timeout)
        # 画面1中的操作器件动作的连接
        self.form1.btnr.clicked.connect(self.JobEvents.f1_btnr_clicked)
        self.form1.btng.clicked.connect(self.JobEvents.f1_btng_clicked)
        self.form1.btnk.clicked.connect(self.JobEvents.f1_btnk_clicked)

    # 各个窗体的初始化

    class StartToDo:
        @staticmethod
        def do1(in_form):  # 窗体初始化
            in_form.setWindowFlags(Qt.FramelessWindowHint)  # 关掉边框

    # 响应事件
    class JobEvents():
        @staticmethod
        def f1_btnr_clicked():
            ui.form1.lamp.set_color('red')
            # pass

        @staticmethod
        def f1_btng_clicked():
            ui.form1.lamp.set_color('green')
            # pass

        @staticmethod
        def f1_btnk_clicked():
            if not ui.form1.lamp.blink:      # 切换指示灯lamp的闪烁
                ui.form1.lamp.set_blink()
            else:
                ui.form1.lamp.reset_blink()


        @staticmethod
        def timer_05s_timeout():
            ui.form1.lamp.blinker('red', 'yellow', timer_05s.bool)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    timer_1s = Clocker()  # 定义全局1s的周期定时器
    timer_05s = Clocker(500)  # 定义全局500ms的周期定时器
    ui = UiObject()  # object的本地实体化
    ui.form1.show()

    sys.exit(app.exec_())
运行效果:

 7、再搞个多态的按钮,可以实现多背景、多文字和闪烁功能,新建button,py,输入以下代码:

from PyQt5.QtWidgets import QPushButton


class button(QPushButton):
    """
    有多种组态的按钮,self.styles存放了各种组态的背景色和文字色以及文字内容
    其格式为   [背景色,文字颜色, 文字内容 ]
    使用之前需要初始化一下组态的内容
    调用时直接根据下标调用即可
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.blink = False
        self.styles = []
        self.style = ''
        self.n = 0

    def set_style(self, n):     # 设置颜色
        if not self.blink:
            self.style = 'background-color: {background};color: {colour};'.format(background=self.styles[n][0], colour=self.styles[n][1])
            self.setStyleSheet(self.style)
            self.setText(self.styles[n][2])

    def set_blink(self):       # 启动闪烁
        self.style = self.styleSheet()
        self.blink = True

    def reset_blink(self):    # 停止闪烁
        self.blink = False
        self.setStyleSheet(self.style)

    def blinker(self, color1, color2, bool_in):      # 执行闪烁
        if not self.blink:
            return False
        if bool_in:
            self.setStyleSheet('background-color: {background};color: {colour};'.format(background=color1, colour=color2))
        else:
            self.setStyleSheet('background-color: {background};color: {colour};'.format(background=color2, colour=color1))

    def togg(self):
        if not self.n == len(self.styles)-1:
            self.n += 1
        else:
            self.n = 0
            print(self.styles[0])
        self.set_style(self.n)

8、在test1.ui界面中加入2个按钮:

 用前面类似的方法将新增的2个按钮提升为新建的button.button:

9、写代码调用:

# 这个是主函数
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import uic, QtCore
from ClockPulse import Clocker  # 自定义的周期脉冲函数,默认参数下周期为1s


class UiObject(QObject):  # 定义一个Object
    def __init__(self):
        super().__init__()
        self.form1 = uic.loadUi('test1.ui')  # 导入ui
        self.StartToDo.do1(self.form1)  # 初始化

        self.connections()   # 动作连接

    # 各种信号的连接
    def connections(self):
        # 周期时钟的连接
        timer_05s.timeout.connect(self.JobEvents.timer_05s_timeout)
        # # 画面1中的操作器件动作的连接
        self.form1.pump_start.clicked.connect(self.JobEvents.f1_pump_start_clicked)
        self.form1.mode_press.clicked.connect(self.JobEvents.f1_mode_press_clicked)
        self.form1.btnr.clicked.connect(self.JobEvents.f1_btnr_clicked)
        self.form1.btng.clicked.connect(self.JobEvents.f1_btng_clicked)
        self.form1.btnk.clicked.connect(self.JobEvents.f1_btnk_clicked)

    # 各个窗体的初始化

    class StartToDo:
        @staticmethod
        def do1(in_form):  # 窗体初始化
            in_form.setWindowFlags(Qt.FramelessWindowHint)  # 关掉边框
            in_form.pump_start.styles = [['#e1e1e1', 'black', '油泵启动'], ['green', 'black', '油泵启动']]  # 对画面中的多态按钮进行初始化
            in_form.mode_press.styles = [['green', 'black', '双压模式'], ['red', 'yellow', '左压模式'], ['red', 'blue', '右压模式']]     # 对画面中的多态按钮进行初始化
    # 响应事件
    class JobEvents():
        @staticmethod
        def f1_btnr_clicked():
            ui.form1.lamp.set_color('red')
            # pass

        @staticmethod
        def f1_btng_clicked():
            ui.form1.lamp.set_color('green')
            # pass

        @staticmethod
        def f1_btnk_clicked():
            if not ui.form1.lamp.blink:
                ui.form1.lamp.set_blink()
            else:
                ui.form1.lamp.reset_blink()

        @staticmethod
        def timer_05s_timeout():
            ui.form1.mode_press.blinker('red', 'blue', timer_05s.bool)
            ui.form1.lamp.blinker('red', 'yellow', timer_05s.bool)

        @staticmethod
        def f1_slider1_valuechanged(var):
            ui.form1.progressbar1.value_changed(var)

        @staticmethod
        def f1_pump_start_clicked():
            ui.form1.pump_start.togg()  # 切换组态的子函数

        @staticmethod
        def f1_mode_press_clicked():
            ui.form1.mode_press.togg()  # 切换组态的子函数



if __name__ == '__main__':
    app = QApplication(sys.argv)
    timer_1s = Clocker()  # 定义全局1s的周期定时器
    timer_05s = Clocker(500)  # 定义全局500ms的周期定时器
    ui = UiObject()  # object的本地实体化
    ui.form1.show()

    sys.exit(app.exec_())
运行效果:

;