上位机编写软件:PyQt5
语言:python
第三方组件:Hslcommunication
PLC:西门子s-7 1200
首界面实现如下:
添加文件名
import datetime #添加时间插件模块
import sys #sys模块包含了与Python解释器和它的环境有关的函数
import threading #提供了一个比thread模块更高层的API来提供线程的并发性。这些线程并发运行并共享内存
import HslCommunication #添加hsl模块
from HslCommunication import SoftBasic, MelsecMcNet, MelsecMcAsciiNet, MelsecA1ENet, SiemensS7Net, SiemensPLCS, \
SiemensFetchWriteNet, OmronFinsNet, ModbusTcpNet, OperateResult, NetSimplifyClient #从hsl模块中添加PLC型号
from PyQt5 import QtWidgets, QtCore, QtGui #QtCore包含模块类的定义;QtGui为窗口系统集成,事件处理,,2D图形,基本图像,字体和文本提供类
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication, QMessageBox, QAction, QPushButton, QVBoxLayout, \
QLineEdit, QTextEdit #从QtWidgets和QtGui中引入用到的模块
from PyQt5.QtGui import QPalette, QFont, QIcon, QBrush, QColor, QPainter
定义一个WindowsLoad的类,其父类是QMainWindow,作为整个PLC首界面的一整个类
class WindowsLoad(QtWidgets.QMainWindow): #定义一个WindowsLoad的类,其父类是QMainWindow
def __init__(self):
def threadReadFromServer(self, num):
netSimplifyClient = NetSimplifyClient('118.24.36.220', 18467) #实例化一个客户端对象,需要手动指定Ip地址和端口
# netSimplifyClient.Token = uuid.UUID('66a469ad-a595-48ed-abe1-912f7085dbcd')
#网络类的身份令牌,在hsl协议的模式下会有效,在和设备进行通信的时候是无效的
# netSimplifyClient.SetLoginAccount("admin","123456")
# 如果采用了账户名和密码的验证时用这条。设置当前的登录的账户名和密码信息,并启用账户验证的功能,账户名为空时设置不生效
#Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
#相当于保存密码的功能,第一次用用户名和密码,以后一段时间内只需要token和客户端的token进行对比即可
connect = netSimplifyClient.ConnectServer()
#netSimplifyClient.ConnectServer()尝试连接远程的服务器,如果连接成功,就切换短连接模式到长连接模式
if connect.IsSuccess == False:
print(connect.Message) #如果连接失败,显示连接失败的信息
else:
netSimplifyClient.ReadFromServer(600, '1.0.0') #客户端向服务器进行请求
netSimplifyClient.ConnectClose() #手动断开与远程服务器的连接
def initUI(self): #对窗口一系列布局,按钮的信号和槽搭建。
#槽函数并不在这个def中
t1 = threading.Thread(target=self.threadReadFromServer, args=(13,))
#t1代表可以执行的某个任务的一个线程,target是最重要的参数,是一个回调函数
t1.start()
#要让一个线程启动,就要调用其start方法即可
def center(self): #控制窗口在屏幕中心
def blogClick(self): #一系列首界面的槽函数
.
.
.
def pushButton101_Click(self): #西门子1200选项被按下的槽函数,显示子界面
self.formSiemens = FormSiemens(SiemensPLCS.S1200)
self.formSiemens.show()
def show(self): #首界面显示函数
super().show()
刚进入的主界面,主要功能是选择不同的PLC。由本次使用的是西门子1200,故点击1200,进入子界面。
首先定义一个传递功能模块,DemoUtils
class DemoUtils: #实用程序类,用于读写结果的呈送
@staticmethod
def ReadResultRender(result: OperateResult, address: str, textBox: QTextEdit):
#参数后加:其实是注释,表明参数的类型
@staticmethod
def WriteResultRender(result: OperateResult, address: str):
子界面的一些布局类,以及功能函数
class UserControlHead(QWidget): #显示主界面的一些绘制,不含功能
class UserControlReadWriteOp(QWidget): #上面两个读写框功能设计类
def __init__(self, parent=None):
def initUI(self): #上面两个读写框的布局函数,以及按钮的信号和槽
def button_read_bool_click(self): # 各种读按钮的触发函数,r-bool按钮按下
if self.textbox5.text() == "1":
DemoUtils.ReadResultRender(self.readWriteNet.ReadBool(self.textbox3.text()), self.textbox3.text(),self.textbox4)
#readWriteNet(连接结果0或1,地址,大框框显示连接信息)
else:
DemoUtils.ReadResultRender(self.readWriteNet.ReadBool(self.textbox3.text(), int(self.textbox5.text())),self.textbox3.text(), self.textbox4)
#没看懂那个1的框框是什么???????????????????
.
.
.
def button_write_bool_click(self): #各种写入按钮的触发函数
if self.textbox7.text().lower() == "true":
#text().lower()函数,将文本的大写全改成小写。如果框框里是true,则执行
DemoUtils.WriteResultRender(self.readWriteNet.WriteBool(self.textbox8.text(), True), self.textbox8.text())
# WriteResultRender(连接结果0或1,连接地址)
# self.readWriteNet.WriteInt64向PLC中写入bool数组,返回是否写入成功,(,地址?????????????????????????????)
else:
DemoUtils.WriteResultRender(self.readWriteNet.WriteBool(self.textbox8.text(), False), self.textbox8.text())
.
.
.
def SetReadWriteNet(self, readWrite, address, strLength=10): #设置读写地址
#在class FormSiemens的第一部分“connect”按钮被按下时会触发这个函数
下面到了Siemens专属类,class FormSiemens,在首界面按下对应的PLC后,会创建一个窗口实例对象,就是下面这个类的实例
class FormSiemens(QtWidgets.QMainWindow):
def __init__(self, plc: SiemensPLCS):
def initUI(self): #整个界面的外观设计,以及模块布局
def center(self):
#下面是一些读写按钮的触发函数
def button_connect_click(self): #第一部分connect按钮的触发函数
def button_disconnect_click(self): #第一部分disconnect按钮的触发函数
def button3_click(self): #3号框,“order number”按钮
def button25_click(self): #3号框,“bulk read”按钮
def button26_click(self): #4号框,“read”按钮
所有类都定义完了,最后是一些收尾代码:
app = QtWidgets.QApplication(sys.argv)
windowsLoad = WindowsLoad()
windowsLoad.show()
sys.exit(app.exec_())