<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[QWidgetAction for QToolButtons on secondary toolbar]]></title><description><![CDATA[<p dir="auto">In my application I use toolbars not only in the QMainWindow, but also in some dock widgets. According to the Qt documentation¸ for proper handling of QToolButtons/QActions in secondary toolbars, these buttons/actions should be subclasses of QWidgetAction.</p>
<blockquote>
<p dir="auto">When a QToolBar is not a child of a QMainWindow, it loses the ability to populate the extension pop up with widgets added to the toolbar using addWidget(). Please use widget actions created by inheriting QWidgetAction and implementing QWidgetAction::createWidget() instead.</p>
</blockquote>
<p dir="auto">I tried to implement my subclass as</p>
<pre><code>#ifndef TOOLBUTTONACTION_H
#define TOOLBUTTONACTION_H

#include &lt;QMenu&gt;
#include &lt;QPointer&gt;
#include &lt;QToolButton&gt;
#include &lt;QWidgetAction&gt;

class ToolButtonAction : public QWidgetAction
{
    Q_OBJECT
  public:
    explicit ToolButtonAction( QObject *parent = nullptr );
    void setAutoRaise( bool autoRaise );
    void setPopupMode( QToolButton::ToolButtonPopupMode mode );
    void setToolButtonStyle( Qt::ToolButtonStyle style );
    void setMenu( QMenu *menu );
    void addActions( const QList&lt;QAction *&gt; &amp;actions );
    void setDefaultAction( QAction *action );
    QAction *defaultAction() const;

  protected:
    QWidget *createWidget( QWidget *parent ) override;
    void deleteWidget( QWidget *widget ) override;

  private:
    void applyState( QToolButton *button ) const;

  private:
    bool mAutoRaise = false;
    Qt::ToolButtonStyle mToolButtonStyle = Qt::ToolButtonStyle::ToolButtonIconOnly;
    QToolButton::ToolButtonPopupMode mPopupMode = QToolButton::ToolButtonPopupMode::DelayedPopup;
    QPointer&lt; QMenu &gt; mMenu;
    QList&lt; QAction * &gt; mButtonActions;
    QPointer&lt; QAction &gt; mDefaultAction;
    QPointer&lt; QToolButton &gt; mButton;
};

#endif // TOOLBUTTONACTION_H
</code></pre>
<p dir="auto">and</p>
<pre><code>#include "toolbuttonaction.h"

#include &lt;QMenu&gt;
#include &lt;QToolBar&gt;

ToolButtonAction::ToolButtonAction( QObject *parent )
  : QWidgetAction( parent )
{
}

void ToolButtonAction::setAutoRaise( bool autoRaise )
{
  mAutoRaise = autoRaise;
  if ( mButton )
  {
    mButton-&gt;setAutoRaise( autoRaise );
  }
}

void ToolButtonAction::setPopupMode( QToolButton::ToolButtonPopupMode mode )
{
  mPopupMode = mode;
  if ( mButton )
  {
    mButton-&gt;setPopupMode( mode );
  }
}

void ToolButtonAction::setToolButtonStyle( Qt::ToolButtonStyle style )
{
  mToolButtonStyle = style;
  if ( mButton )
  {
    mButton-&gt;setToolButtonStyle( style );
  }
}

void ToolButtonAction::setMenu( QMenu *menu )
{
  mMenu = menu;
  if ( mButton )
  {
    mButton-&gt;setMenu( menu );
  }
}

void ToolButtonAction::addActions( const QList&lt; QAction * &gt; &amp;actions )
{
  for ( QAction *action : std::as_const( actions ) )
  {
    mButtonActions.append( action );
  }

  if ( mButton )
  {
    mButton-&gt;addActions( actions );
  }
}

void ToolButtonAction::setDefaultAction( QAction *action )
{
  if ( !action )
  {
    return;
  }

  mDefaultAction = action;

  if ( mButton )
  {
    mButton-&gt;setDefaultAction( action );
  }
}

QAction *ToolButtonAction::defaultAction() const
{
  return mDefaultAction;
}

QWidget *ToolButtonAction::createWidget( QWidget *parent )
{
  QToolButton *button = new QToolButton( parent );
  button-&gt;setAutoRaise( mAutoRaise );
  button-&gt;setPopupMode( mPopupMode );
  button-&gt;setToolButtonStyle( mToolButtonStyle );

  if ( QToolBar *toolBar = qobject_cast&lt; QToolBar * &gt;( parent ) )
  {
    button-&gt;setIconSize( toolBar-&gt;iconSize() );
    connect( toolBar, &amp;QToolBar::iconSizeChanged, button, &amp;QToolButton::setIconSize );
    button-&gt;setToolButtonStyle( toolBar-&gt;toolButtonStyle() );
    connect( toolBar, &amp;QToolBar::toolButtonStyleChanged, button, &amp;QToolButton::setToolButtonStyle );
  }

  if ( mMenu )
  {
    button-&gt;setMenu( mMenu );
  }

  if ( !mButtonActions.isEmpty() )
  {
    button-&gt;addActions( mButtonActions );
  }

  if ( mDefaultAction )
  {
    button-&gt;setDefaultAction( mDefaultAction );
  }
  else
  {
    applyState( button );
    connect( button, &amp;QToolButton::clicked, this, &amp;QAction::trigger );
  }

  mButton = button;
  return button;
}

void ToolButtonAction::deleteWidget( QWidget *widget )
{
  QWidgetAction::deleteWidget( widget );
}

void ToolButtonAction::applyState( QToolButton *button ) const
{
  button-&gt;setEnabled( isEnabled() );

  if ( !mDefaultAction )
  {
    button-&gt;setIcon( icon() );
    button-&gt;setText( text() );
    button-&gt;setToolTip( toolTip() );
  }
}
</code></pre>
<p dir="auto">This works, but I'm not sure I correctly understand and handle case when the same button/action is added in different places, e.g. to the main toolbar/menu and secondary toolbar. Should I keep track of created buttons in my subclass, e.g. to change their properties like autoraise/popup mode/etc. or returning a single widget is enough? My understanding is that <code>createWidget()</code> is called once per container to which I add action. So when for example I add action to a toolbar and then shrink it, a new action is also created for extension popup and I will end up with two actions. Am right?</p>
<p dir="auto">If my understanding is correct, I will need to replace <code>QPointer&lt; QToolButton &gt; mButton;</code> with <code>QList&lt; QPointer&lt; QToolButton &gt; &gt; mButtons;</code> and then in all setters do something like</p>
<pre><code>  for ( QToolButton *button : std::as_const( mButtons ) )
  {
    if ( button )
    {
      button-&gt;setAutoRaise( autoRaise );
    }
  }
</code></pre>
]]></description><link>https://forum.qt.io/topic/165143/qwidgetaction-for-qtoolbuttons-on-secondary-toolbar</link><generator>RSS for Node</generator><lastBuildDate>Mon, 05 Oct 2026 02:23:24 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/165143.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 04 Oct 2026 08:43:21 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to QWidgetAction for QToolButtons on secondary toolbar on Sun, 04 Oct 2026 18:49:26 GMT]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">From a quick look at the implementation of QWidgetAction, you should:</p>
<ul>
<li>nuke <code>mButton</code> completely (requestWidget calls createWidget and builds the list of all widgets created)</li>
<li>in your various setters call <a href="https://doc.qt.io/qt-6/qwidgetaction.html#createdWidgets" target="_blank" rel="noopener noreferrer nofollow ugc">createdWidgets</a> and apply there the changes that were done to all the buttons that have been created.</li>
</ul>
]]></description><link>https://forum.qt.io/post/840362</link><guid isPermaLink="true">https://forum.qt.io/post/840362</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Sun, 04 Oct 2026 18:49:26 GMT</pubDate></item></channel></rss>