Fork me on GitHub

PyQt5笔记之菜单栏

菜单栏

创建单层菜单

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


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.statusBar().showMessage("状态栏:无")
        self.setWindowTitle("单层菜单栏")
        self.setMinimumSize(160, 160)
        self.resize(360, 280)
        self.createActions()
        self.createMenus()

    def createActions(self):
        self.newAct = QAction("新建", self)
        self.newAct.setShortcut("Ctrl+N")
        self.newAct.setStatusTip("状态栏:新建")
        self.newAct.triggered.connect(self.new)

        self.openAct = QAction("打开", self)
        self.openAct.setShortcut("Ctrl+O")
        self.openAct.setStatusTip("状态栏:打开")
        self.openAct.triggered.connect(self.openf)

        self.exitAct = QAction("退出", self)
        self.exitAct.setShortcut("Ctrl+E")
        self.exitAct.setStatusTip("状态栏:退出")
        self.exitAct.triggered.connect(self.close)

    def createMenus(self):
        fileMenu = self.menuBar().addMenu("文件 (&F)")
        fileMenu.addAction(self.newAct)
        fileMenu.addAction(self.openAct)
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAct)

    def new(self):
        pass

    def openf(self):
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

代码分析:

11行:创建一个状态栏,并显示消息

self.statusBar().showMessage("状态栏:无")

12行:设置应用的标题

self.setWindowTitle("单层菜单栏")

13行:设置窗口能缩小的最小值

self.setMinimumSize(160, 160)

14行:设置窗口的默认大小

self.resize(360, 280)

19行:创建一个动作

self.newAct = QAction("新建", self)

20行:为该动作设置快捷键

self.newAct.setShortcut("Ctrl+N")

21行:为该动作设置状态栏显示的信息

self.newAct.setStatusTip("状态栏:新建")

22行:为该动作的triggered信号绑定槽 (self.new)

self.newAct.triggered.connect(self.new)

32行:这里的槽直接使用就好,不用自己再创建,因为有这个方法了;self.close = QMainWindow.close()

self.exitAct.triggered.connect(self.close)

35行:为主窗口创建一个菜单栏,并添加一个名为文件的菜单;(&F)表示可以使用快捷键Alt+F来快速选择它

fileMenu = self.menuBar().addMenu("文件 (&F)")

36行:为菜单添加一个动作 (self.newAct),改动作已在19行创建并设置好了。

fileMenu.addAction(self.newAct)

38行:添加一个分隔符

fileMenu.addSeparator()

创建多层菜单

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


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.statusBar().showMessage("状态栏:无")
        self.setWindowTitle("单层菜单栏")
        self.setMinimumSize(160, 160)
        self.resize(360, 280)
        self.createActions()
        self.createMenus()

    def createActions(self):
        self.newAct = QAction("新建", self)
        self.newAct.setShortcut("Ctrl+N")
        self.newAct.setStatusTip("状态栏:新建")
        self.newAct.triggered.connect(self.new)

        self.openAct = QAction("打开", self)
        self.openAct.setShortcut("Ctrl+O")
        self.openAct.setStatusTip("状态栏:打开")
        self.openAct.triggered.connect(self.openf)

        self.exitAct = QAction("退出", self)
        self.exitAct.setShortcut("Ctrl+E")
        self.exitAct.setStatusTip("状态栏:退出")
        self.exitAct.triggered.connect(self.close)

        self.setAct = QAction("设置", self)
        self.setAct.setStatusTip("状态栏:设置")

    def createMenus(self):
        fileMenu = self.menuBar().addMenu("文件 (&F)")
        fileMenu.addAction(self.newAct)
        fileMenu.addAction(self.openAct)
        moreMenu = fileMenu.addMenu("更多... (&M)")	# 在菜单中添加一个菜单
        moreMenu.addAction(self.setAct)				 # 位子菜单添加动作
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAct)

    def new(self):
        pass

    def openf(self):
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

只是添加了几条代码,已经注释,也可以看 创建单层菜单

如果要创建更多层菜单,只需要向菜单中添加菜单即可

例如:

Amenu = self.menuBar().addMenu("父菜单")
Bmenu = Amenu.addMenu("第一层")
Cmenu = Bmenu.addMenu("第二层")

