翻译自原文:Menus and toolbars in PyQt5

翻译时间 2020 年 8 月 19 日

在 PyQt5 教程的这一部分中,我们创建一个状态栏、菜单栏和一个工具栏。

  • 菜单是位于菜单栏中的一组命令。
  • 工具栏具有应用程序中带有一些常见命令的按钮。
  • 状态栏显示状态信息,通常在应用程序窗口的底部。

QmainWindow

QMainWindow类提供主应用程序窗口。这样可以创建具有状态栏、工具栏和菜单栏的经典应用程序骨架。

状态栏

状态栏是用于显示状态信息的部件。

statusbar.py

#!/usr/bin/python

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.statusBar().showMessage('Ready')

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Statusbar')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

状态栏是在QMainWindow部件的帮助下创建的。

self.statusBar().showMessage('Ready')

为了获取状态栏,我们调用QtWidgets.QMainWindow类的statusBar()方法。方法的首次调用将创建一个状态栏,后续调用返回状态栏对象。showMessage()在状态栏上显示一条消息。

PyQt5 简易菜单

菜单栏是 GUI 应用程序的常见部分,它是一组位于各种菜单中的命令。(Mac OS 对菜单栏的对待方式不同。为了获得类似的结果,我们可以添加以下行:menubar.setNativeMenuBar(False)

simple_menu.py

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QFileInfo


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        root = QFileInfo(__file__).absolutePath()
        exitAct = QAction(QIcon(root + '/exit.png'), '&Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(qApp.quit)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAct)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Simple menu')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在上面的示例中,我们创建一个包含一个菜单的菜单栏。此菜单包含一个操作,如果选中,该操作将终止应用程序。还创建了状态栏。可以使用 Ctrl+Q 快捷方式访问该操作。

root = QFileInfo(__file__).absolutePath()
exitAct = QAction(QIcon(root + '/exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')

QAction是使用菜单栏、工具栏或自定义键盘快捷方式执行的操作抽象。在上面四行中,我们创建一个带有特定图标和"退出"标签的操作。此外,为此操作定义了一个快捷方式。第四行创建状态提示,当我们将鼠标指针悬停在菜单项上时,状态栏中将显示该提示。

exitAct.triggered.connect(qApp.quit)

当我们选择此特定操作时,将发出触发信号。信号连接到QApplication部件的quit()方法。这将终止应用程序。

menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)

menuBar()方法创建一个菜单栏。我们使用addMenu()创建“File”菜单,并添加addAction()操作。

PyQt5 子菜单

子菜单是位于另一个菜单中的菜单。

submenu.py

#!/usr/bin/python

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QMenu, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')

        impMenu = QMenu('Import', self)
        impAct = QAction('Import mail', self)
        impMenu.addAction(impAct)

        newAct = QAction('New', self)

        fileMenu.addAction(newAct)
        fileMenu.addMenu(impMenu)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Submenu')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在示例中,我们有两个菜单项:一个位于"File"菜单中,另一个位于“File”的"Import"子菜单中。

impMenu = QMenu('Import', self)

使用QMenu创建新菜单。

impAct = QAction('Import mail', self)
impMenu.addAction(impAct)

使用addAction()将操作添加到子菜单中。

image-20200819095428995

图:子菜单

PyQt5 复选菜单

在下面的示例中,我们创建一个可以选中和取消选中的菜单。

check_menu.py

#!/usr/bin/python

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')

        menubar = self.menuBar()
        viewMenu = menubar.addMenu('View')

        viewStatAct = QAction('View statusbar', self, checkable=True)
        viewStatAct.setStatusTip('View statusbar')
        viewStatAct.setChecked(True)
        viewStatAct.triggered.connect(self.toggleMenu)

        viewMenu.addAction(viewStatAct)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Check menu')
        self.show()

    def toggleMenu(self, state):

        if state:
            self.statusbar.show()
        else:
            self.statusbar.hide()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

代码示例创建一个包含一个操作的"View"菜单,该操作显示或隐藏状态栏。当将菜单项选中时,状态栏可见。

viewStatAct = QAction('View statusbar', self, checkable=True)

通过checkable选项,我们创建一个可检查菜单。

viewStatAct.setChecked(True)

由于状态栏从一开始就可见,因此我们使用setChecked()方法将复选菜单设置为选中状态。

def toggleMenu(self, state):

    if state:
        self.statusbar.show()
    else:
        self.statusbar.hide()

根据操作的状态,我们显示或隐藏状态栏。

image-20200819095908844

图:复选菜单

PyQt5 上下文菜单

上下文菜单(也称为弹出式菜单)是出现在某些上下文中的命令列表(常见为右键菜单)。例如,在 浏览器中,当我们右键单击网页时,我们会获得上下文菜单,可以重新加载页面、返回或查看页面源。如果我们右键单击工具栏,我们会获得用于管理工具栏的另一个上下文菜单。

context_menu.py

#!/usr/bin/python

import sys
from PyQt5.QtWidgets import QMainWindow, qApp, QMenu, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Context menu')
        self.show()

    def contextMenuEvent(self, event):
        cmenu = QMenu(self)

        newAct = cmenu.addAction("New")
        openAct = cmenu.addAction("Open")
        quitAct = cmenu.addAction("Quit")
        action = cmenu.exec_(self.mapToGlobal(event.pos()))

        if action == quitAct:
            qApp.quit()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

若要使用上下文菜单,我们必须重新实现contextMenuEvent()方法。

action = cmenu.exec_(self.mapToGlobal(event.pos()))

上下文菜单与exec_()方法一起显示。event.pos()从事件对象获取鼠标指针的坐标,并用mapToGlobal()方法将部件坐标转换为全局屏幕坐标。

if action == quitAct:
    qApp.quit()

如果从上下文菜单返回的操作等于退出操作,我们将终止应用程序。

PyQt5 工具栏

菜单对应用程序可以使用的所有命令进行分组。工具栏提供对最常用的命令的快速访问。

toolbar.py

import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QFileInfo

class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):
        root = QFileInfo(__file__).absolutePath()
        exitAct = QAction(QIcon(root + '/exit.png'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.triggered.connect(qApp.quit)

        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(exitAct)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Toolbar')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

在上面的示例中,我们创建一个简单的工具栏。工具栏有一个工具操作,一个退出操作,在触发时终止应用程序。

root = QFileInfo(__file__).absolutePath()
exitAct = QAction(QIcon(root + '/exit.png'), 'Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.triggered.connect(qApp.quit)

与上面的菜单栏示例类似,我们创建一个操作对象。对象具有标签、图标和快捷键绑定。QtGui.QMainWindowquit()方法连接到操作对象的触发信号。

self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)

使用addToolBar()方法创建工具栏。我们使用addAction()将操作对象添加到工具栏中。

image-20200819101135395

图:工具栏

PyQt5 主窗口

在本节的最后一个示例中,我们创建一个菜单栏、工具栏和状态栏,我们还创建一个中央部件。

main_window.py

import sys
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QFileInfo

class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        textEdit = QTextEdit()
        self.setCentralWidget(textEdit)

        root = QFileInfo(__file__).absolutePath()
        exitAct = QAction(QIcon(root + '/exit.png'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit application')
        exitAct.triggered.connect(self.close)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAct)

        toolbar = self.addToolBar('Exit')
        toolbar.addAction(exitAct)

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('Main window')
        self.show()


def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

此代码示例使用菜单栏、工具栏和状态栏创建经典 GUI 应用程序的骨架。

textEdit = QTextEdit()
self.setCentralWidget(textEdit)

在这里,我们创建一个文本编辑部件,并将其设置为QMainWindow的中心部件。中央部件占用所有剩下的空间。

image-20200819101604469

图:主窗口

在 PyQt5 教程的这一部分中,我们使用菜单、工具栏、状态栏和主应用程序窗口。