How can I implement the button, that holds an action (QAction) and can connect with one in designtime in QtDesigner?

StackOverflow https://stackoverflow.com/questions/4149117

  •  30-09-2019
  •  | 
  •  

Question

I want to use an approach, when most of application commands hold in QActions, so that I could drag actions easily into menu, or toolbar, or button, or anything. So, I need to implement such a button. It is easy to write some class, that will hold it, take icon, text, shortcut and tooltip from it and connect clicked() to triggered(). But I can't even force my button's 'action' property into designer. Seems, that only QVariant holdable types may appear in it's property editor.

BUT! Trolls did it somehow, so the task should be achievable. So, any suggestions?

Was it helpful?

Solution

Just adding here for anyone looking for similar solution

https://qt-project.org/wiki/PushButton_Based_On_Action

Header

#ifndef ACTIONBUTTON_H
#define ACTIONBUTTON_H

#include <QPushButton>
#include <QAction>

/*!
  *\brief An extension of a QPushButton that supports QAction.
  * This class represents a QPushButton extension that can be
  * connected to an action and that configures itself depending
  * on the status of the action.
  * When the action changes its state, the button reflects
  * such changes, and when the button is clicked the action
  * is triggered.
  */
class ActionButton : public QPushButton
{
    Q_OBJECT

private:

    /*!
      * The action associated to this button.
      */
    QAction* actionOwner;


public:
    /*!
      * Default constructor.
      * \param parent the widget parent of this button
      */
    explicit ActionButton(QWidget *parent = 0);

    /*!
      * Sets the action owner of this button, that is the action
      * associated to the button. The button is configured immediatly
      * depending on the action status and the button and the action
      * are connected together so that when the action is changed the button
      * is updated and when the button is clicked the action is triggered.
      * \param action the action to associate to this button
      */
    void setAction( QAction* action );


signals:

public slots:
    /*!
      * A slot to update the button status depending on a change
      * on the action status. This slot is invoked each time the action
      * "changed" signal is emitted.
      */
    void updateButtonStatusFromAction();


};

#endif // ACTIONBUTTON_H

Class

#include "actionbutton.h"

ActionButton::ActionButton(QWidget *parent) :
    QPushButton(parent)
{
    actionOwner = NULL;
}

void ActionButton::setAction(QAction *action)
{

    // if I've got already an action associated to the button
    // remove all connections

    if( actionOwner != NULL && actionOwner != action ){
        disconnect( actionOwner,
                    SIGNAL(changed()),
                    this,
                    SLOT(updateButtonStatusFromAction()) );

        disconnect( this,
                    SIGNAL(clicked()),
                    actionOwner,
                    SLOT(trigger()) );
    }


    // store the action
    actionOwner = action;

    // configure the button
    updateButtonStatusFromAction();



    // connect the action and the button
    // so that when the action is changed the
    // button is changed too!
    connect( action,
             SIGNAL(changed()),
             this,
             SLOT(updateButtonStatusFromAction()));

    // connect the button to the slot that forwards the
    // signal to the action
    connect( this,
             SIGNAL(clicked()),
             actionOwner,
             SLOT(trigger()) );
}

void ActionButton::updateButtonStatusFromAction()
{
    setText( actionOwner->text() );
    setStatusTip( actionOwner->statusTip() );
    setToolTip( actionOwner->toolTip() );
    setIcon( actionOwner->icon() );
    setEnabled( actionOwner->isEnabled() );
    setCheckable( actionOwner->isCheckable() );
    setChecked( actionOwner->isChecked());

}

OTHER TIPS

I'm not sure, but I understand that you have an action (created with QtDesigner) and you want to associate this action with a menu, a toolbar button, and a normal button as well.

With QtDesigner, it is easy to use a QAction as a menu-item and as a toolbar button.

If you want to use this QAction with a normal button as well, I guess you cannot do it only with Qt Designer.

My suggestion is to add on your form, with QtDesigner a QToolButton.

In you class constructor, you can then tell the QToolButton that it is connected to your QAction with setDefaultAction().

ui->toolButton->setDefaultAction(ui->actionHello);

You might have to adjust accordingly the geometry of the QToolButton.

Now, if you click on it, the action actionHello with be triggered.

In Qt Designer you can manually add connections. I think you might want to use a normal PushButton and connect the button's clicked() signal to the action's trigger() slot.

Let's say there's a pushButton_AddFile and an actionAddFile. You can add the connection in the Signal/Slot Editor of Qt Designer as follows:

enter image description here

I think you have to implement some specific drop-action. See if QtDesigner has some specific Mime-Type for its components. Anything that is drag and drop must be implemented in this way. Of course is not straightforward to get it right ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top