You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
17 KiB
Python

9 months ago
import sys
import time
import win32con
import win32gui
import win32process
import subprocess
import qtawesome
from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QDockWidget, QWidget, QHBoxLayout, QStackedWidget\
,QVBoxLayout, QProgressBar, QLabel, QButtonGroup
from PyQt5.QtCore import Qt, QTimer, QSize
from PyQt5.QtGui import QIcon, QWindow, QPixmap
from utils.DBModels.BaseModel import *
from model.ClientModel.Client import Client
from UI.ProfibusWidgets.DeviceWidget import DeviceTab
from model.ProjectModel.DeviceManage import DevicesManange
from utils.DBModels.InitParameterDB import InitParameterDB
from protocol.BatterySerial.BatteryProtocol import BatteryManange
from protocol.ModBus.DPV1Master import DPV1Master
from UI.ProfibusWidgets.BlockParameterManageWidget import BlockParameterManageWidget
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QProgressBar, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QPainter, QFont
from utils import Globals
class CustomProgressBar(QProgressBar):
def __init__(self, parent=None):
super().__init__(parent)
self.setTextVisible(False)
self.setFont(QFont("Arial", 10)) # 设置字体大小和类型
def paintEvent(self, event):
super().paintEvent(event)
painter = QPainter(self)
value = self.value()
percentage = round(value / self.maximum() * 100, 1)
text = f"剩余电量{percentage}%"
painter.drawText(self.rect(), Qt.AlignCenter, text)
def getHwndByPid(pid):
def callback(hwnd, hwnds):
if hwnd is not None and win32gui.IsWindowVisible(hwnd):
_, found_pid = win32process.GetWindowThreadProcessId(hwnd)
if found_pid == pid:
hwnds.append(hwnd)
hwnds = []
# win32gui.EnumWindows(callback, hwnds)
while True:
win32gui.EnumWindows(callback, hwnds)
if hwnds:
return hwnds[0]
# 如果没有找到窗口,则等待一段时间再尝试
time.sleep(0.1)
# return hwnds
# return hwnds[0]
8 months ago
class ProfibusWidgets(QWidget):
9 months ago
def __init__(self):
super().__init__()
InitParameterDB()
self.setObjectName("MainWindow")
1 month ago
self.protocolManage = Globals.getValue('protocolManage')
self.usingSharedProfibus = False
self.devicesManange = None
if self.protocolManage and self.protocolManage.hasProfibusSupport():
sharedManager = self.protocolManage.getSharedProfibusManager()
if sharedManager:
self.devicesManange = sharedManager
self.usingSharedProfibus = True
if self.devicesManange is None:
print('没有找到共享的Profibus')
self.devicesManange = DevicesManange()
9 months ago
# self.batteryManange = BatteryManange()
1 month ago
self.dpv1Master = DPV1Master('192.168.4.38', 502)
9 months ago
self.blockParameterManageWidget = BlockParameterManageWidget()
self.process = None
# Globals.setValue('ProfibusWindow', self)
self.initUI()
def initUI(self):
self.protocolTimer = QTimer()
self.protocolTimer.timeout.connect(self.readValues)
self.batteryTimer = QTimer()
self.batteryTimer.timeout.connect(self.refreshProgressBar)
self.batteryTimer.start(3000)
self.searchAddressTimer = QTimer()
self.searchAddressTimer.timeout.connect(self.searchSlave)
self.searchAddressTimer.start(1000)
9 months ago
# self.searchAddressTimer.start(10000)
# self.toolbarWidget = QWidget()
# self.addToolBar(Qt.LeftToolBarArea, self.toolbar)
toolbarLayout = QHBoxLayout()
self.startProtocolBtn = QPushButton()
8 months ago
self.startProtocolBtn.setObjectName("profibusStartProtocolBtn")
# self.startProtocolBtn.setIcon(QIcon('./Static/startProtocol.png'))
9 months ago
self.startProtocolBtn.setText('开始通讯')
8 months ago
self.startProtocolBtn.setIcon(QIcon('Static/start_green.png'))
9 months ago
self.startProtocolBtn.setIconSize(QSize(23, 23))
self.startProtocolBtn.setCheckable(True)
self.startProtocolBtn.clicked.connect(self.startProtocol)
self.switchBtn = QPushButton('通讯组态')
self.switchBtn.setObjectName("switchBtn")
self.switchBtn.setIcon(qtawesome.icon('msc.circuit-board', color='#1fbb6f'))
self.switchBtn.setIconSize(QSize(25, 25))
self.switchBtn.setCheckable(True)
self.switchBtn.clicked.connect(self.switchWidget)
self.valueBtn = QPushButton('变量读写')
self.valueBtn.setObjectName("switchBtn")
self.valueBtn.setIcon(qtawesome.icon('fa.pencil', color='#1fbb6f'))
self.valueBtn.setIconSize(QSize(25, 25))
self.valueBtn.setCheckable(True)
self.valueBtn.clicked.connect(self.switchDeviceValueManageWidget)
self.deviceParameterManageBtn = QPushButton('设备参数管理')
self.deviceParameterManageBtn.setObjectName('deviceParameterManageBtn')
self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.gears', color='#1fbb6f'))
self.deviceParameterManageBtn.setIconSize(QSize(25, 25))
self.deviceParameterManageBtn.setCheckable(True)
self.deviceParameterManageBtn.clicked.connect(self.switchDeviceParManageWidget)
self.addressLabel = QLabel('在线仪表地址:')
self.addressLabel.setObjectName('batteryLabel')
self.batteryProBar = CustomProgressBar()
self.batteryProBar.setRange(0, 100)
self.batteryStateLabel = QLabel()
self.batteryStateLabel.setObjectName('batteryLabel')
self.switchTouchBtn = QPushButton("触控模式")
self.switchTouchBtn.setIconSize(QSize(25, 25))
self.switchTouchBtn.setObjectName('switchTouchBtn')
self.switchTouchBtn.setIcon(qtawesome.icon('fa.hand-pointer-o', color='#1fbb6f'))
self.switchTouchBtn.clicked.connect(self.switchTouchMode)
self.switchTouchBtn.setCheckable(True)
# 创建按钮
# self.minimizeButton = QPushButton(QIcon('./Static/min.png'), "")
8 months ago
# self.minimizeButton.setObjectName('minButton')
# self.closeButton = QPushButton(QIcon('./Static/close.png'), "")
8 months ago
# self.closeButton.setObjectName('closeButton')
9 months ago
8 months ago
# # 按钮点击事件连接
# self.minimizeButton.clicked.connect(self.showMinimized)
# self.closeButton.clicked.connect(self.close)
# hLayout = QHBoxLayout()
# hLayout.addWidget(self.minimizeButton)
# hLayout.addWidget(self.closeButton)
9 months ago
iconLabel = QLabel()
pix = QPixmap('Static/Hicent.png')
9 months ago
scaledPixmap = pix.scaled(168, 28, Qt.KeepAspectRatio)
iconLabel.setPixmap(scaledPixmap)
iconLabel.setScaledContents(True)
8 months ago
# toolbarLayout.addWidget(iconLabel, 1)
# toolbarLayout.addWidget(QWidget(), 1)
9 months ago
toolbarLayout.addWidget(self.startProtocolBtn, 1)
toolbarLayout.addWidget(self.valueBtn, 1)
toolbarLayout.addWidget(self.switchBtn, 1)
toolbarLayout.addWidget(self.switchTouchBtn, 1)
toolbarLayout.addWidget(self.deviceParameterManageBtn, 1)
toolbarLayout.addWidget(QWidget(), 4)
toolbarLayout.addWidget(self.addressLabel, 1)
toolbarLayout.addWidget(QWidget(), 10)
# toolbarLayout.addWidget(QLabel('电量:'), 1)
1 month ago
# toolbarLayout.addWidget(self.batteryProBar, 1)
# toolbarLayout.addWidget(self.batteryStateLabel, 1)
9 months ago
toolbarLayout.addWidget(QWidget(), 1)
8 months ago
# toolbarLayout.addLayout(hLayout, 1)
9 months ago
toolbarLayout.setSpacing(20)
toolbarLayout.setContentsMargins(0, 0, 0, 0)
dpMasterDockWidget = QDockWidget('DP主站')
dpMasterDockWidget.setWidget(DeviceTab(dpMasterDockWidget, self.devicesManange))
dpMasterDockWidget.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) # type: ignore
dpSlaveDockWidget = QDockWidget('DP从站')
dpSlaveDockWidget.setWidget(DeviceTab(dpSlaveDockWidget, self.devicesManange))
dpSlaveDockWidget.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) # type: ignore
paMasterDockWidget = QDockWidget('PA主站')
paMasterDockWidget.setWidget(DeviceTab(paMasterDockWidget, self.devicesManange))
paMasterDockWidget.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) # type: ignore
paSlaveDockWidget = QDockWidget('PA从站')
paSlaveDockWidget.setWidget(DeviceTab(paSlaveDockWidget, self.devicesManange))
paSlaveDockWidget.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) # type: ignore
self.upperWidget = QMainWindow()
self.upperWidget.addDockWidget(Qt.TopDockWidgetArea, dpMasterDockWidget) # type: ignore
self.upperWidget.addDockWidget(Qt.TopDockWidgetArea, dpSlaveDockWidget) # type: ignore
self.upperWidget.addDockWidget(Qt.BottomDockWidgetArea, paMasterDockWidget) # type: ignore
self.upperWidget.addDockWidget(Qt.BottomDockWidgetArea, paSlaveDockWidget) # type: ignore
self.stackWidget = QStackedWidget()
self.stackWidget.addWidget(self.upperWidget)
self.stackWidget.addWidget(QWidget())
self.stackWidget.addWidget(self.blockParameterManageWidget)
self.mainLayout = QVBoxLayout(self)
self.mainLayout.addLayout(toolbarLayout, 1)
self.mainLayout.addWidget(self.stackWidget, 50)
self.setLayout(self.mainLayout)
# self.setCentralWidget(self.stackWidget)
self.setWindowIcon(QIcon('./Static/Hicent.jpg'))
9 months ago
self.setWindowTitle("PROFIBUS总线测试工具")
self.refreshProgressBar()
1 month ago
self._connectProfibusBackend()
9 months ago
self.setWindowFlags(Qt.FramelessWindowHint)
1 month ago
9 months ago
# self.resize(800, 600)
# self.showMaximized()
def startProtocol(self):
if self.startProtocolBtn.isChecked():
self.startProtocolBtn.setText('停止通讯')
self.startProtocolBtn.setIcon(QIcon('./Static/pause.png'))
9 months ago
self.startProtocolBtn.setIconSize(QSize(22, 22))
1 month ago
self._connectProfibusBackend()
9 months ago
self.protocolTimer.start(500)
else:
1 month ago
9 months ago
self.startProtocolBtn.setText('开始通讯')
self.startProtocolBtn.setIcon(QIcon('./Static/start.png'))
9 months ago
self.protocolTimer.stop()
def readValues(self):
1 month ago
if not self._updateProfibusAreasForUI():
return
9 months ago
dockWidgets = self.findChildren(QDockWidget) #找到四个dockWidget窗口
1 month ago
9 months ago
for dockWidget in dockWidgets:
if dockWidget.widget().currentWidget().objectName() == 'initWidget':
# print(dockWidget.widget().currentWidget().objectName())
continue
areaTabWidget = dockWidget.widget().currentWidget()#判断四个窗口里是否
if areaTabWidget.currentWidget().objectName() == 'initWidget':
# print(2)
continue
if areaTabWidget.currentWidget().state:
# print(3)
continue
# masterAndSlave = dockWidget.windowTitle()[2:5]
# proType = dockWidget.windowTitle()
# dataType = dataTypeCombox.currentText()
# dataTypeAndModel = masterAndSlave + dataType
# if dataTypeAndModel in ['主站AI', '主站DI', '从站AO', '从站DO']:
# devicecurIndex =.currentIndex()
# deviceTabText =.tabText(devicecurIndex)
# try:
areacurindex = areaTabWidget.currentIndex()
# deviceName = deviceTabText + proType
buttonlayoutWidget = areaTabWidget.currentWidget().rightAreaWidgets#获取buttonlayout
buttonlayoutWidget.readValues(curIndex = areacurindex)
# except Exception as e:
# print(e)
1 month ago
def _connectProfibusBackend(self):
if self.usingSharedProfibus and self.protocolManage:
sharedManager = self.protocolManage.getSharedProfibusManager()
if sharedManager:
self.devicesManange = sharedManager
self.protocolManage.connectProfibus()
else:
self.devicesManange.connect()
def _updateProfibusAreasForUI(self):
if self.usingSharedProfibus and self.protocolManage:
self.protocolManage.updateProfibusAreas(force=True)
return True
self.devicesManange.readAreas()
return True
9 months ago
def refreshProgressBar(self):
1 month ago
9 months ago
# self.temp = temp / 10 if temp > -3276.8 else float('nan') # 假设温度值需要除以10得到实际℃数
# self.current = current # mA
# self.volt = volt # mV
# self.remaintime = remaintime # 分钟
# self.capacity = capacity # mAH
# self.cappercent = cappercent # 百分比%
# self.state = state # 充放电状态
pass
# result = self.batteryManange.readBatteryInfo()
# self.batteryProBar.setValue(result.cappercent)
# self.batteryStateLabel.setText(result.chargingStatus)
def searchSlave(self):
address = self.dpv1Master.searchSlave()
if address == '读取错误':
self.dpv1Master = DPV1Master('192.168.4.38', 502)
9 months ago
self.addressLabel.setText('在线仪表地址:')
self.addressLabel.setText('在线仪表地址:{}'.format(address))
def switchWidget(self):
if self.process:
self.stackWidget.setCurrentIndex(1)
QTimer.singleShot(50, lambda:self.stackWidget.setCurrentIndex(3))
else:
self.stackWidget.setCurrentIndex(1)
startupInfo = subprocess.STARTUPINFO()
startupInfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupInfo.wShowWindow = 2
self.process = subprocess.Popen("C:\\EnTalk PROFIBUS Manager\\DP.exe",startupinfo=startupInfo)
9 months ago
QTimer.singleShot(500, lambda:self.showLowerWidget(self.process))
# self.showFullScreen()
# self.switchBtn.setIcon(QIcon('./Static/varMagH.png'))
9 months ago
def switchDeviceValueManageWidget(self):
self.stackWidget.setCurrentIndex(0)
try:
self.stackWidget.widget(3).clearFocus()
except Exception as e:
pass
def switchDeviceParManageWidget(self):
# if self.deviceParameterManageBtn.isChecked():
self.stackWidget.setCurrentIndex(2)
try:
self.stackWidget.widget(3).clearFocus()
except Exception as e:
pass
# self.deviceParameterManageBtn.setText('变量读写')
self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.pencil-square-o', color='#1fbb6f'))
# else:
# self.stackWidget.setCurrentIndex(0)
# self.deviceParameterManageBtn.setText('设备参数管理')
# self.deviceParameterManageBtn.setIcon(qtawesome.icon('fa.gears', color='#1fbb6f'))
def showLowerWidget(self, process):
pid = process.pid
hwnd = int(getHwndByPid(pid))
style = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)
exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
wrect = win32gui.GetWindowRect(hwnd)[:2] + win32gui.GetClientRect(hwnd)[2:]
# print('save', hwnd, style, exstyle, wrect)
widget = QWidget.createWindowContainer(QWindow.fromWinId(hwnd))
# print(type(widget))
widget.hwnd = hwnd # 窗口句柄
widget.phwnd = int(self.winId()) # 父窗口句柄
widget.style = style # 窗口样式
widget.exstyle = exstyle # 窗口额外样式
widget.wrect = wrect # 窗口位置
self.stackWidget.addWidget(widget)
widget.setWindowFlags(Qt.FramelessWindowHint)
win32gui.SetParent(hwnd, int(self.winId()))
self.stackWidget.setCurrentIndex(3)
def closeEvent(self, event):
if self.process:
self.process.kill()
# self.batteryManange.close()
def switchTouchMode(self):
if self.switchTouchBtn.isChecked():
Globals.setValue('_touchMode', 1)
self.switchTouchBtn.setIcon(qtawesome.icon('fa.keyboard-o', color='#1fbb6f'))
self.switchTouchBtn.setText('键盘模式')
else:
Globals.setValue('_touchMode', 0)
self.switchTouchBtn.setIcon(qtawesome.icon('fa.hand-pointer-o', color='#1fbb6f'))
self.switchTouchBtn.setText('触控模式')
def toggleMaximize(self):
if self.isMaximized():
self.showNormal()
self.maxRestoreButton.setIcon(QIcon('maximizeIcon.png'))
else:
self.showMaximized()
self.maxRestoreButton.setIcon(QIcon('restoreIcon.png')) # 替换为合适的还原图标路径
if __name__ == '__main__':
app = QApplication(sys.argv)
Client.initDB()
window = MainWindow()
window.show()
sys.exit(app.exec_())