|
|
from csv import excel
|
|
|
import sys
|
|
|
import pandas as pd
|
|
|
from PyQt5 import QtWidgets
|
|
|
from PyQt5.QtCore import Qt
|
|
|
from PyQt5.Qt import *
|
|
|
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QMessageBox, QStackedWidget, QWidget, QTabWidget, QFileDialog
|
|
|
from ctypes import POINTER, cast
|
|
|
from ctypes.wintypes import MSG
|
|
|
from win32 import win32api, win32gui
|
|
|
from win32.lib import win32con
|
|
|
from model.ProjectModel.VarManage import GlobalVarManager
|
|
|
from windoweffect import WindowEffect, MINMAXINFO, NCCALCSIZE_PARAMS
|
|
|
from UI.Main.MainLeft import MainLeft
|
|
|
from UI.Main.MainTop import MainTop
|
|
|
from ..ProjectManages.ProjectWidget import ProjectWidgets
|
|
|
from ..VarManages.VarWidget import VarWidgets, HartWidgets, TcRtdWidgets, AnalogWidgets, HartSimulateWidgets
|
|
|
from ..UserManage.UserWidget import UserWidgets
|
|
|
from ..TrendManage.TrendWidget import TrendWidgets
|
|
|
from ..Setting.Setting import SettingWidget
|
|
|
from model.ClientModel.Client import Client
|
|
|
from utils import Globals
|
|
|
from utils.DBModels.InitParameterDB import InitParameterDB
|
|
|
from UI.ProfibusWidgets.ProfibusWindow import ProfibusWidgets
|
|
|
from UI.ProcedureManager.ProcedureManager import ProcedureManager
|
|
|
|
|
|
class CommonHelper:
|
|
|
def __init__(self):
|
|
|
pass
|
|
|
|
|
|
@staticmethod
|
|
|
def readQss(style):
|
|
|
with open(style,"r") as f:
|
|
|
return f.read()
|
|
|
|
|
|
class MainWindow(QMainWindow):
|
|
|
|
|
|
BORDER_WIDTH = 5 #设圆角
|
|
|
|
|
|
def __init__(self):
|
|
|
super(MainWindow, self).__init__()
|
|
|
InitParameterDB()
|
|
|
self.setupUi()
|
|
|
# self.setStyleSheet(CommonHelper.readQss('static/main.qss'))
|
|
|
|
|
|
self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowSystemMenuHint)
|
|
|
self.SHADOW_WIDTH = 0 #边框距离
|
|
|
self.isLeftPressDown = False #鼠标左键是否按下
|
|
|
self.dragPosition = 0 #拖动时坐标
|
|
|
self.padding = 4
|
|
|
self.Numbers = self.enum(UP=0, DOWN=1, LEFT=2, RIGHT=3, LEFTTOP=4, LEFTBOTTOM=5, RIGHTBOTTOM=6, RIGHTTOP=7, NONE=8) #枚举参数
|
|
|
self.setMinimumHeight(900) #窗体最小高度
|
|
|
self.setMinimumWidth(1600) #窗体最小宽度
|
|
|
self.dir = self.Numbers.NONE #初始鼠标状态
|
|
|
|
|
|
#开启鼠标追踪
|
|
|
self.setMouseTracking(True)
|
|
|
self.centralwidget.setMouseTracking(True)
|
|
|
self.leftWidget.setMouseTracking(True)
|
|
|
self.rightWidget.setMouseTracking(True)
|
|
|
self.topWidget.setMouseTracking(True)
|
|
|
|
|
|
#初始化接口
|
|
|
self.windowEffect = WindowEffect()
|
|
|
# 添加DWM阴影效果
|
|
|
self.windowEffect.addWindowAnimation(self.winId())
|
|
|
self.windowEffect.addShadowEffect(self.winId())
|
|
|
|
|
|
# 解决报错
|
|
|
self.windowHandle().screenChanged.connect(self.__onScreenChanged)
|
|
|
|
|
|
|
|
|
def setupUi(self):
|
|
|
self.showMaximized()
|
|
|
self.centralwidget = QtWidgets.QWidget(self)
|
|
|
self.centralwidget.setObjectName("centralwidget")
|
|
|
|
|
|
self.leftWidget = MainLeft()
|
|
|
self.leftWidget.setObjectName("leftWidget")
|
|
|
|
|
|
self.projectWidget = ProjectWidgets()
|
|
|
self.userWidget = UserWidgets()
|
|
|
self.procedureManagerWidget = ProcedureManager()
|
|
|
|
|
|
self.ModbusTcpMasterWidget = VarWidgets('ModbusTcpMaster')
|
|
|
self.ModbusTcpSlaveWidget = VarWidgets('ModbusTcpSlave')
|
|
|
self.ModbusRtuMasterWidget = VarWidgets('ModbusRtuMaster')
|
|
|
self.ModbusRtuSlaveWidget = VarWidgets('ModbusRtuSlave')
|
|
|
|
|
|
modbusWidgetList = [self.ModbusTcpMasterWidget, self.ModbusTcpSlaveWidget, self.ModbusRtuMasterWidget, self.ModbusRtuSlaveWidget]
|
|
|
modbusNameList = ['MODBUSTCP主站', 'MODBUSTCP从站', 'MODBUSRTU主站', 'MODBUSRTU从站',]
|
|
|
|
|
|
self.profibusWidget = ProfibusWidgets()
|
|
|
self.trendWidget = TrendWidgets()
|
|
|
self.SettingWidget = SettingWidget()
|
|
|
self.hartWidget = HartWidgets()
|
|
|
self.tcrtdWidget = TcRtdWidgets()
|
|
|
self.analogWidget = AnalogWidgets()
|
|
|
self.hartsimulateWidget = HartSimulateWidgets()
|
|
|
|
|
|
self.userWidget.setObjectName('userWidget')
|
|
|
self.projectWidget.setObjectName('projectWidget')
|
|
|
self.trendWidget.setObjectName('trendWidget')
|
|
|
# self.ModBusWidget.setObjectName('varWidget')
|
|
|
self.analogWidget.setObjectName('analogWidget')
|
|
|
self.hartsimulateWidget.setObjectName('hartsimulateWidget')
|
|
|
|
|
|
|
|
|
self.varManageTabWidget = QTabWidget()
|
|
|
self.varManageTabWidget.setObjectName("varManageTabWidget")
|
|
|
self.varManageTabWidget.tabBar().setObjectName('varManageTabBar')
|
|
|
|
|
|
self.rightWidget = QStackedWidget()
|
|
|
self.rightWidget.setObjectName("rightWidget")
|
|
|
self.rightWidget.addWidget(self.projectWidget)
|
|
|
for widget, name in zip(modbusWidgetList, modbusNameList):
|
|
|
widget.setObjectName('varWidget')
|
|
|
self.varManageTabWidget.addTab(widget, name)
|
|
|
|
|
|
self.varManageTabWidget.addTab(self.analogWidget,'IO')
|
|
|
self.varManageTabWidget.addTab(self.tcrtdWidget,'TCRTD')
|
|
|
self.varManageTabWidget.addTab(self.hartWidget,'HART读取')
|
|
|
self.varManageTabWidget.addTab(self.hartsimulateWidget,'HART模拟')
|
|
|
self.varManageTabWidget.addTab(self.profibusWidget,'PROFIBUS')
|
|
|
|
|
|
#添加导入变量按钮
|
|
|
self.importVarButton = QPushButton(QIcon(':/static/import.png'), '导入变量')
|
|
|
self.importVarButton.setObjectName('importBtn')
|
|
|
self.importVarButton.setIconSize(QSize(22, 22))
|
|
|
self.importVarButton.setFlat(True)
|
|
|
self.importVarButton.clicked.connect(self.loadVar)
|
|
|
self.varManageTabWidget.setCornerWidget(self.importVarButton)
|
|
|
|
|
|
|
|
|
|
|
|
self.rightWidget.addWidget(self.varManageTabWidget)
|
|
|
self.rightWidget.addWidget(self.trendWidget)
|
|
|
self.rightWidget.addWidget(self.userWidget)
|
|
|
self.rightWidget.addWidget(self.SettingWidget)
|
|
|
self.rightWidget.addWidget(self.procedureManagerWidget)
|
|
|
self.rightWidget.widget(1)
|
|
|
|
|
|
self.leftWidget.createProject.clicked.connect(lambda: self.exButtonClicked(0))
|
|
|
self.leftWidget.varMag.clicked.connect(self.varShow)
|
|
|
self.leftWidget.trendMag.clicked.connect(self.reFreshTrendWidget)
|
|
|
self.leftWidget.userMag.clicked.connect(lambda: self.exButtonClicked(3))
|
|
|
self.leftWidget.protocolMag.clicked.connect(self.showSetting)
|
|
|
self.leftWidget.procedureMag.clicked.connect(lambda: self.initProcedureDB())
|
|
|
|
|
|
self.setCentralWidget(self.centralwidget)
|
|
|
self.setWindowOpacity(0.995) # 设置窗口透明度
|
|
|
|
|
|
self.topWidget = MainTop(self)
|
|
|
self.topWidget.setObjectName('topWidget')
|
|
|
|
|
|
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
|
|
|
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
|
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
|
|
self.verticalLayout.setObjectName("verticalLayout")
|
|
|
|
|
|
self.horizontalLayout.addWidget(self.leftWidget)
|
|
|
self.horizontalLayout.addWidget(self.rightWidget)
|
|
|
self.horizontalLayout.setStretch(0, 1)
|
|
|
self.horizontalLayout.setStretch(1, 7)
|
|
|
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
|
|
self.horizontalLayout.setSpacing(5)
|
|
|
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
|
|
self.verticalLayout.addWidget(self.topWidget)
|
|
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
|
self.verticalLayout.setStretch(0, 1)
|
|
|
self.verticalLayout.setStretch(1, 18)
|
|
|
self.verticalLayout.setSpacing(0)
|
|
|
|
|
|
# self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口背景透明
|
|
|
self.setWindowFlag(Qt.FramelessWindowHint)
|
|
|
|
|
|
def exButtonClicked(self, index):
|
|
|
if Globals.getValue('currentPro') == -1 and index not in [0, 3]:
|
|
|
return -1
|
|
|
print(index, Globals.getValue('currentPro'))
|
|
|
self.rightWidget.setCurrentIndex(index)
|
|
|
|
|
|
|
|
|
def showSetting(self):
|
|
|
if Globals.getValue('currentPro') == -1:
|
|
|
return
|
|
|
self.SettingWidget.setupUI()
|
|
|
self.rightWidget.setCurrentIndex(4)
|
|
|
|
|
|
|
|
|
def varShow(self):
|
|
|
self.exButtonClicked(1)
|
|
|
Globals.setValue('SearchWidget', 1)
|
|
|
|
|
|
|
|
|
def reFreshTrendWidget(self):
|
|
|
if Globals.getValue('currentPro') == -1:
|
|
|
return
|
|
|
self.trendWidget.getMems()
|
|
|
self.exButtonClicked(2)
|
|
|
|
|
|
def initProcedureDB(self):
|
|
|
if Globals.getValue('currentPro') == -1:
|
|
|
return
|
|
|
self.procedureManagerWidget.initDB()
|
|
|
self.procedureManagerWidget.initUI()
|
|
|
self.exButtonClicked(5)
|
|
|
|
|
|
def loadVar(self):
|
|
|
file_path, _ = QFileDialog.getOpenFileName(self, '选择Excel文件', '', 'Excel Files (*.xlsx *.xls)')
|
|
|
if not file_path:
|
|
|
return
|
|
|
|
|
|
excelData = pd.read_excel(file_path, sheet_name=None)
|
|
|
allVarNames = []
|
|
|
for sheet_name, data in excelData.items():
|
|
|
if '变量名' in data.columns:
|
|
|
# 确保所有变量名转换为字符串
|
|
|
allVarNames.extend(data['变量名'].astype(str).tolist())
|
|
|
|
|
|
if len(allVarNames) != len(set(allVarNames)):
|
|
|
# 确保重复名称列表中的元素都是字符串
|
|
|
repeated_names = [str(name) for name in set(allVarNames) if allVarNames.count(name) > 1]
|
|
|
QMessageBox.warning(self, '警告', f'发现重复的变量名: {", ".join(repeated_names)}')
|
|
|
return
|
|
|
allErrInfo = []
|
|
|
for sheet_name, data in excelData.items():
|
|
|
if '变量名' in data.columns:
|
|
|
importInfo = GlobalVarManager.importVar(sheet_name, data)
|
|
|
allErrInfo.append(importInfo)
|
|
|
if allErrInfo:
|
|
|
# 过滤掉空字符串
|
|
|
allErrInfo = [info for info in allErrInfo if info]
|
|
|
if not allErrInfo:
|
|
|
QMessageBox.information(self, '导入信息', '所有变量导入成功')
|
|
|
else:
|
|
|
|
|
|
errorMessages = '\n'.join(allErrInfo)
|
|
|
QMessageBox.information(self, '导入信息', errorMessages)
|
|
|
|
|
|
|
|
|
|
|
|
def enum(self,**enums):
|
|
|
return type('Enum', (), enums)
|
|
|
|
|
|
def region(self,cursorGlobalPoint):
|
|
|
#获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
|
|
|
rect = self.rect()
|
|
|
tl = self.mapToGlobal(rect.topLeft())
|
|
|
rb = self.mapToGlobal(rect.bottomRight())
|
|
|
|
|
|
x = cursorGlobalPoint.x()
|
|
|
y = cursorGlobalPoint.y()
|
|
|
|
|
|
if(tl.x() + self.padding >= x and tl.x() <= x and tl.y() + self.padding >= y and tl.y() <= y):
|
|
|
#左上角
|
|
|
self.dir = self.Numbers.LEFTTOP
|
|
|
self.setCursor(QCursor(Qt.SizeFDiagCursor)) #设置鼠标形状
|
|
|
elif(x >= rb.x() - self.padding and x <= rb.x() and y >= rb.y() - self.padding and y <= rb.y()):
|
|
|
#右下角
|
|
|
self.dir = self.Numbers.RIGHTBOTTOM
|
|
|
self.setCursor(QCursor(Qt.SizeFDiagCursor))
|
|
|
elif(x <= tl.x() + self.padding and x >= tl.x() and y >= rb.y() - self.padding and y <= rb.y()):
|
|
|
#左下角
|
|
|
self.dir = self.Numbers.LEFTBOTTOM
|
|
|
self.setCursor(QCursor(Qt.SizeBDiagCursor))
|
|
|
elif(x <= rb.x() and x >= rb.x() - self.padding and y >= tl.y() and y <= tl.y() + self.padding):
|
|
|
#右上角
|
|
|
self.dir = self.Numbers.RIGHTTOP
|
|
|
self.setCursor(QCursor(Qt.SizeBDiagCursor))
|
|
|
elif(x <= tl.x() + self.padding and x >= tl.x()):
|
|
|
#左边
|
|
|
self.dir = self.Numbers.LEFT
|
|
|
self.setCursor(QCursor(Qt.SizeHorCursor))
|
|
|
elif( x <= rb.x() and x >= rb.x() - self.padding):
|
|
|
#右边
|
|
|
|
|
|
self.dir = self.Numbers.RIGHT
|
|
|
self.setCursor(QCursor(Qt.SizeHorCursor))
|
|
|
elif(y >= tl.y() and y <= tl.y() + self.padding):
|
|
|
#上边
|
|
|
self.dir = self.Numbers.UP
|
|
|
self.setCursor(QCursor(Qt.SizeVerCursor))
|
|
|
elif(y <= rb.y() and y >= rb.y() - self.padding):
|
|
|
#下边
|
|
|
self.dir = self.Numbers.DOWN
|
|
|
self.setCursor(QCursor(Qt.SizeVerCursor))
|
|
|
else:
|
|
|
#默认
|
|
|
self.dir = self.Numbers.NONE
|
|
|
self.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
|
def mouseReleaseEvent(self,event):
|
|
|
if(event.button() == Qt.LeftButton):
|
|
|
self.isLeftPressDown = False
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
self.releaseMouse()
|
|
|
self.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
|
def mousePressEvent(self,event):
|
|
|
if(event.button()==Qt.LeftButton):
|
|
|
self.isLeftPressDown=True
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
self.mouseGrabber()
|
|
|
else:
|
|
|
self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
|
|
|
|
|
|
def mouseMoveEvent(self,event):
|
|
|
gloPoint = event.globalPos()
|
|
|
rect = self.rect()
|
|
|
tl = self.mapToGlobal(rect.topLeft())
|
|
|
rb = self.mapToGlobal(rect.bottomRight())
|
|
|
|
|
|
if(not self.isLeftPressDown):
|
|
|
self.region(gloPoint)
|
|
|
else:
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
rmove=QRect(tl, rb)
|
|
|
if(self.dir==self.Numbers.LEFT):
|
|
|
if(rb.x() - gloPoint.x() <= self.minimumWidth()):
|
|
|
rmove.setX(tl.x())
|
|
|
else:
|
|
|
rmove.setX(gloPoint.x())
|
|
|
elif(self.dir==self.Numbers.RIGHT):
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
elif(self.dir==self.Numbers.UP):
|
|
|
if(rb.y() - gloPoint.y() <= self.minimumHeight()):
|
|
|
rmove.setY(tl.y())
|
|
|
else:
|
|
|
rmove.setY(gloPoint.y())
|
|
|
elif(self.dir==self.Numbers.DOWN):
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
elif(self.dir==self.Numbers.LEFTTOP):
|
|
|
if(rb.x() - gloPoint.x() <= self.minimumWidth()):
|
|
|
rmove.setX(tl.x())
|
|
|
else:
|
|
|
rmove.setX(gloPoint.x())
|
|
|
if(rb.y() - gloPoint.y() <= self.minimumHeight()):
|
|
|
rmove.setY(tl.y())
|
|
|
else:
|
|
|
rmove.setY(gloPoint.y())
|
|
|
elif(self.dir==self.Numbers.RIGHTTOP):
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
rmove.setY(gloPoint.y())
|
|
|
elif(self.dir==self.Numbers.LEFTBOTTOM):
|
|
|
rmove.setX(gloPoint.x())
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
elif(self.dir==self.Numbers.RIGHTBOTTOM):
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
else:
|
|
|
pass
|
|
|
self.setGeometry(rmove)
|
|
|
else:
|
|
|
self.move(event.globalPos() - self.dragPosition)
|
|
|
event.accept()
|
|
|
|
|
|
def nativeEvent(self, eventType, message):
|
|
|
""" 接受windows发送的信息 """
|
|
|
msg = MSG.from_address(message.__int__())
|
|
|
if msg.message == win32con.WM_NCHITTEST:
|
|
|
# 解决 issue #2 and issue #7
|
|
|
r = self.devicePixelRatioF()
|
|
|
xPos = (win32api.LOWORD(msg.lParam) -
|
|
|
self.frameGeometry().x()*r) % 65536
|
|
|
yPos = win32api.HIWORD(msg.lParam) - self.frameGeometry().y()*r
|
|
|
w, h = self.width()*r, self.height()*r
|
|
|
lx = xPos < self.BORDER_WIDTH
|
|
|
rx = xPos + 9 > w - self.BORDER_WIDTH
|
|
|
ty = yPos < self.BORDER_WIDTH
|
|
|
by = yPos > h - self.BORDER_WIDTH
|
|
|
if lx and ty:
|
|
|
return True, win32con.HTTOPLEFT
|
|
|
elif rx and by:
|
|
|
return True, win32con.HTBOTTOMRIGHT
|
|
|
elif rx and ty:
|
|
|
return True, win32con.HTTOPRIGHT
|
|
|
elif lx and by:
|
|
|
return True, win32con.HTBOTTOMLEFT
|
|
|
elif ty:
|
|
|
return True, win32con.HTTOP
|
|
|
elif by:
|
|
|
return True, win32con.HTBOTTOM
|
|
|
elif lx:
|
|
|
return True, win32con.HTLEFT
|
|
|
elif rx:
|
|
|
return True, win32con.HTRIGHT
|
|
|
elif msg.message == win32con.WM_NCCALCSIZE:
|
|
|
if self.__isWindowMaximized(msg.hWnd):
|
|
|
self.__monitorNCCALCSIZE(msg)
|
|
|
return True, 0
|
|
|
elif msg.message == win32con.WM_GETMINMAXINFO:
|
|
|
if self.__isWindowMaximized(msg.hWnd):
|
|
|
window_rect = win32gui.GetWindowRect(msg.hWnd)
|
|
|
if not window_rect:
|
|
|
return False, 0
|
|
|
|
|
|
# get the monitor handle
|
|
|
monitor = win32api.MonitorFromRect(window_rect)
|
|
|
if not monitor:
|
|
|
return False, 0
|
|
|
|
|
|
# get the monitor info
|
|
|
__monitorInfo = win32api.GetMonitorInfo(monitor)
|
|
|
monitor_rect = __monitorInfo['Monitor']
|
|
|
work_area = __monitorInfo['Work']
|
|
|
|
|
|
# convert lParam to MINMAXINFO pointer
|
|
|
info = cast(msg.lParam, POINTER(MINMAXINFO)).contents
|
|
|
|
|
|
# adjust the size of window
|
|
|
info.ptMaxSize.x = work_area[2] - work_area[0]
|
|
|
info.ptMaxSize.y = work_area[3] - work_area[1]
|
|
|
info.ptMaxTrackSize.x = info.ptMaxSize.x
|
|
|
info.ptMaxTrackSize.y = info.ptMaxSize.y
|
|
|
|
|
|
# modify the upper left coordinate
|
|
|
info.ptMaxPosition.x = abs(window_rect[0] - monitor_rect[0])
|
|
|
info.ptMaxPosition.y = abs(window_rect[1] - monitor_rect[1])
|
|
|
return True, 1
|
|
|
|
|
|
return QWidget.nativeEvent(self, eventType, message)
|
|
|
|
|
|
|
|
|
def __isWindowMaximized(self, hWnd) -> bool:
|
|
|
""" Determine whether the window is maximized """
|
|
|
# GetWindowPlacement() returns the display state of the window and the restored,
|
|
|
# maximized and minimized window position. The return value is tuple
|
|
|
windowPlacement = win32gui.GetWindowPlacement(hWnd)
|
|
|
if not windowPlacement:
|
|
|
return False
|
|
|
|
|
|
return windowPlacement[1] == win32con.SW_MAXIMIZE
|
|
|
|
|
|
def __monitorNCCALCSIZE(self, msg: MSG):
|
|
|
""" 调整窗口大小 """
|
|
|
monitor = win32api.MonitorFromWindow(msg.hWnd)
|
|
|
|
|
|
# If the display information is not saved, return directly
|
|
|
if monitor is None and not self.__monitorInfo:
|
|
|
return
|
|
|
elif monitor is not None:
|
|
|
self.__monitorInfo = win32api.GetMonitorInfo(monitor)
|
|
|
|
|
|
# adjust the size of window
|
|
|
params = cast(msg.lParam, POINTER(NCCALCSIZE_PARAMS)).contents
|
|
|
params.rgrc[0].left = self.__monitorInfo['Work'][0]
|
|
|
params.rgrc[0].top = self.__monitorInfo['Work'][1]
|
|
|
params.rgrc[0].right = self.__monitorInfo['Work'][2]
|
|
|
params.rgrc[0].bottom = self.__monitorInfo['Work'][3]
|
|
|
|
|
|
def __onScreenChanged(self):
|
|
|
hWnd = int(self.windowHandle().winId())
|
|
|
win32gui.SetWindowPos(hWnd, None, 0, 0, 0, 0, win32con.SWP_NOMOVE |
|
|
|
win32con.SWP_NOSIZE | win32con.SWP_FRAMECHANGED)
|
|
|
|
|
|
def closeEvent(self, event):
|
|
|
reply = QMessageBox.question(self,
|
|
|
'Quit',
|
|
|
"是否要退出程序?",
|
|
|
QMessageBox.Yes | QMessageBox.No,
|
|
|
QMessageBox.No)
|
|
|
if reply == QMessageBox.Yes:
|
|
|
try:
|
|
|
Client.close()
|
|
|
except:
|
|
|
pass
|
|
|
event.accept()
|
|
|
else:
|
|
|
event.ignore()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
app = QApplication(sys.argv)
|
|
|
app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
|
|
|
app.setStyleSheet(CommonHelper.readQss('static/main.qss'))
|
|
|
# print(QtWidgets.QStyleFactory.keys())
|
|
|
ex = MainWindow()
|
|
|
ex.show()
|
|
|
sys.exit(app.exec_())
|