PyQt5 menubar.setNativeMenuBar(True) does nothing on MacOS Monterey
-
Hi and welcome to devnet,
What exactly are you expecting when setting that value to True ? It's the default value.
-
Hi @SGaist
I might be wrong but when you set it to true, the menu bar should be displayed to the native position on the system (top of the app for Windows; on the menu bar for MacOS). Currently, it does not put it in the native position, and it disappears completely. When it's set to false, it works just fine, and it sits inside the actual app window. Its default value being true makes sense, since before I found this function and used it the menu bar was completely inexistent; exactly like it is right now as it's set to true. I used Designer to create the UI file (which includes the menubar) so could that be the problem? Do I have to create it manually in the .py file if I want the position to be native to the system? I also couldn't find anything related to the menubar in the privacy & security tab in the settings, so I don't think it's a permission issue.
-
Ok, it's clearer now. Looks wrong as it should work out of the box.
I would check two things:
- that the menu menuBar returns has the proper content (I suspect not) and check whether the one you defined is not empty
- generate the python code with the PyQt5 pyuic tool to see if it does things correctly in contrast with loadUi
-
Ok, it's clearer now. Looks wrong as it should work out of the box.
I would check two things:
- that the menu menuBar returns has the proper content (I suspect not) and check whether the one you defined is not empty
- generate the python code with the PyQt5 pyuic tool to see if it does things correctly in contrast with loadUi
Hi @SGaist
Since the menubar can modify setNativeMenuBar() of the menubar widget, I would assume it returns the proper content.
After generating the python code from the terminal and modifying my main file, it works exactly the same as it did when I used loadUi.
main .py file:
import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QMainWindow, QDialog, QPushButton, QPlainTextEdit, QMenuBar, QMenu, QAction ) from PyQt5.uic import loadUi from MainWindow import Ui_MainWindow class MainWindow(QMainWindow): def __init__(self): super(QMainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.show() app = QApplication(sys.argv) window = MainWindow() app.exec_()
UI .py file
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file # # Created by: PyQt5 UI code generator 5.15.7 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.setWindowModality(QtCore.Qt.NonModal) MainWindow.resize(1000, 650) MainWindow.setStyleSheet("") MainWindow.setDocumentMode(False) MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget) self.plainTextEdit.setGeometry(QtCore.QRect(0, 0, 1001, 601)) self.plainTextEdit.setBaseSize(QtCore.QSize(0, 0)) font = QtGui.QFont() font.setFamily("Apple Color Emoji") font.setPointSize(24) self.plainTextEdit.setFont(font) self.plainTextEdit.setStyleSheet("") self.plainTextEdit.setBackgroundVisible(False) self.plainTextEdit.setObjectName("plainTextEdit") MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setEnabled(True) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setEnabled(True) self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 24)) self.menubar.setMinimumSize(QtCore.QSize(0, 0)) self.menubar.setBaseSize(QtCore.QSize(0, 0)) self.menubar.setStyleSheet("") self.menubar.setDefaultUp(False) self.menubar.setNativeMenuBar(True) self.menubar.setObjectName("menubar") self.menuSettings = QtWidgets.QMenu(self.menubar) self.menuSettings.setMinimumSize(QtCore.QSize(0, 0)) self.menuSettings.setObjectName("menuSettings") self.menuFile = QtWidgets.QMenu(self.menubar) self.menuFile.setObjectName("menuFile") self.menuEdit = QtWidgets.QMenu(self.menubar) self.menuEdit.setObjectName("menuEdit") MainWindow.setMenuBar(self.menubar) self.actionPreferences = QtWidgets.QAction(MainWindow) self.actionPreferences.setObjectName("actionPreferences") self.menuSettings.addAction(self.actionPreferences) self.menubar.addAction(self.menuSettings.menuAction()) self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuEdit.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "NeoText")) self.menuSettings.setTitle(_translate("MainWindow", "Settings")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.menuEdit.setTitle(_translate("MainWindow", "Edit")) self.actionPreferences.setText(_translate("MainWindow", "Preferences"))
Really not sure what could be going on here.
The code:
#!/usr/bin/python """ ZetCode PyQt5 tutorial This program creates a submenu. Author: Jan Bodnar Website: zetcode.com """ 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()
From the Zetcode website (https://zetcode.com/gui/pyqt5/menustoolbars/) works fine though, it creates a native menubar which is visible and works, so that pretty much rules it out from being an issue with MacOS.
-
Alright, I figured it out. Looks like it's half a MacOS thing and half my fault.
Menubars on MacOS are weird, like 'Settings' and 'Edit' are preserved and they're just wank. It turns out that (apparently) you can't have a 'Settings' menu being MacOS preserves it under a different menu and all that. It also seems that in order for a menu (at least the ones which are not preserved) to natively be displayed, they must have a sub menu. My mistake was that I only gave 'Settings' a sub menu but since it's preserved, it isn't allowed to exist. Weirdly, a few minutes after opening the application, 'Edit' pops up, but it isn't the menu I created, it's most likely the MacOS 'Edit' since the only sub menu under it is the emojis and symbols menu.
Weird, but hopefully this helps people out.
-
From the looks of it, you have two issues:
- Your menus have no text but File and Edit are special cases on macOS as well as Preferences
- Your menus are empty
-
From the looks of it, you have two issues:
- Your menus have no text but File and Edit are special cases on macOS as well as Preferences
- Your menus are empty
Yeah, weird though since empty menus are allowed when not using the native menu bar.
I changed 'Preferences' to something else in the 'Settings' menu and it displayed properly next to 'File.' Is it possible to put the 'Settings' menu into the "proper" MacOS place (under the [App name] menubar)?
-
Yeah, weird though since empty menus are allowed when not using the native menu bar.
I changed 'Preferences' to something else in the 'Settings' menu and it displayed properly next to 'File.' Is it possible to put the 'Settings' menu into the "proper" MacOS place (under the [App name] menubar)?
@Ard_Flamingo said in PyQt5 menubar.setNativeMenuBar(True) does nothing on MacOS Monterey:
Is it possible to put the 'Settings' menu into the "proper" MacOS place (under the [App name] menubar)?
See Menu Role
-
Thanks everyone. Everything is working now! Just have to ask, could 'Preferences' be any lower? I hate it being so high on the list.
-
Thanks everyone. Everything is working now! Just have to ask, could 'Preferences' be any lower? I hate it being so high on the list.
@Ard_Flamingo said in PyQt5 menubar.setNativeMenuBar(True) does nothing on MacOS Monterey:
could 'Preferences' be any lower? I hate it being so high on the list.
No it can't and this is the place where users expect it to be
-
The position of Preferences is managed by macOS and not something you should try to change as it would break the macOS guidelines.