Adding a Menu Bar using PyQt / PySide2

Hi guys,

Been trying a various alternatives but can’t manage to get things working. What I am trying to do is add a Menu Bar to my window using Qt (Python). I have attached an example of my code below. Any tips / advise would be greatly appreciated. Thanks in advance.

# ===============================
# I M P O R T    M O D U L U E S
# ===============================
import maya.OpenMayaUI as omui

# for Maya 2018+...
try:
  
  from PySide2.QtCore import *
  from PySide2.QtGui import *
  from PySide2.QtWidgets import *
  from PySide2 import __version__
  from shiboken2 import wrapInstance 

# for older versions of Maya...
except ImportError:
  
  from PySide.QtCore import * 
  from PySide.QtGui import * 
  from PySide import __version__
  from shiboken import wrapInstance

# ==========
# C L A S S
# ==========
class Test_UI(QWidget):
    
    def __init__(self, *args, **kwargs):
        
        super(Test_UI, self).__init__(*args, **kwargs)
        
        self.setParent(self.GetMainWindow())
        self.setWindowFlags(Qt.Window)
        
        self.setObjectName('Test_UI_uniqueId')
        self.setWindowTitle('Test User Interface')
        self.setGeometry(50, 50, 280, 150)
        self.initUI()
        
    def GetMainWindow(self):
        
        ptr = omui.MQtUtil.mainWindow()
        mainWindow = wrapInstance(long(ptr), QWidget)
        
        return mainWindow
        
    def initUI(self):
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        
        self.menuBar = QMenuBar()
        self.menu = QMenu()
        self.menuBar.addMenu(self.menu)
        
        self.text = QLabel()
        self.text.setText("Test Window")
        self.text.setAlignment(Qt.AlignCenter)
        
        self.layout.addWidget(self.menuBar, 0, 0, 1, 1)
        self.layout.addWidget(self.text, 0, 0, 1, 1)
        
if __name__ == "__main__":
    
    Test_UI(Test_UI().GetMainWindow()).show() # show UI

You probably want to specify a parent for your menuBar, self.menuBar = QMenuBar(self).
Probably also true for the rest of the sub objects. They are possibly getting garbage collected as nothing is being told to keep them alive.

Thanks for the prompt reply, R.White.

Apologies for the confusion but what do you mean ‘specify a parent’? How would I go about doing that?

image
QMenuBar takes a parent as an argument in its constructor.

https://doc.qt.io/qtforpython/PySide2/QtWidgets/QMenuBar.html

1 Like

This is also rather wasteful, as you’re building a whole instance of your UI just to get the main window.

Probably better to just define GetMainWindow as a stand alone function. Plus you can reuse it for future GUIs.

Thanks for pointing me in the proper direction, Katz and R.White. I think I finally got something that works. R.White–you’re completely right. Much better now.

I appreciate all the help. Let me know if there is anything else that stands out.

# ===============================
# I M P O R T    M O D U L U E S
# ===============================
import maya.OpenMayaUI as omui

# for Maya 2018+...
try:
  
  from PySide2.QtCore import *
  from PySide2.QtGui import *
  from PySide2.QtWidgets import *
  from PySide2 import __version__
  from shiboken2 import wrapInstance 

# for older versions of Maya...
except ImportError:
  
  from PySide.QtCore import * 
  from PySide.QtGui import * 
  from PySide import __version__
  from shiboken import wrapInstance

# ==========
# C L A S S
# ==========
class Test_UI(QWidget):
    
    def __init__(self, *args, **kwargs):
        
        super(Test_UI, self).__init__(*args, **kwargs)
        
        self.setParent(self.GetMainWindow())
        self.setWindowFlags(Qt.Window)
        
        self.setObjectName('Test_UI_uniqueId')
        self.setWindowTitle('Test User Interface')
        self.setGeometry(50, 50, 280, 150)
        self.initUI()
        
    def GetMainWindow(self):
        
        ptr = omui.MQtUtil.mainWindow()
        mainWindow = wrapInstance(long(ptr), QWidget)
        
        return mainWindow
        
    def initUI(self):
        
        self.layout = QGridLayout(self)
        self.setLayout(self.layout)
        
        self.menuBar = QMenuBar(parent = self.GetMainWindow()) # requires parent
        self.menu = QMenu(self)
        self.menu.setTitle("Menu")
        self.menuBar.addMenu(self.menu)
        self.menu.addAction("Menu Item")
        self.menu.triggered[QAction].connect(self.MenuAction)
        
        self.text = QLabel(self)
        self.text.setText("Test Window")
        self.text.setAlignment(Qt.AlignCenter)
        
        self.layout.addWidget(self.menuBar, 0, 0, 1, 1)
        self.layout.addWidget(self.text, 0, 0, 1, 1)
        
    def MenuAction(self):
        print("Menu Works.")
        
if __name__ == "__main__":
    
    Test_UI().show() # show UI