PDA

View Full Version : Determine a menu's caller, multiple buttons same menu (updated)



tescrin
26th November 2012, 18:07
Update: I had mis-typed part of my problem description. This is now corrected.

Consider:

//some container class
QPushButton *a,*b,*c;
//initialization code
QAction *superCoolAction; //action initialized to release some signal, SCA_Signal

QMenu *sharedMenu;
//initialization code contains superCoolAction, it's parent is this container class

a->addMenu(sharedMenu);
b->addMenu(sharedMenu);
c->addMenu(sharedMenu);


Now, when someone clicks on any of these buttons it will open the menu; and they may click the action (which will emit SCA_Signal), but I'd like this signal to contain data telling me which button released it. Boiling this question down further, I'm curious if there's a "who called me" style function I can use on menus.

I ask because I know you can do this with Signals, but in that case it would just tell me the "menu" called it I believe. I've considered odd implementations such as releasing a signal when the button is clicked to "pre-empt" the next signal so I can bypass this issue; but that causes a coupling issue. I could instead prep the container class to catch SCA_Signal and clean it up, emiting a similar signal with the necessary information about who called it; but these both feel klugey.

What's the best way to know which button opened a menu if it's a menu that is used on several buttons?

amleto
27th November 2012, 02:23
the best way is to redeisgn so actions aren't dependent on things that they should be agnostic of. I mean children should care about parents, and slots shouldnt care about callers. See 'dependency injection/inversion'. If your action needs to know the caller in order to work correctly, then your action doesnt have enough information to begin with.

tescrin
27th November 2012, 15:43
I'll see what I can do on that front. It'd be easy enough to make multiples of the menu; but I had figured making 5 more menus (it has 4 submenus..) and their actions for each button would be needless clutter if I could pass the caller as an argument.

That said, sharing the menu is a shortcut and will likely just bite me elsewhere. *grumble grumble*
Thanks on the advice

prof.ebral
28th November 2012, 18:20
you can find the sender. I do this in PyQt. Here is an example of a rotation widget that has a slider and a spinbox. They both send their data to the same method and I find the sender so I don't create a recursive error


def rotateValue(self, rotate):
if self.mapPage.sender() == self.rotateMenu.slider:
if not self.rotateMenu.setOnce:
self.rotateMenu.spinbox.setValue(rotate)
self.rotateMenu.setOnce = True
if self.mapPage.sender() == self.rotateMenu.spinbox:
if not self.rotateMenu.setOnce:
self.rotateMenu.slider.setValue(rotate)
self.rotateMenu.setOnce = True
self.rotateMenu.setOnce = False
self.itemOffset(rotate); self.setRotation(rotate);
self.mapGuide.updateTable()
self.Rotation = rotate

amleto
29th November 2012, 13:47
that's all very well and good, but the problem is that the 'sender' the OP is interested in the 'creator' of the menu. The menu will be the 'sender' and this isn't what he wants. In fact that OP says this all in his first post.

wysota
29th November 2012, 15:26
What's the best way to know which button opened a menu if it's a menu that is used on several buttons?
If all elses fail, set a dynamic property on the menu (or each of the actions) that will point to the object that created the menu.