Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

qt

qt-designer

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?

like image 789
Maxim Popravko Avatar asked Nov 10 '10 21:11

Maxim Popravko


2 Answers

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.

like image 94
Jérôme Avatar answered Sep 30 '22 13:09

Jérôme


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());

}
like image 27
Yash Avatar answered Sep 30 '22 13:09

Yash