PYQT “pop up menu”

499 views
Skip to first unread message

aba...@spinvfx.com

unread,
Oct 16, 2018, 12:17:10 AM10/16/18
to Python Programming for Autodesk Maya
Hey all,

I am new to using Qt to design UI’s, as my only background is using maya.cmds. I am slowly learning that you able todo a lot of complex things, but with that it creates a larger learning curve.

I am trying to learn how to recreate the maya - cmds.popupMenu() [this is a right click menu on a button] using only qt to allow me to add; buttons,checkboxes , radial collectives and text fields inside this pop up menu.


Any information would be greatly appreciated

- Adam B

Michael Boon

unread,
Oct 16, 2018, 1:52:51 AM10/16/18
to Python Programming for Autodesk Maya
It depends a lot on the context you're in. If you have created a custom Qt button and you want to give it a right-click menu, a lot of the time you have to do something like this in the __init__ function:
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.showCustomContextMenu)
and then write your own showCustomContextMenu(self, point) function that creates a QMenu and assigns QActions to it, then shows the menu using something like
menu.popup(self.mapToGlobal(point))

If you're accessing your widget through maya.cmds, or you're trying to add a right-click menu to existing Maya controls it would be different.

If your button is a QPushButton, note that you can use setMenu() to give it a little drop-down menu with an arrow (see here), which might be simpler and friendlier.

ajr...@gmail.com

unread,
Oct 16, 2018, 9:29:47 AM10/16/18
to Python Programming for Autodesk Maya
Hey Michael,

Thanks for the reply, I am sorta following what your saying but I think I need more clarification on what you're saying. I was about to create a menu like you talked about at the end (https://pastebin.com/EFJ4TisK) but this is not really what I'm looking todo.

I am really truing to create a popup menu on a QPushButton() like this: https://pasteboard.co/HIILBT2.gif

Hope this helps, as I am a little confused on how to implement what you are saying.

- Adam B.

Justin Israel

unread,
Oct 16, 2018, 1:54:07 PM10/16/18
to python_in...@googlegroups.com
What qualities, specifically, are you after, that are not covered by the code examples? Pictures are fun, but it doesn't clarify if it's left or right click behaviour, if the content of the menu is the focus, if it's the position. 


Hope this helps, as I am a little confused on how to implement what you are saying.

- Adam B.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/04963cac-2347-4ef3-bbc3-8b321864881b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Adam Baker

unread,
Oct 16, 2018, 4:42:33 PM10/16/18
to Python Programming for Autodesk Maya
I’m looking to create a menu that is shown when you preform a right click on a button. The photo was an example for the maya.cmds.popupMenu() that I want to repeat using QT Instead.

Hope this helps

- Adam

Wexler

unread,
Oct 16, 2018, 5:07:54 PM10/16/18
to Python Programming for Autodesk Maya
Here is an example that might put you in the right track...... please note, I did not test this snippet


from functools import partial

class MyUI(window or dialog or widget or whatever...):
   
# create a button
   
self.my_btn = QtWidgets.QPushButton('Right Click Me')
   
# left click
   
self.my_btn.clicked.connect(partial(self.call_def_left))
   
# set it with custom menu Contex
   
self.my_btn.customContextMenuRequested.connect(partial(self.add_menu))


   
# menu thingy, this is the right click
   
def add_menu(self):
       
""" add menus to btns """
        menu
= QtWidgets.QMenu(self)


       
for char_env in [('Char Yes', QtGui.QPixmap('img_char_location')),
                         
('Env Yes', QtGui.QPixmap('img_env_location'))
                         
]:
            action
= QtWidgets.QAction(char_env[1], char_env[0], self,
                                       triggered
=partial(self.call_def_YES))


           
# add the action to the menu
            menu
.addAction(action)


       
# exec' the menu on the position of the cursor
        menu
.exec_(QtGui.QCursor.pos())

Michael Boon

unread,
Oct 16, 2018, 8:21:02 PM10/16/18
to Python Programming for Autodesk Maya
I think Wexler has basically what you need there.
All the self.my_btn stuff should be in a function, probably in __init__ for a simple case.
You might also need
self.my_btn.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
and the connections don't need to use a partial function as long as you accept the correct arguments in your connected functions.

ajr...@gmail.com

unread,
Oct 16, 2018, 9:09:03 PM10/16/18
to Python Programming for Autodesk Maya
I am starting to get a little confused with both replies I was able to capture to left click using self.my_btn.clicked.connect(partial(self.call_def_left)) but unable to show the CustomContextMenu with the right click.

could you please simplify this for me ?

Thanks
- Adam B.

Daniel Wexler

unread,
Oct 17, 2018, 1:44:57 PM10/17/18
to python_in...@googlegroups.com
Errors? Get any?
The btn creation can be anywhere in the window/dialog class.
Than you connect its context to the add_menu def' that execute as you press right click.



--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Justin Israel

unread,
Oct 17, 2018, 4:24:27 PM10/17/18
to python_in...@googlegroups.com
The CustomContextMenu approach requires 2 thing:

1) widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
2) widget.customContextMenuRequested.connect(self.handleMenu)

The first one sets the mode for the way the widget handles context menus to fire the customContextMenuRequested signal when you right click the widget.
The second one connects that customContextMenuRequested signal to a custom function, in this case called handleMenu(). 

For the handler function, Qt will pass you the widget local position if you want it. Otherwise you can have it accept no arguments and pass a position directly:

```python
class MyWidget(QtGui.QWidget):

    def __init__(self):
        super(MyWidget, self).__init__()
        self.resize(600,400)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self._showMenu)

    def _showMenu(self):
        m = QtGui.QMenu()
        m.addAction("test")
        m.exec_(QtGui.QCursor.pos())
```

Also, I want to point out one "gotcha" about the example given by Wexler. When you do something like this:

menu = QMenu(self)
...
menu.exec_()

You are most likely leaking a QMenu instance every time. This is because the menu has been parented to the widget and once you close the menu, the instance hangs around. You can either call menu.deleteLater() after the exec returns, or you can just avoid parenting it to the widget.


Justin
 

Thanks

- Adam B.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

ajr...@gmail.com

unread,
Oct 25, 2018, 1:06:21 AM10/25/18
to Python Programming for Autodesk Maya
Thank you all for you help I Have it working now :D'

- Adam B

Nicolas Combecave

unread,
Oct 25, 2018, 5:39:08 AM10/25/18
to python_in...@googlegroups.com
When we use a qt popupMenu to reproduce the maya native contextual menu, one of the things we noticed and did not like was that maya indicates that there is a contextual menu by changing the icon when you hover a widget.
if you want to adhere to maya style and reproduce this, you have to use this code snippet:

yourWidget.setCursor(QtGui.QCursor(':/rmbMenu.png', hotX=6, hotY=4))

Here, hotX and hotY are values we found that did not offset the cursor position.


Reply all
Reply to author
Forward
0 new messages