Re: Cloning a QAction object
Why do you need to change the parent? It's not possible to copy the action but you can connect one action to another's triggered() signal. You can even connect to its changed() signal to update one action when the other changes (for instance it gets disabled).
So you can implement a clone action with more or less this:
Code:
class CloneAction
: public QAction { Q_OBJECT
public:
connect(original, SIGNAL(changed()), this, SLOT(updateMe())); // update on change
connect(original, SIGNAL(destroyed()), this, SLOT(deleteLater())); // delete on destroyed
connect(original, SIGNAL(triggered()), this, SLOT(trigger())); // trigger on triggered
// repeat with toggled, etc.
// connect the other way round as well if it makes sense - depends if you want one way or two way relation
m_orig = original;
}
private slots:
void updateMe(){
setProperty(qPrintable(prop), m_orig->property(qPrintable(prop)));
}
private:
};
You can build upon it...
Re: Cloning a QAction object
Thanks for your reply. I'm a beginner in QT, I think it is better to describe my original problem. I have an action which is defined in the main menu (created in QTDesigner), but it can also be used from a toolbar and from a context menu of a control. I wish to know that my action is fired from the context menu (or not) because in this case the slot function connected to the action should be worked slightly differently. In fact I do not wish to create a new action element, I prefer using the existing one, but in this case the sender()->parent() is always the MainWindow object in the connected slot function. Therefore I'm forced to make a duplicate of the original action, it must be created in my context menu. Now I can use sender()->parent()->objectName() to distinguish the source object but it's not an elegant solution, at least copying properties is ugly.
In the example below, actionTrack_Analysis is the original action. Simple addAction(QAction *) is commented out, I have to duplicate the original action and only its important properties are copied.
Code:
contextMenu.setObjectName("contextMenu");
// unfortunately original actions cannot be used, because we must know
// that the sender object is from contextMenu or MainWindow
//contextMenu.addAction(actionTrack_Analysis);
QAction* action
= contextMenu.
addAction(actionTrack_Analysis
->text
(),
this,
SLOT(on_actionTrack_Analysis_triggered
()), actionTrack_Analysis
->shortcut
());
action->setEnabled(actionTrack_Analysis->isEnabled());
action->setIcon(actionTrack_Analysis->icon());
contextMenu.addAction(action);
Re: Cloning a QAction object
Quote:
Originally Posted by
brazso
Thanks for your reply. I'm a beginner in QT, I think it is better to describe my original problem. I have an action which is defined in the main menu (created in QTDesigner), but it can also be used from a toolbar and from a context menu of a control. I wish to know that my action is fired from the context menu (or not) because in this case the slot function connected to the action should be worked slightly differently. In fact I do not wish to create a new action element, I prefer using the existing one, but in this case the sender()->parent() is always the MainWindow object in the connected slot function.
If these "actions" do different things (even if they don't differ much), I'd use separate QAction instances.
Checking if an action was fired from a context menu is relatively easy - you can set a temporary value on the action while building the menu and remove it after the menu is closed, like in the snippet below, but I'd still use separate actions.
Code:
connect(someAction, SIGNAL(triggered()), ..., SLOT(doSomething()));
//...
menu.addAction(someAction);
someAction->setProperty("calledFromContextMenu", true);
//...
menu.exec();
someAction->setProperty("calledFromContextMenu", false);
//...
void X::doSomething(){
QAction *a
= qobject_cast<QAction
*>
(sender
());
if(!a) return;
if(a->property("calledFromContextMenu").toBool()){
// ...
} else {
// ...
}
}