Files
general-system-framework/wndMain/sub_uiMain.py

363 lines
19 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 主控界面子类
import time
from PySide6.QtCore import Qt, QRect, QTimer, QPoint, Slot
from PySide6.QtGui import QCloseEvent
from PySide6.QtWidgets import QMainWindow, QStatusBar, QLabel, QVBoxLayout, QMessageBox, QApplication, QDialog
from .pageDataQuery.sub_uiQuery import CSubPageQuery
from .pageDevDebug.sub_uiDevDebug import CSubPageDevDebug
from .pageParaSet.sub_uiParaSet import CSubPageParaSetting
from .pageRecipeMgt.sub_uiRecipe import CSubPageRecipe
from .pageUserMgt.sub_uiUser import CSubPageUser
from .uiMain import Ui_dlgMain
from .pageAutoPage.sub_uiAutoPage import CSubPageAutoProc
from common.generalFunc import CCommon
from common.allTypesEnum import EOSType, ESubPageType
from .statusBarView.vwStatusBar import CStatusbarView
from .funcBarView.vwFunctionBar import CFunctionBarView
from .pagePasswdChange.sub_uiPasswdChange import CPasswdChange
from .pagePasswdChange.uiPasswdChange import Ui_dlgChangePasswd
from wndCtrl.stateCtrl.clsSysState_autoproc import CStateAutoProc
from msg_dict import g_uiCtrlScript, g_uiGeometrySize, g_otherScripts, g_errMsgText
# 根据系统平台类型,调整屏幕尺寸高宽比例
def getSizeRatio(osType: EOSType) -> list:
if EOSType.MACOS == osType:
lstRatio = [1.0, 0.88]
elif EOSType.LINUX == osType:
lstRatio = [0.9, 1.0]
else:
lstRatio = [1.0, 1.0]
return lstRatio
class CSubUiMain(QMainWindow):
_m_nTimeCount = 0 #用作定时器,每秒计数
# public:
def __init__(self, userId: str, userType: str, parent=None):
super().__init__(parent)
# 挂载UI界面将当前业务类实例传入setupUiUI组件成为实例属性
self.ui = Ui_dlgMain()
self.ui.setupUi(self)
# 获取屏幕分辨率
self._m_arrScreen = CCommon.fnGetScreenRate()
# 按需声明对应的成员变量
self._m_status = None # 状态栏对象
self._m_bQuitType = True # 退出方式True完全退出系统 False返回到登录窗口
self._m_currentUser = [userId, userType]
pass
# 界面初始化
def uiInit(self) -> None:
self._createStatusLabels() # 创建状态栏显示标签
self._initStatusBar() # 创建并初始化状态栏
self._screenAdapter() # 界面自适应
# ---------------------------
self._createSubPages((int(self.ui.stkMainContainer.width()), int(self.ui.stkMainContainer.height()))) # 创建功能子页面
self._add2StackWidget() # 添加到容器
self._adjustRdoButtons() # 调整功能框单选按钮布局
# 添加其他和界面或控件初始化相关的操作
self.setWindowTitle(g_uiCtrlScript['WND_TITLE_MAIN']) #设置窗口标题
self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True) # 设置当窗口close时确保关闭即销毁窗口
self._changeWndStyle() # 修改窗体属性
# ----------------------------
self._createFuncBarView() # 初始化功能区更新视图
self._updateFuncBar(CStatusbarView.fnGetGridScript(self.lblMainVariableItems[2])) # 根据当前登录用户类别,刷新功能区状态
# ----------------------------
self._createTimer() # 创建定时器
# ---------------------------------------------------------------
self._setupSignalSlotMapping() # 创建信号映射
self.m_timer.start()
pass
# private:
#------------------------------------------------------------------------------------------------------------
# 界面自适应
def _screenAdapter(self) -> None:
fRatio = getSizeRatio(EOSType.MACOS) # 屏幕尺寸高宽调整比例
realSize = (self._m_arrScreen[0] * fRatio[0], self._m_arrScreen[1] * fRatio[1])
self.setFixedSize(int(realSize[0]), int(realSize[1]))
rctGroups = self._adjustGroupBox(realSize) # 调整主界面上面和左侧的组合框
self._adjustButtonAboutUser(rctGroups[2]) # 调整上面最右侧组合框中的按钮布局
self._adjustStackPage(rctGroups[3], rctGroups[2]) #调整右侧窗口容器空间
self._adjustCapacityStatisticsCtrl() # 调整产能统计相关控件的布局
pass
# 组合框自适应
def _adjustGroupBox(self, screenSize: tuple[float, float]) -> list:
nTopGroupBoxHeight = int(screenSize[1] / 8)
# 设置上面第一个组合框大小
rctTemp: list[QRect] = [QRect(), QRect(), QRect(), QRect()]
rctTemp[0].setTop(g_uiGeometrySize['WND_MARGIN_VERT'])
rctTemp[0].setLeft(g_uiGeometrySize['WND_MARGIN_HORI'])
rctTemp[0].setHeight(nTopGroupBoxHeight)
rctTemp[0].setWidth(int(screenSize[0] / 3))
self.ui.grpMainSysInfo_0.setGeometry(rctTemp[0])
# ---------------------------------
# 设置上面第二个组合框大小
rctTemp[1].setTop(g_uiGeometrySize['WND_MARGIN_VERT'])
rctTemp[1].setLeft(rctTemp[0].right() + g_uiGeometrySize['WND_MARGIN_HORI'])
rctTemp[1].setHeight(nTopGroupBoxHeight)
rctTemp[1].setWidth(int(rctTemp[0].width() * 5 / 3))
self.ui.grpMainSysInfo_1.setGeometry(rctTemp[1])
# 设置上面第三个组合框大小
rctTemp[2].setTop(g_uiGeometrySize['WND_MARGIN_VERT'])
rctTemp[2].setLeft(rctTemp[1].right() + g_uiGeometrySize['WND_MARGIN_HORI'])
rctTemp[2].setHeight(nTopGroupBoxHeight)
rctTemp[2].setWidth(screenSize[0] - rctTemp[0].width() - rctTemp[1].width() - g_uiGeometrySize['WND_MARGIN_HORI'] * 3)
self.ui.grpMainForUser.setGeometry(rctTemp[2])
# 设置功能组合框位置大小
rctTemp[3] = self.ui.grpMainModule.geometry()
rctTemp[3].setTop(rctTemp[0].bottom() + g_uiGeometrySize['WND_MARGIN_VERT'])
rctTemp[3].setLeft(rctTemp[0].left())
rctTemp[3].setHeight(screenSize[1] - g_uiGeometrySize['WND_MARGIN_VERT'] * 2 - rctTemp[0].height() - self._m_status.height())
self.ui.grpMainModule.setGeometry(rctTemp[3])
return rctTemp
# 用户切换和修改密码按钮自适应
def _adjustButtonAboutUser(self, rctSize: QRect) -> None:
nBtnHeight: int = (rctSize.height() - g_uiGeometrySize['WND_MARGIN_VERT'] * 6) / 2
nBtnWidth: int = rctSize.width() - g_uiGeometrySize['WND_MARGIN_HORI'] * 4
rctBtn = QRect()
rctBtn.setLeft(g_uiGeometrySize['WND_MARGIN_HORI'] * 2)
rctBtn.setTop(g_uiGeometrySize['WND_MARGIN_VERT'] * 2)
rctBtn.setWidth(nBtnWidth)
rctBtn.setHeight(nBtnHeight)
self.ui.btnMainSwitchUser.setGeometry(rctBtn)
#---------------------------
nTempHeight = rctBtn.height()
rctBtn.setTop(g_uiGeometrySize['WND_MARGIN_VERT'] * 4 + rctBtn.height())
rctBtn.setHeight(nTempHeight)
self.ui.btnMainChangePasswd.setGeometry(rctBtn)
pass
# 子页面堆栈控件自适应
def _adjustStackPage(self, rctFuncGrp: QRect, rctUserGrp: QRect) -> None:
rctStack = self.ui.stkMainContainer.geometry()
rctStack.setLeft(rctFuncGrp.right() + g_uiGeometrySize['WND_MARGIN_HORI'])
rctStack.setTop(rctFuncGrp.top())
rctStack.setHeight(rctFuncGrp.height())
rctStack.setRight(rctUserGrp.right())
self.ui.stkMainContainer.setGeometry(rctStack)
# 功能组合框,单选按钮自适应排列
def _adjustRdoButtons(self) -> None:
layVert = QVBoxLayout()
layVert.addWidget(self.ui.rdbMainAutoProc, alignment=Qt.AlignmentFlag.AlignHCenter)
layVert.addWidget(self.ui.rdbMainDebug, alignment=Qt.AlignmentFlag.AlignHCenter)
layVert.addWidget(self.ui.rdbMainSetting, alignment=Qt.AlignmentFlag.AlignHCenter)
layVert.addWidget(self.ui.rdbMainQuery, alignment=Qt.AlignmentFlag.AlignHCenter)
layVert.addWidget(self.ui.rdbMainRecipe, alignment=Qt.AlignmentFlag.AlignHCenter)
layVert.addWidget(self.ui.rdbMainUser, alignment=Qt.AlignmentFlag.AlignHCenter)
# 计算组合框内radiobutton之间的垂直间距
grpHeight = self.ui.grpMainModule.geometry().height()
nHeightGap = (grpHeight - g_uiGeometrySize['WND_MARGIN_VERT'] * 4 -
self.ui.rdbMainDebug.height() * 6) / 5
layVert.setSpacing(nHeightGap)
layVert.setContentsMargins(g_uiGeometrySize['WND_MARGIN_HORI'] * 2,
g_uiGeometrySize['WND_MARGIN_VERT'] * 2,
g_uiGeometrySize['WND_MARGIN_HORI'] * 2,
g_uiGeometrySize['WND_MARGIN_VERT'] * 2)
self.ui.grpMainModule.setLayout(layVert)
# 产能统计控件布局排列
def _adjustCapacityStatisticsCtrl(self) -> None:
nSizeArr = (self.ui.grpMainSysInfo_0.geometry().width(), self.ui.grpMainSysInfo_0.geometry().height())
# 计算控件之间的排列间隔宽度
nGapWidth = (nSizeArr[0] - g_uiGeometrySize['WND_MARGIN_VERT'] * 7 - self.ui.lblMainWoodTotal.width()
- self.ui.lblMainWoodNG.width() - self.ui.lblMainPassRate.width() - self.ui.edtMainWoodNG.width() * 3) / 2
# 根据组合框的宽高,布局内部控件
ptPosition = [QPoint(), QPoint(),] # 0: 给label 1给editbox
ptPosition[0].setY(nSizeArr[1] / 2 - g_uiGeometrySize['WND_MARGIN_VERT']) # 设置第一个label的高度位置
ptPosition[0].setX(g_uiGeometrySize['WND_MARGIN_HORI'] * 2) # 设置第一个label的水平位置
nTempCtrlSize = [self.ui.lblMainWoodTotal.width(), self.ui.lblMainWoodTotal.height(),] # 临时存储控件的宽高
self.ui.lblMainWoodTotal.setGeometry(ptPosition[0].x(), ptPosition[0].y(), nTempCtrlSize[0], nTempCtrlSize[1])
# -----------------------------------------------------------
rctTemp = self.ui.lblMainWoodTotal.geometry()
nLabelTop = rctTemp.top()
ptPosition[1].setX(rctTemp.right() + g_uiGeometrySize['WND_MARGIN_HORI'])
ptPosition[1].setY(rctTemp.top() - g_uiGeometrySize['WND_MARGIN_VERT'] / 2)
nTempWidth = self.ui.edtMainWoodTotal.width()
nTempHeight = self.ui.edtMainWoodTotal.height()
self.ui.edtMainWoodTotal.setGeometry(ptPosition[1].x(), ptPosition[1].y(), nTempWidth, nTempHeight)
# -----------------------------------------------------------
rctTemp = self.ui.edtMainWoodTotal.geometry()
nEditTop = rctTemp.top()
ptPosition[0].setX(rctTemp.right() + nGapWidth)
ptPosition[0].setY(nLabelTop)
nTempCtrlSize[0] = self.ui.lblMainWoodNG.width()
nTempCtrlSize[1] = self.ui.lblMainWoodNG.height()
self.ui.lblMainWoodNG.setGeometry(ptPosition[0].x(), ptPosition[0].y(), nTempCtrlSize[0], nTempCtrlSize[1])
# -----------------------------------------------------------
rctTemp = self.ui.lblMainWoodNG.geometry()
ptPosition[1].setX(rctTemp.right() + g_uiGeometrySize['WND_MARGIN_HORI'])
ptPosition[1].setY(nEditTop)
self.ui.edtMainWoodNG.setGeometry(ptPosition[1].x(), ptPosition[1].y(), nTempWidth, nTempHeight)
# -----------------------------------------------------------
rctTemp = self.ui.edtMainWoodNG.geometry()
ptPosition[0].setX(rctTemp.right() + nGapWidth)
nTempCtrlSize[0] = self.ui.lblMainPassRate.width()
nTempCtrlSize[1] = self.ui.lblMainPassRate.height()
self.ui.lblMainPassRate.setGeometry(ptPosition[0].x(), ptPosition[0].y(), nTempCtrlSize[0], nTempCtrlSize[1])
# -----------------------------------------------------------
rctTemp = self.ui.lblMainPassRate.geometry()
ptPosition[1].setX(rctTemp.right() + g_uiGeometrySize['WND_MARGIN_HORI'])
self.ui.edtMainPassRate.setGeometry(ptPosition[1].x(), ptPosition[1].y(), nTempWidth, nTempHeight)
pass
#------------------------------------------------------------------------------------------------------------
# 创建子页面实体
def _createSubPages(self, szStack: tuple[int, int]) -> None:
# 在此处添加每个子页面
self.m_subPages = (CSubPageAutoProc(szStack, self), CSubPageDevDebug(szStack, self),
CSubPageParaSetting(szStack, self), CSubPageQuery(szStack, self),
CSubPageRecipe(self._m_currentUser[0], szStack, self), CSubPageUser(szStack, self))
for item in self.m_subPages:
item.uiInit()
# 将子页面添加到堆栈控件中
def _add2StackWidget(self):
for item in self.m_subPages:
self.ui.stkMainContainer.addWidget(item)
self.ui.stkMainContainer.setCurrentWidget(self.m_subPages[0])
#------------------------------------------------------------------------------------------------------------
# 修改窗体属性
def _changeWndStyle(self):
self.setWindowFlags(Qt.WindowType.Dialog | Qt.WindowType.CustomizeWindowHint |
Qt.WindowType.WindowTitleHint | Qt.WindowType.WindowCloseButtonHint |
Qt.WindowType.WindowMinimizeButtonHint)
pass
# 创建状态栏
def _initStatusBar(self):
self._m_status = QStatusBar(self)
self._m_status.setSizeGripEnabled(True)
self.setStatusBar(self._m_status)
# 添加标签到状态栏,用分隔符区分
nScan: int = 0
while 4 > nScan:
self._m_status.addWidget(self.lblMainConstStatusItems[nScan])
self._m_status.addWidget(self.lblMainVariableItems[nScan])
self._m_status.addWidget(QLabel(g_otherScripts['OTHER_SEPARATOR']))
nScan += 1
else:
self._m_status.addWidget(self.lblMainConstStatusItems[4])
self._m_status.addWidget(self.lblMainVariableItems[4])
# 更新状态栏中的当前登录用户和用户类别
CStatusbarView.fnRefreshGridScript(self.lblMainVariableItems[1], self._m_currentUser[0])
CStatusbarView.fnRefreshGridScript(self.lblMainVariableItems[2], self._m_currentUser[1])
# 更新当前作业状态
CStatusbarView.fnRefreshGridScript(self.lblMainVariableItems[3], g_otherScripts['OTHER_PROC_STATE_0'])
pass
# 创建状态显示标签
def _createStatusLabels(self) -> None:
self.lblMainConstStatusItems = (QLabel(g_uiCtrlScript['WND_STATUSBAR_0']), QLabel(g_uiCtrlScript['WND_STATUSBAR_1']), QLabel(g_uiCtrlScript['WND_STATUSBAR_2']), QLabel(g_uiCtrlScript['WND_STATUSBAR_3']), QLabel(g_uiCtrlScript['WND_STATUSBAR_4']))
self.lblMainVariableItems = [QLabel(''), QLabel(''), QLabel(''), QLabel(''), QLabel('')]
# --------------------------------------------
# 创建主界面功能区视图类
def _createFuncBarView(self) -> None:
lstRdoButtons: list = [self.ui.rdbMainAutoProc, self.ui.rdbMainDebug, self.ui.rdbMainSetting, self.ui.rdbMainQuery,
self.ui.rdbMainRecipe, self.ui.rdbMainUser]
self._m_vwUpdatingFuncBar = CFunctionBarView(lstRdoButtons) # 声明功能区视图
# 更新功能区控件状态
def _updateFuncBar(self, userType: str) -> None:
self._m_vwUpdatingFuncBar.setCtrlsEnabled(userType)
if userType == g_uiCtrlScript['CTRL_USER_TYPE_ADMIN']:
self.ui.rdbMainQuery.setChecked(True)
self._setPageVisibleProperty(ESubPageType.DATAQUERY.value[0])
# --------------------------------------------
# 创建定时器
def _createTimer(self) -> None:
self.m_timer = QTimer(self)
self.m_timer.setTimerType(Qt.TimerType.PreciseTimer)
self.m_timer.setInterval(100)
#--------------------------------------------
# 内嵌页面跳转处理
def _setPageVisibleProperty(self, pageType: int) -> None:
self.ui.stkMainContainer.setCurrentWidget(self.m_subPages[pageType])
# 建立信号槽连接
def _setupSignalSlotMapping(self) -> None:
self.m_timer.timeout.connect(self._onTimer) # 定时器信号
self.ui.rdbMainAutoProc.toggled.connect(self._onClickRdoButton)
self.ui.rdbMainDebug.toggled.connect(self._onClickRdoButton)
self.ui.rdbMainSetting.toggled.connect(self._onClickRdoButton)
self.ui.rdbMainQuery.toggled.connect(self._onClickRdoButton)
self.ui.rdbMainRecipe.toggled.connect(self._onClickRdoButton)
self.ui.rdbMainUser.toggled.connect(self._onClickRdoButton)
self.ui.btnMainSwitchUser.clicked.connect(self._onClickBtnSwitchUser)
self.ui.btnMainChangePasswd.clicked.connect(self._onClickBtnChangePasswd)
pass
# 主界面退出流程
def _quitMainWndProc(self, bQuitType: bool) -> None:
# 先获取登录窗口引用
dlgParent = self.parentWidget()
# 销毁主窗口,显示登录窗口
self.m_timer.stop() # 停止计时器
time.sleep(0.03) # 等待其他操作执行结束
self.close()
# 显示之前的登录窗口
if bQuitType:
QApplication.instance().quit()
else:
dlgParent.show()
# ----------------事件重载----------------
def closeEvent(self, event: QCloseEvent) -> None:
if CStateAutoProc.getProcState():
QMessageBox.information(self, g_uiCtrlScript['MSG_TITLE_TIPS'], g_errMsgText['ERR_AUTOPROC_BUSY'])
event.ignore()
else:
reply = QMessageBox.question(self, g_uiCtrlScript['MSG_TITLE_TIPS'], g_uiCtrlScript['MSG_SCRIPT_CONFIRM'],
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No)
if reply == QMessageBox.StandardButton.Yes:
self._quitMainWndProc(self._m_bQuitType)
event.accept()
else: event.ignore()
# ----------------信号槽接口----------------
@Slot()
def _onTimer(self):
# 定时器响应消息
if 10 == CSubUiMain._m_nTimeCount:
self.lblMainVariableItems[0].setText(CCommon.fnGetCurrentTime())
CSubUiMain._m_nTimeCount = 0
CSubUiMain._m_nTimeCount += 1
# 读取io状态
# g_warnState.setIOReadingException(g_emv.readIO(), g_emv.getIOErrMessage()) # 将反馈结果同步到报警器
@Slot()
def _onClickRdoButton(self):
# 单选按钮关联信号接口
selRdo = self.sender()
strName: str = selRdo.objectName()
if 'rdbMainAutoProc' == strName and self.ui.rdbMainAutoProc.isChecked():
self._setPageVisibleProperty(ESubPageType.AUTOPROC.value[0])
elif 'rdbMainDebug' == strName and self.ui.rdbMainDebug.isChecked():
self._setPageVisibleProperty(ESubPageType.DEVDEBUG.value[0])
elif 'rdbMainSetting' == strName and self.ui.rdbMainSetting.isChecked():
self._setPageVisibleProperty(ESubPageType.PARASETTING.value[0])
elif 'rdbMainQuery' == strName and self.ui.rdbMainQuery.isChecked():
self._setPageVisibleProperty(ESubPageType.DATAQUERY.value[0])
elif 'rdbMainRecipe' == strName and self.ui.rdbMainRecipe.isChecked():
self._setPageVisibleProperty(ESubPageType.RECIPEMANAGE.value[0])
elif 'rdbMainUser' == strName and self.ui.rdbMainUser.isChecked():
self._setPageVisibleProperty(ESubPageType.USERMANAGE.value[0])
@Slot()
def _onClickBtnSwitchUser(self):
self._m_bQuitType = False
self.close()
pass
@Slot()
def _onClickBtnChangePasswd(self):
passwd_dlg = CPasswdChange(self._m_currentUser[0], parent=self)
passwd_dlg.uiInit()
passwd_dlg.exec()
pass