Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PyQt5 menubar.setNativeMenuBar(True) does nothing on MacOS Monterey
Forum Updated to NodeBB v4.3 + New Features

PyQt5 menubar.setNativeMenuBar(True) does nothing on MacOS Monterey

Scheduled Pinned Locked Moved Solved Qt for Python
12 Posts 3 Posters 2.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Ard_FlamingoA Offline
    Ard_FlamingoA Offline
    Ard_Flamingo
    wrote on last edited by
    #1

    I've been making a text editor using the PyQt5 framework (I chose this older version since there's more tutorials for it) and I've made a simple menu bar in Designer. In the class for the Main Window UI, setting menubar.setNativeMenuBar(True) does nothing, while setting it to False does as it's intended to, it creates the menu bar inside the actual app, not the MacOS menu bar. I want it to be native but setting the function to True does nothing. My code:

    .py file

    import sys
    from PyQt5.QtWidgets import (
        QApplication, QWidget, QMainWindow, QDialog, QPushButton, QPlainTextEdit, QMenuBar, QMenu, QAction
    )
    from PyQt5.uic import loadUi
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(QMainWindow, self).__init__()
            loadUi("MainWindow.ui", self)
            menubar = self.menuBar()
            menubar.setNativeMenuBar(True)
            self.show()
    
    
    app = QApplication(sys.argv)
    
    
    window = MainWindow()
    
    
    app.exec_()
    

    .ui file:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>1000</width>
        <height>650</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>NeoText</string>
      </property>
      <property name="styleSheet">
       <string notr="true"/>
      </property>
      <property name="documentMode">
       <bool>false</bool>
      </property>
      <property name="tabShape">
       <enum>QTabWidget::Rounded</enum>
      </property>
      <widget class="QWidget" name="centralwidget">
       <widget class="QPlainTextEdit" name="plainTextEdit">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>1001</width>
          <height>601</height>
         </rect>
        </property>
        <property name="baseSize">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="font">
         <font>
          <family>Apple Color Emoji</family>
          <pointsize>24</pointsize>
         </font>
        </property>
        <property name="styleSheet">
         <string notr="true"/>
        </property>
        <property name="backgroundVisible">
         <bool>false</bool>
        </property>
       </widget>
      </widget>
      <widget class="QStatusBar" name="statusbar">
       <property name="enabled">
        <bool>true</bool>
       </property>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="enabled">
        <bool>true</bool>
       </property>
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>1000</width>
         <height>24</height>
        </rect>
       </property>
       <property name="minimumSize">
        <size>
         <width>0</width>
         <height>0</height>
        </size>
       </property>
       <property name="baseSize">
        <size>
         <width>0</width>
         <height>0</height>
        </size>
       </property>
       <widget class="QMenu" name="menuSettings">
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="title">
         <string>Settings</string>
        </property>
        <addaction name="actionPreferences"/>
       </widget>
       <widget class="QMenu" name="menuFile">
        <property name="title">
         <string>File</string>
        </property>
       </widget>
       <widget class="QMenu" name="menuEdit">
        <property name="title">
         <string>Edit</string>
        </property>
       </widget>
       <addaction name="menuSettings"/>
       <addaction name="menuFile"/>
       <addaction name="menuEdit"/>
      </widget>
      <action name="actionPreferences">
       <property name="text">
        <string>Preferences</string>
       </property>
      </action>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    Thanks in advance, I've really been hitting my head over this.

    1 Reply Last reply
    0
    • Ard_FlamingoA Offline
      Ard_FlamingoA Offline
      Ard_Flamingo
      wrote on last edited by
      #6

      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.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi and welcome to devnet,

        What exactly are you expecting when setting that value to True ? It's the default value.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • Ard_FlamingoA Offline
          Ard_FlamingoA Offline
          Ard_Flamingo
          wrote on last edited by Ard_Flamingo
          #3

          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.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            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

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            Ard_FlamingoA 1 Reply Last reply
            0
            • SGaistS SGaist

              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
              Ard_FlamingoA Offline
              Ard_FlamingoA Offline
              Ard_Flamingo
              wrote on last edited by Ard_Flamingo
              #5

              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.

              1 Reply Last reply
              0
              • Ard_FlamingoA Offline
                Ard_FlamingoA Offline
                Ard_Flamingo
                wrote on last edited by
                #6

                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.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  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

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  Ard_FlamingoA 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    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
                    Ard_FlamingoA Offline
                    Ard_FlamingoA Offline
                    Ard_Flamingo
                    wrote on last edited by
                    #8

                    @SGaist

                    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)?

                    M 1 Reply Last reply
                    0
                    • Ard_FlamingoA Ard_Flamingo

                      @SGaist

                      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)?

                      M Offline
                      M Offline
                      mpergand
                      wrote on last edited by
                      #9

                      @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

                      1 Reply Last reply
                      0
                      • Ard_FlamingoA Offline
                        Ard_FlamingoA Offline
                        Ard_Flamingo
                        wrote on last edited by Ard_Flamingo
                        #10

                        Thanks everyone. Everything is working now! Just have to ask, could 'Preferences' be any lower? I hate it being so high on the list.

                        M 1 Reply Last reply
                        0
                        • Ard_FlamingoA Ard_Flamingo

                          Thanks everyone. Everything is working now! Just have to ask, could 'Preferences' be any lower? I hate it being so high on the list.

                          M Offline
                          M Offline
                          mpergand
                          wrote on last edited by
                          #11

                          @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

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #12

                            The position of Preferences is managed by macOS and not something you should try to change as it would break the macOS guidelines.

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved