How to determine the source of an QAction?

2019-07-02 14:12发布

I want to know if there is any easy/elegant way to determine the source of an QAction? What I mean I have one QAction which is added to multiple QWidgets (with QWidget::addAction) and when the triggered signal of the action gets emitted I need to know which QWidget is the source because I need to query that specific widget.

I don't see any way to do this with the QAction itself, the parent is always the same no matter from where the actions gets triggered.

The idea I had to solve this was to save a global pointer to the active widget, but again there seems to be no elegant way in Qt to capture the event when a widget receives the focus to set it as the active one.

Another way would be to use different QActions for each widget, but in my case it's better to use one because the user can customize the shortcuts of the actions and I don't think it's good design to have multiple actions with the same shortcuts and text etc. which all do the same but operate on different widgets.

P.S.: Most of the actions can be triggered either by shortcut (with widget context enabled so the widget need focus anyways) and also from a custom context menu on that widget.

I can provide a simple code example if that helps to understand my problem:

// init the action etc.
void Widget::init()
{
    QAction *action = new QAction("Do Something");
    action->setShortcut("Ctrl+X");
    action->setShortcutContext(Qt::WidgetShortcut);
    connect(action, SIGNAL(triggered()), SLOT(action_triggered()));

    // assume the widgets 1 to 3 already exist (type QWidget* off course)
    widget1->addAction(action);
    widget2->addAction(action);
    widget3->addAction(action);
}

// SLOT action_triggered()
void Widget::action_triggered()
{
    QWidget *source;
    // TODO: which widget is the source: widget1, widget2 or widget3?
}

1条回答
成全新的幸福
2楼-- · 2019-07-02 14:49

I think you can use QAction associatedWidgets method to determine the list of widgets, to which action was added. Then you can examine this list for widget, that currently has focus.

QList <QWidget *> widget_list = sender()->associatedWidgets();

for(int i = 0; i != widget_list.size(); ++i) {
    if (widget_list.at(i)->hasFocus()){
        sourceWidget = widget_list.takeAt(i);
        break;
    }
}
查看更多
登录 后发表回答