tags:

views:

49

answers:

1

I'm planning on using qActions for use globally in my application. The idea is to have an action to be available at any level in the widget parent/child hierarchy.

Let's say I have the following GUI:

+--------------+
| +----------+ |
| |  +----+  | |
| |  | W2 |  | |
| |  +----+  | |
| |    W1    | |
| +----------+ |
|  MainWindow  |
+--------------+

W2 has a QPushButton which I want to use with a QAction defined in MainWindow. So the question is: What is the recommended way of working with QActions in multiple level hierarchy of widgets?

Here are my approaches:

  1. Define the actions in a MainWindow singleton, and access it from W2 to add the qaction to the QPushButton.

  2. Define the actions in MainWindow and add them to W1, which in turn would add the qaction to W2, which in turn would add the action to the QPushButton (I don't like this one).

  3. Create a Delegate singleton class to hold qactions and access it from MainWindow to make the global connections of qactions' triggers to the backend (model), and also access it from W2 to add the action wanted to the QPushButton.

Thanks

+1  A: 

Personnally, I'd go with a modified version of the second option, in the other way, because it keeps the hierarchy of your program. I say the other way because I would make the w2 pushButton propagate the signal up to the mainWindow. An advantage to this option is that if you add another w2 in w1, you simply have to connect it to w1, your mainWindow will stay exactly the same (encapsulation). Same thing, if you add a w1 in your mainWindow, you only have to connect the new w1 to your mainWindow and you don't have to care with the pushButton in the w2 of the new w1.

Here is the code to make this solution works:

In your w2 class constructor:

connect(pushButton, SIGNAL(clicked(bool)), this, SIGNAL(buttonClicked(bool)));

In your w1 class constructor:

connect(widget2, SIGNAL(buttonClicked(bool)), this, SIGNAL(buttonClicked(bool)));

In your mainWindow class constructor:

connect(widget1, SIGNAL(buttonClicked(bool)), anyAction, SIGNAL(triggered(bool)));
connect(anyAction, SIGNAL(triggered(bool)), this, SLOT(onActionTriggered(bool)));

Obvisouly, you must define the correct signals/slot in your class definitions and be sure that whatever you connect has already been created.

Hope this helps.

Live
Thanks for your answer. I think your solution means that for every new action added that has to be handled by W2 widgets, a new connection must exist at every level, from W2 all the way to MainWindow. Is this correct?
Daniel
If you add a new button in w2 that must trigger another action in mainWindow, yes you will have to add a new connection to every level. It may seem to be heavy, but in my opinion it is an easier flow to follow and understand. If you have many actions, you may prefer to put your w2 widget directly in your mainWindow, as a QDockWidget for example or another way to keep the layout identical but by easily access w2 from mainWindow and vice versa.
Live