右键打开菜单

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


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.cutAct = QAction("&Cut", self)
        self.copyAct = QAction("&Copy", self)
        self.pasteAct = QAction("&Paste", self)

    def contextMenuEvent(self, event):
        menu = QMenu(self)
        menu.addAction(self.cutAct)
        menu.addAction(self.copyAct)
        menu.addAction(self.pasteAct)
        menu.exec(event.globalPos())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

官方菜单实例

源码是C++语言的。研究了半天,还好长得差不多,Python算是写出来了。

官方菜单示例:https://doc.qt.io/qt-5/qtwidgets-mainwindows-menus-example.html# (了解更多就看看这个吧)

官方示例源码:https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/mainwindows/menus/mainwindow.cpp?h=5.13

import sys
from PyQt5.QtWidgets import QMessageBox, QActionGroup, QVBoxLayout, QFrame, QLabel, QSizePolicy, QApplication, QMenu, QMenuBar, QMainWindow, QWidget, QAction
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QKeySequence, QFont


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        widget = QWidget(self)
        self.setCentralWidget(widget)

        self.topFiller = QWidget(self)
        self.topFiller.setSizePolicy(QSizePolicy.Expanding,  QSizePolicy.Expanding)

        self.infolabel = QLabel("<i>Choose a menu option, or right-click to invoke a context menu</i>")
        self.infolabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.infolabel.setAlignment(Qt.AlignCenter)

        self.bottomFiller = QWidget(self)
        self.bottomFiller.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(5, 5, 5, 5)
        self.layout.addWidget(self.topFiller)
        self.layout.addWidget(self.infolabel)
        self.layout.addWidget(self.bottomFiller)
        widget.setLayout(self.layout)

        self.createActions()
        self.createMenus()

        self.statusBar().showMessage("A context menu is available by right-clicking")

        self.setWindowTitle("Menu")
        self.setMinimumSize(160, 160)
        self.resize(480, 320)


    def contextMenuEvent(self, event):
        menu = QMenu(self)
        menu.addAction(self.cutAct)
        menu.addAction(self.copyAct)
        menu.addAction(self.pasteAct)
        menu.exec(event.globalPos())

    def createActions(self):
        self.newAct = QAction("&New", self)
        self.newAct.setShortcuts(QKeySequence.New)
        self.newAct.setStatusTip("Create a new file")
        self.newAct.triggered.connect(self.newFile)

        self.openAct = QAction("&Opem", self)
        self.openAct.setShortcuts(QKeySequence.Open)
        self.openAct.setStatusTip("Open an existing file")
        self.openAct.triggered.connect(self.opens)

        self.saveAct = QAction("&Save", self)
        self.saveAct.setShortcuts(QKeySequence.Save)
        self.saveAct.setStatusTip("")
        self.saveAct.triggered.connect(self.save)

        self.printsAct = QAction("&Print", self)
        self.printsAct.setShortcuts(QKeySequence.Print)
        self.printsAct.setStatusTip("Print the document")
        self.printsAct.triggered.connect(self.prints)

        self.exitAct = QAction("&Exit", self)
        self.exitAct.setShortcuts(QKeySequence.Quit)
        self.exitAct.setStatusTip("Exit the application")
        self.exitAct.triggered.connect(self.close)

        self.undoAct = QAction("&Undo", self)
        self.undoAct.setShortcuts(QKeySequence.Undo)
        self.undoAct.setStatusTip("Undo the last operation")
        self.undoAct.triggered.connect(self.undo)

        self.redoAct = QAction("&Redo", self)
        self.redoAct.setShortcuts(QKeySequence.Redo)
        self.redoAct.setStatusTip("Redo the last operation")
        self.redoAct.triggered.connect(self.redo)

        self.cutAct = QAction("&Cut", self)
        self.cutAct.setShortcuts(QKeySequence.Cut)
        self.cutAct.setStatusTip("Cut the current selection's contents to the clipboard")
        self.cutAct.triggered.connect(self.cut)

        self.copyAct = QAction("&Copy", self)
        self.copyAct.setShortcuts(QKeySequence.Copy)
        self.copyAct.setStatusTip("Copy the current selection's contents to the clipboard")
        self.copyAct.triggered.connect(self.copy)

        self.pasteAct = QAction("&Paste", self)
        self.pasteAct.setShortcuts(QKeySequence.Paste)
        self.pasteAct.setStatusTip("Paste the clipboard's contents into the current selection")
        self.pasteAct.triggered.connect(self.paste)

        self.boldAct = QAction("&Bold", self)
        self.boldAct.setShortcuts(QKeySequence.Bold)
        self.boldAct.setStatusTip("Make the text bold")
        self.boldAct.triggered.connect(self.bold)
        self.boldFont = QFont()
        self.boldFont.setBold(True)
        self.boldAct.setFont(self.boldFont)

        self.italicAct = QAction("&Italic", self)
        self.italicAct.setCheckable(True)
        self.italicAct.setShortcut(QKeySequence.Italic)
        self.italicAct.setStatusTip("Make the text italic")
        self.italicAct.triggered.connect(self.italic)
        self.italicFont = QFont()
        self.italicFont.setItalic(True)
        self.italicAct.setFont(self.italicFont)

        self.setLineSpacingAct = QAction("Set &Line Spacing...", self)
        self.setLineSpacingAct.setStatusTip("Change the gap between the lines of a paragraph")
        self.setLineSpacingAct.triggered.connect(self.setParagraphSpacing)

        self.setParagraphSpacingAct = QAction("Set &Paragraph Spacing...", self)
        self.setParagraphSpacingAct.setStatusTip("Change the gap between paragraphs")
        self.setParagraphSpacingAct.triggered.connect(self.setParagraphSpacing)

        self.aboutAct = QAction("&About", self)
        self.aboutAct.setStatusTip("Show the application's About box")
        self.aboutAct.triggered.connect(self.about)

        self.aboutQtAct = QAction("About &Qt", self)
        self.aboutQtAct.setStatusTip("Show the Qt library's About box")
        self.aboutQtAct.triggered.connect(QApplication.aboutQt)
        self.aboutQtAct.triggered.connect(self.aboutQt)

        self.leftAlignAct = QAction("&Left Align", self)
        self.leftAlignAct.setCheckable(True)
        self.leftAlignAct.setShortcut("Ctrl+L")
        self.leftAlignAct.setStatusTip("Left align the selected tetx")
        self.leftAlignAct.triggered.connect(self.leftAlign)

        self.rightAlignAct = QAction("&Right Align", self)
        self.rightAlignAct.setCheckable(True)
        self.rightAlignAct.setShortcut("Ctrl+R")
        self.rightAlignAct.setStatusTip("Right algin the selected text")
        self.rightAlignAct.triggered.connect(self.rightAlign)

        self.justifyAct = QAction("&Justify", self)
        self.justifyAct.setCheckable(True)
        self.justifyAct.setShortcut("Ctrl+J")
        self.justifyAct.setStatusTip("Justify the selected text")
        self.justifyAct.triggered.connect(self.justify)

        self.centerAct = QAction("&Center", self)
        self.centerAct.setCheckable(True)
        self.centerAct.setShortcut("Ctrl+E")
        self.centerAct.setStatusTip("Center the selected text")
        self.centerAct.triggered.connect(self.center)

        self.alignmentGroup = QActionGroup(self)
        self.alignmentGroup.addAction(self.leftAlignAct)
        self.alignmentGroup.addAction(self.rightAlignAct)
        self.alignmentGroup.addAction(self.justifyAct)
        self.alignmentGroup.addAction(self.centerAct)
        self.leftAlignAct.setChecked(True)

    def createMenus(self):

        fileMenu = self.menuBar().addMenu("&File")
        fileMenu.addAction(self.newAct)
        fileMenu.addAction(self.openAct)
        fileMenu.addAction(self.saveAct)
        fileMenu.addAction(self.printsAct)
        fileMenu.addSeparator()
        fileMenu.addAction(self.exitAct)

        editMenu = self.menuBar().addMenu("&Edit")
        editMenu.addAction(self.undoAct)
        editMenu.addAction(self.redoAct)
        editMenu.addSeparator()
        editMenu.addAction(self.cutAct)
        editMenu.addAction(self.copyAct)
        editMenu.addAction(self.pasteAct)
        editMenu.addSeparator()

        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction(self.aboutAct)
        helpMenu.addAction(self.aboutQtAct)

        formatMenu = editMenu.addMenu("&Help")
        formatMenu.addAction(self.boldAct)
        formatMenu.addAction(self.italicAct)
        formatMenu.addSeparator().setText("Alignment")
        formatMenu.addAction(self.leftAlignAct)
        formatMenu.addAction(self.rightAlignAct)
        formatMenu.addAction(self.justifyAct)
        formatMenu.addAction(self.centerAct)
        formatMenu.addSeparator()
        formatMenu.addAction(self.setLineSpacingAct)
        formatMenu.addAction(self.setParagraphSpacingAct)


    def newFile(self):
        self.infolabel.setText("Invoked <b>File|New</b>")

    def opens(self):
        self.infolabel.setText("Invoked <b>File|Open</b>")

    def save(self):
        self.infolabel.setText("Invoked <b>File|Save</b>")

    def prints(self):
        self.infolabel.setText("Invoked <b>File|Print</b>")

    def undo(self):
        self.infolabel.setText("Invoked <b>Edit|Undo</b>")

    def redo(self):
        self.infolabel.setText("Invoked <b>Edit|Redo</b>")

    def cut(self):
        self.infolabel.setText("Invoked <b>Edit|Cut</b>")

    def copy(self):
        self.infolabel.setText("Invoked <b>Edit|Copy</b>")

    def paste(self):
        self.infolabel.setText("Invoked <b>Edit|Paste</b>")

    def bold(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Bold</b>")

    def italic(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Italic</b>")

    def leftAlign(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Left Align</b>")

    def rightAlign(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Right Align</b>")

    def justify(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Justify</b>")

    def center(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Center</b>")

    def setLineSpacing(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Set Line Spacing</b>")

    def setParagraphSpacing(self):
        self.infolabel.setText("Invoked <b>Edit|Format|Set Paragraph Spacing</b>")

    def about(self):
        self.infolabel.setText("Invoked <b>Help|About</b>")
        QMessageBox.information(self, "About Menu", "The <b>Menu</b> example shows how to create menu-bar menus and context menus.")

    def aboutQt(self):
        self.infolabel.setText("Invoked <b>Help|About Qt</b>")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

菜单常用方法

方法 案例 描述
QMenu().setIcon() QMenu().setIcon(QIcon("D:\\.cookie.png")) 为菜单设置一个图标,默认预留一个空位
QMenu().setSeparatorsCollapsible() QMenu().setSeparatorsCollapsible(False) 是否将多个连续的分隔符合并为一个;True表示合并,False表示不合并,默认为True
QMenu().setTearOffEnabled() QMenu.setTearOffEnabled(True) 菜单能否被撕下(移动,变成独立的小窗口),True可以撕下,False不可以,默认为False
QMenu().setTitle() QMenu().setTitle("文件 (&F)") 设置菜单的标题
QMenu().aboutToShow() QMenu().aboutToShow.connect(self.func) 将该信号绑定到一个槽;当你点击菜单后显示出来就会发送此信号(不常用)
QMenu().aboutToHide() QMenu().aboutToHide.connect(self.func) 将该信号绑定到一个槽;当你的菜单隐藏后就会发送此信号(不常用)
QMenu().hovered() QMenu().hovered.connect(self.func) 将该信号绑定到一个槽;当你的鼠标滑过或悬停在菜单时就会发送此信号(不建议用)
QMenu().triggered() QMenu().triggered.connect(self.func) 将该信号绑定到一个槽;当你点击了菜单下的动作(QAction)时会发送此信号(注意:菜单下的菜单不会被触发)
QMenu().addSeparator() QMenu().addSeparator() 为菜单添加分隔符
QMenu().setShortcut() QMenu().setShortcut("Ctrl+A") 设置快捷键
QMenu().clear() QMenu().clear() 清除菜单

posted on 2019-09-24 18:50  刘合栋  阅读(1683)  评论(0编辑  收藏  举报