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

363 lines
19 KiB
Python
Raw Normal View History

# 主控界面子类
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