Skip to content
Advertisement

Multiple context menu in a single qTableView pyqt5

i added two functions in two different pushButtons. for both function i used a common qtableView. i created two contextmenu, whenever user clicked pushButton1 func1 is called and result set will be shown in qtableView and user can select items from contextmenu1 and same like pushButton2 ,where contextMenu2 will appear . but in my code context menu is not showing correctly. for ex: if user hit pushbutton1 then for both dataset context menu is same. so context menu is depends on which pushButton hit first. also menu is not close quickly after selected the item ,why!

main.py

JavaScript

Advertisement

Answer

Every signal connection triggers the target slot (function). If you connect the same signal to two functions, both functions get called, even if you connect twice to the same function. In fact, when you say “menu is not close[d] quickly after select[ing] the item”, the truth is that the menu is opened multiple times. You can easily check that if you just add a print statement to each function.

There are different solutions depending on the situation (unfortunately, your code and function namings aren’t very verbose, so we cannot really know what every function does).

Disconnect from all other slots

This can be done by calling a simple disconnect() on the signal, which disconnects from all other (already) connected slots. Note that this would raise an exception if no connection exists, so it should be done inside a try/except block:

JavaScript

The same goes for func2, obviously.

Disconnect from known slots

Similarly to the previous point, but only disconnects from the other slots.
Be aware that this wouldn’t work well in your case, as you’re connecting with a button click (which could happen more than once, resulting in calling the menu function for every time you clicked the button, as explained above).

Connect to a single slot, with a variable to choose the menu

This is probably the best and safest method for this kind of situations.

Instead of continuously changing the target of the connection, set a variable to specify which model is referenced and use a single function that will decide which menu use based on that variable.

Note that in this case I set the context policy (which can actually be done in Designer) and the connection directly in the setupUi, but in reality none of this should ever be done (more on this later).

JavaScript

Another possibility could be to set the attribute for the model, but the concept would be almost the same.

Create different persistent menus, but attached to the models

Similarly to the above, instead of setting a variable (which should be more verbose), you can create the different menus for each model and make them their attributes:

JavaScript

Note that any implementation above could be a bit more simplicistic (and OOP consistent) if you properly use pyuic files instead of trying to edit them, which is considered bad practice for many reasons, and in this specific case because it often overcomplicates things and could create confusion about the object structure, function purpose, etc. For instance, signal connections should not be done inside retranslateUi, which has a completely different purpose. Read more about using Designer.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement