Pyside菜单
pyside菜单依旧是一堆坑
全坑写法
import os
import sys
from PySide6.QtGui import *
from PySide6.QtWidgets import *
# macOS 必须显式设应用名称,否则看到 "python"
os.environ['QT_MAC_BUNDLE_APPLICATION_MENU_BAR'] = '1'
QApplication.setApplicationName('MenuTest')
app = QApplication(sys.argv)
# 1. 第一个主窗口——全局菜单诞生
main = QMainWindow()
main.setWindowTitle('Main(菜单持有者)')
bar = main.menuBar() # 此时 main 未 show,无父级
# 2. 把动作放进子菜单 → 系统栏才会显示
fileMenu = bar.addMenu('File')
act = QAction('Test', main)
act.setShortcut('Ctrl+T')
act.triggered.connect(lambda: print('triggered'))
fileMenu.addAction(act)
# 因为show之间建立了菜单, 所以就算关闭也还在. 但是, 一开始又不在, 因为qt延迟show他, sub窗口挡住了他. 所以这种写法属实是自己找别扭.
main.show()
# 3. 再开一个窗口
sub = QMainWindow()
sub.setWindowTitle('Sub')
sub.show()
app.exec()
- 先建立了bar, 后main.show, 因此这个menu依旧是全局menu.
- 但是, 一开始因为窗口sub挡住了窗口main, 此时没有菜单, 必须main窗口被激活(成为key窗口), 菜单才会出现.
- 三联顺序, 不能漏:
- bar = main.menuBar() # 生成bar
- fileMenu = bar.addMenu(‘File’) # 生成一级菜单标题
- fileMenu.addAction(act) # 加入实际act
真正能用的
from PySide6.QtCore import Qt
from PySide6.QtGui import QAction, QKeySequence
from PySide6.QtWidgets import QApplication, QMainWindow, QMenuBar
app = QApplication([])
# 1. 创建无父级的菜单栏 → 自动成为 macOS 全局菜单
global_menu = QMenuBar(None) # 关键:parent=None
# 2. 定义动作(全局快捷键直接设在这里)
new_act = QAction("New", global_menu)
new_act.setShortcut(QKeySequence("Ctrl+N"))
new_act.setShortcutContext(Qt.ApplicationShortcut) # 应用级,确保跨窗口
new_act.triggered.connect(lambda: print("全局 New"))
# 3. 组装菜单
file_menu = global_menu.addMenu("File")
file_menu.addAction(new_act)
aw=[]
# 4. 以后随便开多少个 QMainWindow,都不需要再 setMenuBar()
for i in range(3):
w = QMainWindow()
w.setWindowTitle(f"window-{i}")
w.show()
aw.append(w)
app.exec()
- 此时菜单的第一个不是你设置的名字, 而是python, 不必在意, 打包的info.plist才能设置这个, 下面两个设置是毫无意义的.
- #QApplication.setApplicationName(‘MenuTest’)
- #QApplication.setApplicationDisplayName(“YourApp”)
- 这里定义了一个全局快捷键, 这个是全局快捷键的最佳实践.