拖拽窗体及代替系统标题栏按键(最小化、缩放、关闭窗体)功能由主菜单实现。
将MyMainWindow对象定义为全局变量,以便在MyMenuBar和QMenuButton类中使用。
MyMainWIndow:
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__() #父类初始化
self.oldPos = None #通过主菜单拖拽窗体时使用
self.setWindowFlags(Qt.FramelessWindowHint) # 隐藏标题栏
self.setMenuBar(MyMenu()) #添加主菜单
MyMenuBar(重载QMenuBar的mousePressEvent、mouseMoveEvent、mouseReleaseEvent、mouseDoubleClickEvent):
class MyMenu(QMenuBar):
def __init__(self):
super(MyMenu, self).__init__() # 初始化父类
subMenu=self.addMenu('subMenu') #添加子菜单
subMenuGeometry = self.actionGeometry(subMenu.menuAction()) #获取子菜单在菜单栏的实际位置
'''
#如果使用subMenu.pos()方法,读出的QPoint是空的。
#如果使用subMenu.Geometry()方法,读出的是QRect(0,0,100,30),但实际并没有100那么宽
'''
self.menuGemotry = QPoint(helpGeometry.topRight().x()+100, self.height())#用来判断鼠标是否在菜单栏有子菜单的位置上
button=QMenuButton(self.height())
self.setCornerWidget(button)
def mousePressEvent(self, event): #重写mousePressEvent事件,记录下鼠标按下时窗体所在的位置
if event.button() == Qt.LeftButton and (self.menuGemotry.x()<event.pos().x() and self.menuGemotry.y()>event.pos().y()):
self.oldPos=event.pos()
super(MyMenu, self).mousePressEvent(event)
def mouseMoveEvent(self, event):#重写mouseMoveEvent事件,根据鼠标拖动时鼠标的位置以及鼠标按下时记录的位置使用窗体的move方法移动窗体
if self.oldPos is not None:
delta = event.pos() - self.oldPos
xrun_global.mainForm.move(xrun_global.mainForm.oldPos + delta)
xrun_global.mainForm.oldPos=xrun_global.mainForm.pos()
else:
super(MyMenu, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.oldPos=None
super(MyMenu, self).mouseReleaseEvent(event)
def mouseDoubleClickEvent(self, event):
if self.menuGemotry.x() < event.pos().x() and self.menuGemotry.y() > event.pos().y():
if mainForm.isMaximized():
mainForm.setWindowState(Qt.WindowNoState)
self.button.zoomButton.setIcon(QIcon('icon/maximum_window_state.ico'))
else:
mainForm.setWindowState(Qt.WindowMaximized)
self.button.zoomButton.setIcon(QIcon('icon/normal_window_state.ico'))
mainForm.oldPos = xrun_global.mainForm.pos()
主菜单自定义按键(最小化、缩放、关闭窗体):
class QMenuButton(QWidget):
def __init__(self,menuHeight):
super(QMenuButton, self).__init__()
self.setContentsMargins(0,0,0,0)#缩小内边距,增加按键判定区域
self.setFixedHeight(menuHeight)
self.setStyleSheet("background-color:#232629")
self.buttonQSS = 'QPushButton {border: none;}\
QPushButton:hover {background-color: #c8c8c8;}'
self.buttonSize = QSize(30, 30)
self.LayoutInit()
self.HideButtonInit()
self.ZoomButtonInit()
self.ExitButtonInit()
def LayoutInit(self):
self.buttonHLayout = QHBoxLayout()
self.buttonHLayout.setContentsMargins(0, 0, 0,0)
self.setLayout(self.buttonHLayout)
def HideButtonInit(self):
self.hideButton = QPushButton("")
self.hideButton.setIcon(QIcon('icon/minimum_window_state.ico'))
self.hideButton.setFixedWidth(30)
self.hideButton.setIconSize(self.buttonSize)
self.hideButton.setStyleSheet(self.buttonQSS)
self.hideButton.clicked.connect(self.HideBUttonClicked)
self.buttonHLayout.addWidget(self.hideButton)
def ZoomButtonInit(self):
self.zoomButton = QPushButton("")
self.zoomButton.setIcon(QIcon('icon/normal_window_state.ico'))
self.zoomButton.setFixedWidth(30)
self.zoomButton.setIconSize(self.buttonSize)
self.zoomButton.setStyleSheet(self.buttonQSS)
self.zoomButton.clicked.connect(self.ZommButtonClicked)
self.buttonHLayout.addWidget(self.zoomButton)
def ExitButtonInit(self):
self.exitButton = QPushButton("")
self.exitButton.setIcon(QIcon('icon/exit.ico'))
self.exitButton.setFixedWidth(30)
self.exitButton.setIconSize(self.buttonSize)
self.exitButton.setStyleSheet(self.buttonQSS)
self.exitButton.clicked.connect(self.ExitButtonClicked)
self.buttonHLayout.addWidget(self.exitButton)
def HideBUttonClicked(self):
xrun_global.mainForm.setWindowState(Qt.WindowMinimized)
def ZommButtonClicked(self):
if mainForm.isMaximized():
mainForm.setWindowState(Qt.WindowNoState)
else:
mainForm.setWindowState(Qt.WindowMaximized)
self.zoomButton.setIcon(QIcon('icon/normal_window_state.ico'))
mainForm.oldPos=mainForm.pos()
def ExitButtonClicked(self):
dialog = QMessageBox(QMessageBox.Information, "Warning", "if you click OK, the software will exit",
QMessageBox.Yes | QMessageBox.No)
flag = dialog.exec_()
if flag == QMessageBox.Yes:
mainForm.close()