#devices.py
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
#-----------------------控制面板-----------------------------#
class FacePane(QWidget):
send_singal = Signal(int)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.init_ui()
def init_ui(self):
self.setFixedSize(250, 150)
self.btn_manual = QPushButton("手动", self)
self.btn_auto = QPushButton("自动", self)
self.btn_start = QPushButton("启动", self)
self.btn_stop = QPushButton("停止", self)
self.btn_manual.setGeometry(20, 20, 100, 40)
self.btn_auto.setGeometry(120, 20, 100, 40)
self.btn_start.setGeometry(20, 60, 100, 40)
self.btn_stop.setGeometry(120, 60, 100, 40)
#-------------------------组件类--------------------------------
'''
zt字:1个字节 SW
0:手自动 True :自动 False:手动
1:打开状态
2:关闭状态
3:故障
4:备用
5:备用
6:备用
7:备用
控制字: 1 个字节 CW
0:手自动切换
1:打开
2:关闭
3:备用
4:备用
5:备用
6:备用
7:备用
'''
class BaseDevices(QWidget):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.__sw:int = 0
self.__cw:int = 0
self.TageName = "控制阀门"
@property
def SW(self):
return self.__sw
@SW.setter
def SW(self, value):
self.__sw = value
self.update_status()
@property
def CW(self):
return self.__cw
@CW.setter
def CW(self, value:int):
self.__cw=value
def update_status(self):
"""根据条件刷新界面的具体实现方法,可以在这里添加详细逻辑"""
pass
class Fapt(BaseDevices):
singal = Signal(int)
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.facepane = FacePane()
self.brush_color = Qt.gray
self.__last_sw = None
def update_status(self):
if self.__last_sw == self.SW:
return
if self.SW>>0 & 1:
self.facepane.btn_manual.setStyleSheet("background-color:gray")
self.facepane.btn_auto.setStyleSheet("background-color:green")
else:
self.facepane.btn_manual.setStyleSheet("background-color:green")
self.facepane.btn_auto.setStyleSheet("background-color:gray")
style = "background-color:green" if self.SW>>1&1 else "background-color:gray"
self.facepane.btn_start.setStyleSheet(style)
style2 = "background-color:green" if self.SW >> 2 & 1 else "background-color:gray"
self.facepane.btn_stop.setStyleSheet(style2)
self.update()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing,1)
if self.SW >>0 & 1: #该字第0位
painter.drawText(self.width()//2-10,self.height()//2+20,"自动")
else:
painter.drawText(self.width() // 2 -10, self.height() // 2+20, "手动")
if self.SW>>1&1: self.brush_color = Qt.green #第1位 打开状态
if self.SW>>2&1: self.brush_color = Qt.gray #第2位 关闭状态
if self.SW >>3&1: self.brush_color = Qt.red # 第2位 故障
painter.setBrush(self.brush_color)
path = QPainterPath()
path.moveTo(0,0)
path.lineTo(0,self.height()-11)
path.lineTo(self.width()-1,0)
path.lineTo(self.width()-1,self.height()-11)
path.closeSubpath()
painter.drawPath(path)
self.__last_sw = self.SW
#--------------------------------------------------------------------------------------------------
def contextMenuEvent(self, event):
self.facepane.show()
#按下
self.facepane.btn_manual.pressed.connect(self.on_press_slot)
self.facepane.btn_auto.pressed.connect(self.on_press_slot)
self.facepane.btn_start.pressed.connect(self.on_press_slot)
self.facepane.btn_stop.pressed.connect(self.on_press_slot)
#释放
self.facepane.btn_manual.released.connect(self.on_release_slot)
self.facepane.btn_auto.released.connect(self.on_release_slot)
self.facepane.btn_start.released.connect(self.on_release_slot)
self.facepane.btn_stop.released.connect(self.on_release_slot)
#信号间传递
self.facepane.send_singal.connect(lambda value:self.singal.emit(value))
def on_press_slot(self):
sender = self.sender()
text = sender.text()
match text:
case "手动":
self.CW = self.CW | 0x01
case "自动":
self.CW = self.CW | 0x02
case"启动":
self.CW = self.CW | 0x04
case "停止":
self.CW = self.CW | 0x08
self.facepane.send_singal.emit(self.CW)
def on_release_slot(self):
sender = self.sender()
text = sender.text()
match text:
case "手动":
self.CW = self.CW & 0xfe
case "自动":
self.CW = self.CW & 0xfd
case"启动":
self.CW = self.CW & 0xfb
case "停止":
self.CW = self.CW & 0x07
self.facepane.send_singal.emit(self.CW)
通信封装simensS7.py
from snap7 import util,client
from loguru import logger
logger.add("output.log", format="{time} - {level} - {message}")
class Sinemens:
def __init__(self):
self.plc:client.Client = None
self.write_bytes = bytearray(10)
def connect(self):
self.plc = client.Client()
self.plc.set_connection_type(3)
self.plc.connect("192.168.5.20",0,1)
def disconnect(self):
if self.plc is not None:
self.plc.disconnect()
def read_data(self)->int:
self.bytes = self.plc.db_read(1,0,20)
return util.get_byte(self.bytes,0)
def write_data(self,value:int):
util.set_byte(self.write_bytes,0,value)
try:
self.plc.db_write(1,10,self.write_bytes)
except Exception as e:
logger.debug(f"写入错误{e}")
test.py
import time
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
from devices import Fapt
from simensS7 import Sinemens
class Window(QWidget):
def __init__(self):
super().__init__()
self.resize(600,600)
self.simens = Sinemens()
self.fapt = Fapt(self)
self.fapt.singal.connect(self.on_fatp_slot)
self.fapt.setGeometry(20,20,100,100)
self.btn = QPushButton("btn",self)
self.btn.setGeometry(50,200,80,30)
self.btn2 = QPushButton("btn", self)
self.btn2.setGeometry(150, 200, 80, 30)
self.btn.clicked.connect(self.on_btn1_click)
self.btn2.clicked.connect(self.on_btn2_click)
self.t = threading.Thread(target=self.task,args=(self,),daemon=True)
def task(self,win):
while True:
data = win.simens.read_data()
win.fapt.SW = data
time.sleep(0.5)
def on_fatp_slot(self,value):
self.simens.write_data(value)
def on_btn1_click(self):
self.simens.connect()
self.t.start()
def on_btn2_click(self):
self.simens.disconnect()
if __name__ == '__main__':
# 创建一个应用程序实例
app = QApplication(sys.argv)
# 创建一个顶层窗口
window = Window()
# 显示窗口
window.show()
# 进入应用程序的主循环,等待事件处理
sys.exit(app.exec()