如何使用按钮在 PyQt5 中的两个菜单栏之间切换?菜单栏消失

Posted

技术标签:

【中文标题】如何使用按钮在 PyQt5 中的两个菜单栏之间切换?菜单栏消失【英文标题】:How can I use a push button to change between two menu bars in PyQt5? The menu bar disappears 【发布时间】:2019-06-05 09:43:42 【问题描述】:

我有两个自定义 QMenuBar 类 MyMenuBar0MyMenuBar1,我想在按下按钮时从一个菜单栏切换到另一个。下面说明的问题是按下按钮会导致菜单消失。我应该如何设置以允许按钮在菜单之间切换?

示例 1(工作示例,不使用按钮)

当菜单栏作为主窗口的__init__ 方法的一部分进行更改时,一切正常。

class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.setMenuBar( MyMenuBar0(self) ) #first menu bar set
        self.change_menu_bar()    #successful change to the second menu bar

    def change_menu_bar(self):
        self.setMenuBar( MyMenuBar1(self) )

示例 2(问题示例,尝试使用按钮)

当使用按钮重复上述操作时,按下按钮会导致菜单消失。

class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.setMenuBar( MyMenuBar0(self) )
        button  = QtWidgets.QPushButton(self)
        button.clicked.connect( self.button_change_menu_bar )

    def button_change_menu_bar(self, a):
        self.setMenuBar( MyMenuBar1(self) ) #causes the menu bar to disappear

这里是重现问题的完整代码:

示例 1

import sys
from PyQt5 import QtWidgets


class MyMenuBar0(QtWidgets.QMenuBar):
    def __init__(self, parent):
        super().__init__(parent)
        menu        = self.addMenu('Menu 0')
        action0     = QtWidgets.QAction('Action 0', self)
        action1     = QtWidgets.QAction('Action 1', self)
        menu.addAction(action0)
        menu.addAction(action1)


class MyMenuBar1(QtWidgets.QMenuBar):
    def __init__(self, parent):
        super().__init__(parent)
        menu        = self.addMenu('Menu 1')
        action0     = QtWidgets.QAction('Action 2', self)
        action1     = QtWidgets.QAction('Action 3', self)
        menu.addAction(action0)
        menu.addAction(action1)


class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.setMenuBar( MyMenuBar0(self) ) #first menu bar set
        self.change_menu_bar()    #successful change to the second menu bar

    def change_menu_bar(self):
        self.setMenuBar( MyMenuBar1(self) )


if __name__ == '__main__':
    app    = QtWidgets.QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec_())

示例 2

import sys
from PyQt5 import QtWidgets


class MyMenuBar0(QtWidgets.QMenuBar):
    def __init__(self, parent):
        super().__init__(parent)
        menu        = self.addMenu('Menu 0')
        action0     = QtWidgets.QAction('Action 0', self)
        action1     = QtWidgets.QAction('Action 1', self)
        menu.addAction(action0)
        menu.addAction(action1)


class MyMenuBar1(QtWidgets.QMenuBar):
    def __init__(self, parent):
        super().__init__(parent)
        menu        = self.addMenu('Menu 1')
        action0     = QtWidgets.QAction('Action 2', self)
        action1     = QtWidgets.QAction('Action 3', self)
        menu.addAction(action0)
        menu.addAction(action1)



class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.setMenuBar( MyMenuBar0(self) )
        button  = QtWidgets.QPushButton(self)
        button.clicked.connect( self.button_change_menu_bar )

    def button_change_menu_bar(self, a):
        self.setMenuBar( MyMenuBar1(self) )  #causes the menu bar to disappear


if __name__ == '__main__':
    app    = QtWidgets.QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec_())

【问题讨论】:

尝试将button = QtWidgets.QPushButton(self)更改为central_widget = QtWidgets.QWidget() self.setCentralWidget(central_widget) button = QtWidgets.QPushButton(central_widget) 我试过了,但并没有解决问题。菜单仍然消失。 【参考方案1】:

您希望将两个菜单栏都放入 setUI 方法并简化您的代码。这可能对你有用。

class MyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args):
        super().__init__(*args)
        self.setUI()

    def setUI(self):
        self.MenuBar0 = QMenuBar()
        # ...
        self.menuBar1 = QMenuBar()
        # ...
        button  = QPushButton('Toggle')
        button.clicked.connect( self.button_change_menu_bar )

    def button_change_menu_bar(self):
        state = self.menuBar0.isVisible()
        self.menuBar0.setVisible(not state)
        self.menuBar1.setVisible(state)

【讨论】:

感谢您的建议,但这在 PyQt5 中不起作用。 QMenuBar 和 QPushButton 都需要父参数。即使添加了父母,切换行为也不起作用。菜单栏的可见性不会切换。

以上是关于如何使用按钮在 PyQt5 中的两个菜单栏之间切换?菜单栏消失的主要内容,如果未能解决你的问题,请参考以下文章

使用 Tkinter 中的菜单栏在页面之间切换

如何在我的程序中添加 PyQt 菜单栏?

PyQt5+Eric6开发的一个使用菜单栏工具栏的示例

PyQt5——DAY3

如何在pyqt5中的两个窗口之间传递参数?

pyqt5——菜单和工具栏