试试用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_())
运行效果:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
可以使用PyModbus库和PyQt5库来实现Modbus通讯上位机。以下是一个简单的示例代码,可以作为参考: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QLineEdit, QTextEdit from PyQt5.QtCore import Qt from pymodbus.client.sync import ModbusTcpClient class MainWindow(QMainWindow): def __init__(self): super().__init__() # 创建GUI控件 self.label_ip = QLabel('IP地址:', self) self.label_ip.move(10, 10) self.edit_ip = QLineEdit('127.0.0.1', self) self.edit_ip.move(70, 10) self.label_port = QLabel('端口号:', self) self.label_port.move(10, 40) self.edit_port = QLineEdit('502', self) self.edit_port.move(70, 40) self.label_slave = QLabel('从站地址:', self) self.label_slave.move(10, 70) self.edit_slave = QLineEdit('1', self) self.edit_slave.move(70, 70) self.label_address = QLabel('起始地址:', self) self.label_address.move(10, 100) self.edit_address = QLineEdit('0', self) self.edit_address.move(70, 100) self.label_count = QLabel('数量:', self) self.label_count.move(10, 130) self.edit_count = QLineEdit('10', self) self.edit_count.move(70, 130) self.button_read = QPushButton('读取', self) self.button_read.move(10, 160) self.button_read.clicked.connect(self.on_read_clicked) self.text_result = QTextEdit('', self) self.text_result.move(10, 190) self.text_result.setReadOnly(True) def on_read_clicked(self): # 读取Modbus数据 client = ModbusTcpClient(self.edit_ip.text(), port=int(self.edit_port.text())) client.connect() result = client.read_holding_registers(int(self.edit_address.text()), int(self.edit_count.text()), unit=int(self.edit_slave.text())) client.close() # 显示结果 if result.isError(): self.text_result.setText('读取失败: %s' % result) else: values = result.registers self.text_result.setText('读取成功: %s' % values) if __name__ == '__main__': app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 上述代码中,我们创建了一个MainWindow类,包含了用于配置Modbus通讯参数和读取数据的GUI控件。当用户点击“读取”按钮时,程序会使用PyModbus库连接到指定的Modbus TCP从站,读取指定的寄存器数据,并在文本框中显示结果。 注意,这只是一个简单的示例代码,实际应用中还需要处理各种错误和异常情况,以确保程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深蓝海拓

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

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

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

打赏作者

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

抵扣说明:

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

余额充值