pyqt实现星三角减压启动

这个对于plc上实现是非常容易得。它本来就是逻辑控制器,如果用代码实现它,该怎么做呢?这个实现起来看似简单,实则是有不少坑的(大神除外)。我一直想用类来封装,让它继承QObject,为啥非要继承QObject,而不集成python自己的object,因为在Qobject里有自己的定时器,这样就容易实现定时功能啦。开始我想把这个类都放在一个大定时器里或线程里,发现这个会不停地执行,如果要去处理,又有加入不少逻辑,看起来很不爽。解决方案是界面里放个定时器,它的功能就是监控状态,并对状态做出处理,如更新界面,对下位机做出处理。先设计两个类Input,InOut两个类,InPut类用来接受,比如启动,停止,设置时间间隔等,Inout类用来对plc进行输出控制,代码如下:

输入类:

class InPut:
    __slots__=["start","stop","fault","interval"]
    def __init__(self,start:bool=None,stop:bool=None,fault:bool=None,timeflag:bool = None,interval:int = 3000):
        self.start: bool = start
        self.stop: bool = stop
        self.fault: bool = fault
        self.interval: bool = interval

输入输出类:

class InOut:
    def __init__(self,mainout,starout,tranout,byte:bytearray):
        '''
           :param mainout:
           :param starout:
           :param tranout:
           :param byte:
        '''
        self.__mainout = mainout
        self.__starout = starout
        self.__tranout = tranout
        self.__byte = byte
    def main_out_state(self):return self.get_bool(self.__byte,self.__mainout//8,self.__mainout%8)
    def star_out_state(self):return self.get_bool(self.__byte,self.__starout//8,self.__starout%8)
    def tran_out_state(self):return self.get_bool(self.__byte,self.__tranout//8,self.__tranout%8)

    def set_main_out(self,val):self.set_bool(self.__byte,self.__mainout//8,self.__mainout%8,val)
    def set_star_out(self,val):self.set_bool(self.__byte,self.__starout//8,self.__starout%8,val)
    def set_tran_out(self,val):self.set_bool(self.__byte,self.__tranout//8,self.__tranout%8,val)
    @staticmethod
    def get_bool(bytearray_: bytearray, byte_index: int, bool_index: int) -> bool:
        index_value = 1 << bool_index
        byte_value = bytearray_[byte_index]
        current_value = byte_value & index_value
        return current_value == index_value
    @classmethod
    def set_bool(cls,bytearray_: bytearray, byte_index: int, bool_index: int, value: bool):
        if value not in {0, 1, True, False}:
            raise TypeError(f"Value value:{value} is not a boolean expression.")
        current_value = cls.get_bool(bytearray_, byte_index, bool_index)
        index_value = 1 << bool_index

        # check if bool already has correct value
        if current_value == value:
            return
        if value:
            # make sure index_v is IN current byte
            bytearray_[byte_index] += index_value
        else:
            # make sure index_v is NOT in current byte
            bytearray_[byte_index] -= index_value

下面是降压启动类;


class Motor(QObject):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.flag = False

    def startStop(self,input:InPut,inout: InOut):
        if input.start:
            print("启动条件满足",not inout.main_out_state(),not inout.star_out_state(),not input.fault)
            if all([not inout.main_out_state(),not inout.star_out_state(),not inout.tran_out_state(),not input.fault]):
                inout.set_main_out(True)
                inout.set_star_out(True)
                inout.set_tran_out(False)
                print("星启动")

            if inout.main_out_state() and inout.star_out_state():
                self.time_id = self.startTimer(input.interval)
                self.flag = True
                print("定时器启动")
        if input.stop:
            if self.flag:
                self.killTimer(self.time_id)
            inout.set_main_out(False)
            inout.set_star_out(False)
            inout.set_tran_out(False)
            print("停止")
        self.inout = inout

    def checkState(self,input:InPut,inout: InOut):
        if input.fault:
            inout.set_main_out(False)
            inout.set_star_out(False)
            inout.set_tran_out(False)
            print("故障停止")



    def timerEvent(self, event):
        self.inout.set_star_out(False)
        self.inout.set_tran_out(True)
        self.killTimer(self.time_id)
        self.flag = False
        print("三角启动")

下面是对该类进行测试:



from PySide6.QtWidgets import *
from PySide6.QtCore import *
from snap7 import util



class Ui_Form(object):
    def setupUi(self, Form):
        if not Form.objectName():
            Form.setObjectName(u"Form")
        Form.resize(848, 447)
        self.btn_start = QPushButton(Form)
        self.btn_start.setObjectName(u"btn_start")
        self.btn_start.setGeometry(QRect(70, 50, 75, 23))
        self.btn_stop = QPushButton(Form)
        self.btn_stop.setObjectName(u"btn_stop")
        self.btn_stop.setGeometry(QRect(70, 90, 75, 23))
        self.formLayoutWidget = QWidget(Form)
        self.formLayoutWidget.setObjectName(u"formLayoutWidget")
        self.formLayoutWidget.setGeometry(QRect(420, 30, 211, 211))
        self.formLayout = QFormLayout(self.formLayoutWidget)
        self.formLayout.setObjectName(u"formLayout")
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.lab1 = QLabel(self.formLayoutWidget)
        self.lab1.setObjectName(u"lab1")

        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.lab1)

        self.lab2 = QLabel(self.formLayoutWidget)
        self.lab2.setObjectName(u"lab2")

        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.lab2)

        self.lab3 = QLabel(self.formLayoutWidget)
        self.lab3.setObjectName(u"lab3")

        self.formLayout.setWidget(2, QFormLayout.FieldRole, self.lab3)

        self.lab4 = QLabel(self.formLayoutWidget)
        self.lab4.setObjectName(u"lab4")

        self.formLayout.setWidget(3, QFormLayout.FieldRole, self.lab4)


        self.retranslateUi(Form)
        self.btn_start.clicked["bool"].connect(Form.btn_start_click)
        self.btn_stop.clicked.connect(Form.btn_stop_click)

        QMetaObject.connectSlotsByName(Form)
    # setupUi

    def retranslateUi(self, Form):
        Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
        self.btn_start.setText(QCoreApplication.translate("Form", u"START", None))
        self.btn_stop.setText(QCoreApplication.translate("Form", u"STOP", None))
        self.lab1.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab2.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab3.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab4.setText(QCoreApplication.translate("Form", u"TextLabel", None))
    # retranslateUi


class Ui(QWidget,Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.bytes = bytearray(1)
        self.input = InPut()
        self.inout = InOut(0,1,2,self.bytes)
        self.motor = Motor()
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.on_timer)
        self.timer.start(200)

    def on_timer(self):
        self.motor.checkState(self.input,self.inout)

        tex1="主接触器启动" if self.inout.main_out_state() else "主接触器停止"
        self.lab1.setText(tex1)

        tex2 = "星接触器启动" if self.inout.star_out_state() else "星接触器停止"
        self.lab2.setText(tex2)

        tex3 = "三角接触器启动" if self.inout.tran_out_state() else "三角接触器停止"
        self.lab3.setText(tex3)

        tex4 = "设备正常" if not self.input.fault else "设备故障"
        self.lab4.setText(tex4)

        print(self.bytes)


    def btn_start_click(self):
        self.input.start = True
        self.input.stop = False
        self.motor.startStop(self.input,self.inout)


    def btn_stop_click(self):
        self.input.start = False
        self.input.stop = True
        self.motor.startStop(self.input, self.inout)

    def btn_main_click(self,state):
        util.set_bool(self.bytes,0,0,state)
        print("main",state)

    def btn_star_click(self,state):
        util.set_bool(self.bytes, 0, 1, state)
        self.input.timeflag = state
        print("star", state)

    def btn_tran_click(self,state):
        util.set_bool(self.bytes, 0, 2, state)
        print("tran", state)
    def le_enter_event(self):
        ...
    def btn_fault_click(self,state):
        self.input.fault=state
        print("fault",state)


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

    win = Ui()
    win.show()

    sys.exit(app.exec())





 运行结果:

上面代的motor类再次优化一下,这样更简洁。代码复制后可以直接测试

from PySide6.QtCore import QObject
class InOut:
    def __init__(self,mainout,starout,tranout,byte:bytearray):
        '''
           :param mainout:
           :param starout:
           :param tranout:
           :param byte:
        '''
        self.__mainout = mainout
        self.__starout = starout
        self.__tranout = tranout
        self.__byte = byte
    def main_out_state(self):return self.get_bool(self.__byte,self.__mainout//8,self.__mainout%8)
    def star_out_state(self):return self.get_bool(self.__byte,self.__starout//8,self.__starout%8)
    def tran_out_state(self):return self.get_bool(self.__byte,self.__tranout//8,self.__tranout%8)

    def set_main_out(self,val):self.set_bool(self.__byte,self.__mainout//8,self.__mainout%8,val)
    def set_star_out(self,val):self.set_bool(self.__byte,self.__starout//8,self.__starout%8,val)
    def set_tran_out(self,val):self.set_bool(self.__byte,self.__tranout//8,self.__tranout%8,val)
    @staticmethod
    def get_bool(bytearray_: bytearray, byte_index: int, bool_index: int) -> bool:
        index_value = 1 << bool_index
        byte_value = bytearray_[byte_index]
        current_value = byte_value & index_value
        return current_value == index_value
    @classmethod
    def set_bool(cls,bytearray_: bytearray, byte_index: int, bool_index: int, value: bool):
        if value not in {0, 1, True, False}:
            raise TypeError(f"Value value:{value} is not a boolean expression.")
        current_value = cls.get_bool(bytearray_, byte_index, bool_index)
        index_value = 1 << bool_index

        # check if bool already has correct value
        if current_value == value:
            return
        if value:
            # make sure index_v is IN current byte
            bytearray_[byte_index] += index_value
        else:
            # make sure index_v is NOT in current byte
            bytearray_[byte_index] -= index_value

class InPut:
    __slots__=["start","stop","fault","interval"]
    def __init__(self,start:bool=None,stop:bool=None,fault:bool=None,timeflag:bool = None,interval:int = 3000):
        self.start: bool = start
        self.stop: bool = stop
        self.fault: bool = fault
        self.interval: bool = interval


class Motor(QObject):
    def __init__(self,intput:InPut=None,inout:InOut=None,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.flag = False
        self.input: InPut = intput
        self.inout: InOut = inout

    def startStop(self):
        if self.input.start:
            print("启动条件满足",not self.inout.main_out_state(),not self.inout.star_out_state(),not self.input.fault)
            if all([not self.inout.main_out_state(),not self.inout.star_out_state(),not self.inout.tran_out_state(),not self.input.fault]):
                self.inout.set_main_out(True)
                self.inout.set_star_out(True)
                self.inout.set_tran_out(False)
                print("星启动")

            if self.inout.main_out_state() and self.inout.star_out_state():
                self.time_id = self.startTimer(self.input.interval)
                self.flag = True
                print("定时器启动")
        if self.input.stop:
            if self.flag:
                self.killTimer(self.time_id)
            self.inout.set_main_out(False)
            self.inout.set_star_out(False)
            self.inout.set_tran_out(False)
            print("停止")


    def checkState(self):
        if self.input.fault:
            self.inout.set_main_out(False)
            self.inout.set_star_out(False)
            self.inout.set_tran_out(False)
            print("故障停止")

    def timerEvent(self, event):
        self.inout.set_star_out(False)
        self.inout.set_tran_out(True)
        self.killTimer(self.time_id)
        self.flag = False
        print("三角启动")



from PySide6.QtWidgets import *
from PySide6.QtCore import *
from snap7 import util



class Ui_Form(object):
    def setupUi(self, Form):
        if not Form.objectName():
            Form.setObjectName(u"Form")
        Form.resize(848, 447)
        self.btn_start = QPushButton(Form)
        self.btn_start.setObjectName(u"btn_start")
        self.btn_start.setGeometry(QRect(70, 50, 75, 23))
        self.btn_stop = QPushButton(Form)
        self.btn_stop.setObjectName(u"btn_stop")
        self.btn_stop.setGeometry(QRect(70, 90, 75, 23))
        self.formLayoutWidget = QWidget(Form)
        self.formLayoutWidget.setObjectName(u"formLayoutWidget")
        self.formLayoutWidget.setGeometry(QRect(420, 30, 211, 211))
        self.formLayout = QFormLayout(self.formLayoutWidget)
        self.formLayout.setObjectName(u"formLayout")
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.lab1 = QLabel(self.formLayoutWidget)
        self.lab1.setObjectName(u"lab1")

        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.lab1)

        self.lab2 = QLabel(self.formLayoutWidget)
        self.lab2.setObjectName(u"lab2")

        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.lab2)

        self.lab3 = QLabel(self.formLayoutWidget)
        self.lab3.setObjectName(u"lab3")

        self.formLayout.setWidget(2, QFormLayout.FieldRole, self.lab3)

        self.lab4 = QLabel(self.formLayoutWidget)
        self.lab4.setObjectName(u"lab4")

        self.formLayout.setWidget(3, QFormLayout.FieldRole, self.lab4)


        self.retranslateUi(Form)
        self.btn_start.clicked["bool"].connect(Form.btn_start_click)
        self.btn_stop.clicked.connect(Form.btn_stop_click)

        QMetaObject.connectSlotsByName(Form)
    # setupUi

    def retranslateUi(self, Form):
        Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
        self.btn_start.setText(QCoreApplication.translate("Form", u"START", None))
        self.btn_stop.setText(QCoreApplication.translate("Form", u"STOP", None))
        self.lab1.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab2.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab3.setText(QCoreApplication.translate("Form", u"TextLabel", None))
        self.lab4.setText(QCoreApplication.translate("Form", u"TextLabel", None))
    # retranslateUi


class Ui(QWidget,Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.btn_fault = QPushButton("故障测试",self)
        self.btn_fault.setCheckable(True)
        self.btn_fault.move(100,200)
        self.btn_fault.clicked[bool].connect(self.btn_fault_click)

        self.bytes = bytearray(1)
        input = InPut()
        inout = InOut(0,1,2,self.bytes)
        self.motor = Motor(input,inout)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.on_timer)
        self.timer.start(200)

    def on_timer(self):
        self.motor.checkState()

        tex1="主接触器启动" if self.motor.inout.main_out_state() else "主接触器停止"
        self.lab1.setText(tex1)

        tex2 = "星接触器启动" if self.motor.inout.star_out_state() else "星接触器停止"
        self.lab2.setText(tex2)

        tex3 = "三角接触器启动" if self.motor.inout.tran_out_state() else "三角接触器停止"
        self.lab3.setText(tex3)

        tex4 = "设备正常" if not self.motor.input.fault else "设备故障"
        self.lab4.setText(tex4)

        print(self.bytes)


    def btn_start_click(self):
        self.motor.input.start = True
        self.motor.input.stop = False
        self.motor.startStop()


    def btn_stop_click(self):
        self.motor.input.start = False
        self.motor.input.stop = True
        self.motor.startStop()




    def btn_fault_click(self,state):
        self.motor.input.fault=state
        print("fault",state)






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

    win = Ui()
    win.show()

    sys.exit(app.exec())





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/546045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么MySQL数据库超过2000万条数据,查询依然很快:B+树和数据页结构解析

MYSQL数据库单表建议最大2000万条数据&#xff0c;很多人都说如果超过了2000万条数据&#xff0c;性能就会下降的特别厉害。但是你实际上存储后&#xff0c;发现即使超过了2000万但是查询依旧很快&#xff0c;这是为什么&#xff1f; Mysql为了查询速度&#xff0c;内部使用了…

私域流量变现干货:轻松盘活,高效增长!

你知道如何增长私域流量并将这些流量转化为实际收益&#xff0c;让我们的品牌价值最大化吗&#xff1f; 今天&#xff0c;就分享几点干货&#xff0c;帮助大家盘活私域流量&#xff0c;实现高效增长&#xff01; 1、精准定位和用户画像 首先&#xff0c;了解您的私域流量源于…

JavaWeb开发03-Mybatis入门-基础操作-XML映射文件-动态SQL

一、Mybatis-入门 Java程序控制数据库 1.入门 定义实体类&#xff1a;一定要和表中的字段一一对应 配置连接数据库数据 建立Mapper层语句&#xff0c;来获取数据库数据以及将其封装到user的list中去。 2.配置SQL提示 为了进行查询数据库中有哪些表&#xff0c;所以得连接数据…

详解IP证书申请

申请IP证书&#xff0c;也被称为IP SSL证书&#xff0c;是一种特殊的SSL证书&#xff0c;它不同于传统的域名验证&#xff08;DV&#xff09;证书&#xff0c;是通过验证公网IP地址而不是域名来确保安全连接。这种证书用于保护IP地址&#xff0c;并在安装后起到加密作用。以下是…

VTK —— 一、Windows10下编译VTK源码,并用Vs2017代码测试(附编译流程、附编译好的库、vtk测试源码)

效果 编译 1、下载VTK8.2.0源码        2、解压源码后&#xff0c;进入目录创建build目录&#xff0c;同时在build内创建install目录 (下图install目录是在cmake第一次后才手动创建&#xff0c;建议在创建build时创建)        3、打开CMake&#xff0c;如下图填入…

CSS 这就是一个按照我看到的css ,边用边总结的笔记~

margin 和 paddingdisplay外部表现类(display-outside) : block , inline内部表现类(display-inside) : flex,gird,table,flow,flow-root,ruby margin 和 padding 可以设置1~4个属性 属性个数属性值1一起设置 上下左右2分别设置 上下 , 左右3分别设置 上 , 左右 , 下4分别设置…

戏作打油诗《无知》

笔者经营多年的《麻辣崇州论坛》&#xff0c;半月前突被攻击我在“霸屏”&#xff0c;没处讲理&#xff0c;特戏作打油诗《无知》一首&#xff0c;为那个无理取闹、砸我“麻辣崇州论坛”的无知小儿画像如下。 请点击链接&#xff0c;一目了然&#xff1a;崇州论坛-麻辣社区 没…

Gemini国内怎么使用

GPT、Claude、Gemini全系列模型国内使用方法来了&#xff01; 一直以来很多人问我能不能有个稳定&#xff0c;不折腾的全球AI大模型测试网站&#xff0c;既能够保证真实靠谱&#xff0c;又能够保证稳定、快速&#xff0c;不要老动不动就挂了、出错或者漫长的响应。 到目前为止…

Android T多屏多显——应用双屏间拖拽移动功能(更新中)

功能以及显示效果简介 需求&#xff1a;在双屏显示中&#xff0c;把启动的应用从其中一个屏幕中移动到另一个屏幕中。 操作&#xff1a;通过双指按压应用使其移动&#xff0c;如果移动的距离过小&#xff0c;我们就不移动到另一屏幕&#xff0c;否则移动到另一屏。 功能分析…

基于Python的微博舆论分析,微博评论情感分析可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

ARM/X86+FPGA轨道交通/工程车辆行业的解决方案

深圳推出首条无人驾驶地铁—深圳地铁20号线&#xff0c;可以说是深圳地铁的一次开创性的突破。智能交通不断突破的背后&#xff0c;需要很严格的硬件软件等控制系 统&#xff1b;地铁无人驾驶意味着信号系统、通信系统、综合监控系统、站台屏蔽门工程等项目必须严格执行验收。…

上位机图像处理和嵌入式模块部署(用树莓派4b开发固件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 嵌入式开发的领域其实很广&#xff0c;有上位机、驱动和bsp移植。较早之前&#xff0c;由于自己曾经在芯片公司上班&#xff0c;所以对uboot、linu…

ARM汇编指令、指令中s后缀的作用、N、Z、C、V位有什么作用、ARM汇编启动代码

ARM汇编指令 学习arm汇编的主要目的是为了编写arm启动代码,启动代码启动以后,引导程序到c语言环境下允许。换句话说启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。因此启动代码的主要任务有: 初始化异常向量表; 初始化各工作模式的栈指针寄存器; 开启arm…

如何通过Linux pciehp sysfs接口控制PCIe Slot电源状态?-2

NVME SSD电源状态判断 通过pciehp sysfs接口对NVMe SSD所在的PCIe插槽进行Power On/Off操作时&#xff0c;确实会间接影响到NVMe SSD本身的电源状态。因为NVMe SSD是作为PCIe设备连接到特定插槽上的&#xff0c;插槽电源状态的变化通常会直接影响到与其相连的设备。 当对PCIe…

网络篇12 | 链路层 ARP

网络篇12 | 链路层 ARP 01 简介1&#xff09;工作过程2&#xff09;ARP缓存2.1 动态ARP表项2.2 静态ARP表项2.3 短静态ARP表项2.4 长静态ARP表项 02 ARP报文格式1&#xff09;ARP请求报文格式2&#xff09;ARP响应报文格式3&#xff09;套一层以太网帧&#xff08;ARP帧&#x…

史上最全excel导入功能测试用例设计(以项目为例)

web系统关于excel的导入导出功能是很常见的&#xff0c;通常为了提高用户的工作效率&#xff0c;在维护系统中的一些数据的时候&#xff0c;批量导入往往比一个一个添加或者修改快很多。针对导入功能的测试&#xff0c;往往会有很多种情况&#xff0c;现在针对平时项目中遇到的…

灰度部署、滚动部署与蓝绿部署

前言 最近在进行单元化建设方面的的工作&#xff0c;其中涉及服务分组和蓝绿发布相关的概念&#xff0c;在这里总结一下了解到的相关知识。 版本更新策略 功能开关 在应用逻辑里内置功能开关&#xff0c;通过开关的打开关闭来决定执行新旧逻辑&#xff0c;无需路由机制支持…

使用DockerCompose配置基于哨兵模式的redis主从架构集群

文章目录 一、注意事项&#xff08;坑点&#xff01;&#xff01;&#xff01;&#xff09;二、配置Redis主从架构集群第一步&#xff1a;创建目录文件结构第二步&#xff1a;编写DockerCompose配置文件第三步&#xff1a;编写redis.conf第四步&#xff1a;启动redis主从集群 三…