如何在 QMainWindow 中创建菜单栏
Posted
技术标签:
【中文标题】如何在 QMainWindow 中创建菜单栏【英文标题】:How to create a menu-bar in a QMainWindow 【发布时间】:2017-11-20 13:49:21 【问题描述】:我正在使用 PyQT 编写一个小型应用程序。我正在尝试在应用程序顶部创建一个菜单栏,其中包含常用选项(“文件”、“编辑”、“选项”等),但是当我尝试将其添加到 QMainWindow 类时,我的工具栏没有出现。我环顾四周,但对我来说我做错了什么并不明显。请注意,我尝试使用QMainWindow.menuBar()
方法而不是创建QToolbar
,但如果我这样做,则该栏将完全不可见。使用下面的代码,我至少得到一个空栏,即使它是空的。下面的代码是这个问题的一个最小示例。我想知道我必须更改哪些操作才能显示。
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QBrush
from PyQt5.QtWidgets import QMainWindow, QGraphicsScene, QToolBar, QMenu, QAction, QGraphicsView, QApplication
class GraphWindow(QMainWindow):
def __init__(self):
super().__init__()
self.scene = QGraphicsScene()
# a grid foreground
self.scene.setBackgroundBrush(QBrush(Qt.lightGray, Qt.CrossPattern))
self.grid = True
# Create upper toolbar with menu options
tb = QToolBar()
menu = QMenu()
db_action = QAction("Open file")
db_action.setStatusTip("Select a file to use as a database")
db_action.triggered.connect(self.open_new_db)
menu.addAction(db_action)
tb.addWidget(menu)
tb.setAllowedAreas(Qt.TopToolBarArea)
tb.setFloatable(False)
tb.setMovable(False)
self.addToolBar(tb)
self.statusBar().showMessage("Ready")
# Demonstrate the results from the input.
graphics = QGraphicsView(self.scene)
self.setCentralWidget(graphics)
self.showFullScreen()
def open_new_db(self):
pass
def keyPressEvent(self, e):
# Currently, we respond to a press of the Escape key by closing the program.
if e.key() == Qt.Key_Escape:
self.close()
app = QApplication(sys.argv)
gr = GraphWindow()
sys.exit(app.exec_())
【问题讨论】:
您使用的是什么操作系统版本和QT版本?这个could 是bug 我使用elementary OS 0.4.1 Loki 和PyQT 5.9 【参考方案1】:要在菜单栏中创建菜单,您必须给它一个标题。此外,Qt 不获取菜单或操作的所有权,因此您必须为它们提供父级或以其他方式保留对它们的引用,以免它们被垃圾收集。您的示例可以这样修复:
class GraphWindow(QMainWindow):
def __init__(self):
...
# Create menu options
menubar = self.menuBar()
menu = QMenu('File', self) # title and parent
db_action = QAction("Open file", self) # title and parent
db_action.setStatusTip("Select a file to use as a database")
db_action.triggered.connect(self.open_new_db)
menu.addAction(db_action)
menubar.addMenu(menu)
self.statusBar().showMessage("Ready")
请注意,根本不需要工具栏。实现相同目的的一种更短更简单的方法是更直接地添加菜单和操作,如下所示:
menubar = self.menuBar()
menu = menubar.addMenu('File')
db_action = menu.addAction("Open file")
db_action.setStatusTip("Select a file to use as a database")
db_action.triggered.connect(self.open_new_db)
这里,Qt 会在需要的地方自动设置父级。
【讨论】:
谢谢,这正是我需要的。【参考方案2】:问题是由垃圾收集器引起的,变量只保留在创建的上下文中,并且由于您在构造函数中创建了它,因此该 python 方法的结尾将其消除。只有具有父元素或类成员的元素才会保留,因此在此解决方案中使用第一个选项。
class GraphWindow(QMainWindow):
def __init__(self):
[...]
# Create upper toolbar with menu options
tb = QToolBar(self)
menu = QMenu(self)
db_action = QAction("Open file", self)
db_action.setStatusTip("Select a file to use as a database")
db_action.triggered.connect(self.open_new_db)
menu.addAction(db_action)
tb.addWidget(menu)
tb.setAllowedAreas(Qt.TopToolBarArea)
tb.setFloatable(False)
tb.setMovable(False)
self.addToolBar(tb)
self.statusBar().showMessage("Ready")
[...]
【讨论】:
以上是关于如何在 QMainWindow 中创建菜单栏的主要内容,如果未能解决你的问题,请参考以下文章
在没有框架的python中创建一个QMainWindow,尽管它是可移动和可调整大小的