菜單欄
創建單層菜單
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() |
清除菜單 |
