Results 1 to 14 of 14

Thread: QAction with QPushButton

  1. #1
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default QAction with QPushButton

    Hello! QAction is meant to work together with QPushButtons, right? Somehow it doesn't work out for me. I defined a QAction and it works nicely on a QMenuBar, but when I try to add it to a QPushButton, nothing happens. I mean the button doesn't trigger the action. Here is my code.

    Qt Code:
    1. QAction* recordAction = new QAction(tr("&Record"), this);
    2. recordAction->setToolTip(tr("Toggles recording."));
    3. recordAction->setShortcut(QKeySequence(tr("Return")));
    4. connect(recordAction, SIGNAL(triggered()), this, SLOT(record()));
    5.  
    6. QMenuBar* menuBar = new QMenuBar();
    7. menuBar->addAction(recordAction);
    8.  
    9. ui.recordButton->addAction(recordAction);
    To copy to clipboard, switch view to plain text mode 

    The button and the whole ui has been created with Qt Designer.
    What am I doing wrong?

  2. #2
    Join Date
    Oct 2012
    Posts
    132
    Thanks
    10
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QAction with QPushButton

    I think this questions is similar to yours: http://stackoverflow.com/questions/1...gned-a-qaction

  3. The following user says thank you to Infinity for this useful post:

    Cruz (26th January 2014)

  4. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QAction with QPushButton

    Use QToolButton to get a button that triggers the action. QPushButton::addAction() (inherited from QWidget) adds the action to its context (right click) menu.

  5. #4
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    Quite frankly, I'm somewhat disappointed with this part. After not being able to use QAction with QPushButton in a simple way, I decided to add QActions directly to a QMenuBar. I already have a QMenuBar anyways and it would be great if I didn't have to define an additional QToolBar and all the QToolButtons to put in it. I would only have one thin bar on the top of the screen with a couple of drop down menus and a few "buttons" to press to trigger actions. Perfectly suitable for my application. Well it does kind of work as in I get my buttons and they can trigger the connected actions. The problem is that the QActions inside the QMenuBar don't deliver all the promised nifty features, like showing a tool tip or being checkable. Admittedly, perhaps I'm not doing something right, so here is my code:

    Qt Code:
    1. QAction* saveStateAction = new QAction(tr("&Save State"), this);
    2. saveStateAction->setToolTip(tr("Saves the state history.")); // No tool tip ever shows up.
    3. saveStateAction->setShortcut(QKeySequence(tr("Ctrl+S")));
    4. connect(saveStateAction, SIGNAL(triggered()), this, SLOT(saveStateHistory()));
    5.  
    6. QAction* loadStateAction = new QAction(tr("&Load State"), this);
    7. loadStateAction->setToolTip(tr("Loads the state history."));
    8. loadStateAction->setShortcut(QKeySequence(tr("Ctrl+L")));
    9. connect(loadStateAction, SIGNAL(triggered()), this, SLOT(loadStateHistory()));
    10.  
    11. QAction* recordAction = new QAction(tr("Record"), this);
    12. recordAction->setCheckable(true); // Checkable makes no difference.
    13. recordAction->setToolTip(tr("Toggles recording."));
    14. recordAction->setShortcut(QKeySequence(tr("Return")));
    15. connect(recordAction, SIGNAL(triggered()), this, SLOT(record()));
    16.  
    17.  
    18. QMenuBar* menuBar = new QMenuBar();
    19. QMenu* fileMenu = menuBar->addMenu(tr("&File"));
    20. fileMenu->addAction(saveStateAction); // Inside a QMenu checkable works, but no tool tip.
    21. fileMenu->addAction(loadStateAction);
    22.  
    23. menuBar->addSeparator(); // The separator doesn't do anything either...
    24. menuBar->addAction(" "); // ...so I hacked this for now. Would love to disable this button, but can't.
    25.  
    26. menuBar->addAction(recordAction); // The actions added to the menu directly are not checkable and no tool tip shows up.
    To copy to clipboard, switch view to plain text mode 

    Were my expectations too high that it could be done so simply, or did I overlook something in the documentation?

  6. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    Quote Originally Posted by Cruz View Post
    it would be great if I didn't have to define an additional QToolBar and all the QToolButtons to put in it.
    If you don't want to use a QToolBar, don't use a QToolBar.

    The replies so far suggested to use a QToolButton instead of QPushButton.

    Cheers,
    _

  7. #6
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    It seems that QToolButtons were meant to be inside a QToolBar, so that's why I brought that up. But essentially, I would like to avoid using any kind of button all together and just use QActions inside a QMenuBar. Any comments on why the features named above don't work?

  8. #7
    Join Date
    Oct 2012
    Posts
    132
    Thanks
    10
    Thanked 21 Times in 21 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QAction with QPushButton

    The separator doesn't do anything either...
    I have never seen an application using separators in the menu bar. It seems like Qt doesn't support that feature.
    You might want to use a stylesheet to achieve spacing between menu items: http://qt-project.org/doc/qt-4.8/sty...izing-qmenubar

    Inside a QMenu checkable works, but no tool tip.
    Same here. I don't think that tool tips are commonly used in menu entries and thus not be supported by QMenu.

  9. #8
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QAction with QPushButton

    Quote Originally Posted by Cruz View Post
    It seems that QToolButtons were meant to be inside a QToolBar, so that's why I brought that up. But essentially, I would like to avoid using any kind of button all together and just use QActions inside a QMenuBar. Any comments on why the features named above don't work?
    A QAction is not a visual element it is the abstract representation of an action that can be triggered by anything that can be connected to its trigger() (or toggle()) slot. This can be a visual element (or elements) like a QPushButton, QToolButton, QMenu, or another non-visual elements like a QTimer.

    If you have a QPushButton and want clicking it to trigger the action then connect QPushButton::clicked() to QAction::trigger(). If you want to save yourself a few seconds then use QToolButton which does this automatically. You can put a QToolButton anywhere you can put a widget, it does not have to be on a QToolBar although that is a typical use.

    The QToolButton will show the tool tip of its default action.
    The QPushButton does not know about the action you have loosely coupled it to so displays its own (blank) tool tip.


    Want an action on a QMenuBar? Just add it, and a menu "button" will be created for you. If you are going to have a menu bar without any menus though just use QToolBar and then you will get the tooltips from the QToolButtons (you can get drop down menus on QToolButtons too).

    QMenu does not show the tool tip of the actions under most (any?) styles.
    QMenuBar::addSeparator() does work if the style supports it.

    Your fake separator can be made non-clickable by disabling the action but the style may still show hover effects.
    Qt Code:
    1. QAction *fakeSeparator = mb->addAction(" ");
    2. fakeSeparator->setEnabled(false);
    To copy to clipboard, switch view to plain text mode 

    I don't know how difficult sub-classing QMenuBar and forcing the separator support would be (and don't have time to find out for you).

  10. The following user says thank you to ChrisW67 for this useful post:

    Cruz (28th January 2014)

  11. #9
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    Thank you for the useful comments. At least the fake separator problem has been solved, as disabling the action has exactly the desired effect. It is clear to me that QAction is not a visual element. However, it seems to be an intended way to add them directly to a menu bar and since this is perfectly legitimate, it's such a pity that tool tips and checkable don't work. Nonetheless, for my special case, the simplicity of this solution trumps the overhead of defining explicit buttons and dealing with a layout to add the buttons to, even if I have to go without tool tips and checkables. It just makes me wonder why there are three different concepts that work in different ways (QPushButton, QToolButton, and QAction in QMenuBar or QMenu), where all of them are essentially just clickable buttons that trigger actions. To me as a user of the Qt framework this appears to be a place that could perhaps use a think over.

  12. #10
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QAction with QPushButton

    QPushButton and QToolButton are both QAbstractButtons, with the former being more general purpose than the latter which is better suited to a Command Pattern usage. QMenuBar and QMenu is a hierarchical presentation of QActions rendered in a familiar UI fashion. (Either button type can have a context menu also) The range of options represents the range of common UI widgets on the various platforms Qt started on.

    Checkable does work with an action in the QMenuBar. The QAction is marked checked and any QToolButton or QMenu items attached to that action are rendered "checked" when the item in the QMenuBar is clicked. The QMenuBar does not expect a menu to be on/off and consequently does not render a distinct "checked" look (this you could override if you really wanted). If you want a permanently opened menu then the tearoff function is available. Really though it sounds like you want a tool bar not a menu.

    Qt Code:
    1. #include <QtGui>
    2.  
    3. class MainWindow: public QMainWindow {
    4. Q_OBJECT
    5. public:
    6. explicit MainWindow(QWidget *p = 0): QMainWindow(p) {
    7. QAction *a = new QAction("Futz About", this);
    8. a->setToolTip("I will futz about on command");
    9. a->setCheckable(true);
    10. connect(a, SIGNAL(triggered()), SLOT(futzAbout()));
    11.  
    12. QMenuBar *mb = menuBar();
    13. mb->addAction(a); // <<<< try clicking this guy and watch the others change
    14.  
    15. QMenu *menu = new QMenu("A Menu", this);
    16. menu->addAction(a);
    17. mb->addMenu(menu);
    18.  
    19. QPushButton *pb = new QPushButton("Futz QPushButton", this);
    20. connect(pb, SIGNAL(clicked()), a, SLOT(trigger()));
    21.  
    22. QToolButton *tb = new QToolButton(this);
    23. tb->setDefaultAction(a);
    24.  
    25. QWidget *content = new QWidget(this);
    26. QVBoxLayout *layout = new QVBoxLayout(content);
    27. layout->addWidget(pb);
    28. layout->addWidget(tb);
    29. setCentralWidget(content);
    30. }
    31.  
    32. private slots:
    33. void futzAbout() {
    34. qDebug() << Q_FUNC_INFO;
    35. }
    36. };
    37.  
    38. int main(int argc, char **argv) {
    39. QApplication app(argc, argv);
    40. MainWindow w;
    41. w.show();
    42. return app.exec();
    43. }
    44. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

  13. #11
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    Quote Originally Posted by Cruz View Post
    It seems that QToolButtons were meant to be inside a QToolBar, so that's why I brought that up.
    Yes, you brought that up to rant instead of trying a suggested solution. Well done!

    Quote Originally Posted by Cruz View Post
    But essentially, I would like to avoid using any kind of button all together and just use QActions inside a QMenuBar.
    Very nice!
    Ranting about a proposed solution without even trying, trying something totally unrelated instead and ranting about that and all based on a question you didn't even want an answer for.

    Definitely the way forward!

  14. #12
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    I find the concept of QActions very appealing in terms of defining all action related things like text, icon, tool tip, checkable, keyboard shortcut and what not in one place, pointing it to the slot that is to be triggered, and then attaching the action to a button or a menu. But apparently this concept has not been thoroughly implemented and the suggestions made in this thread so far are redirections to the parts of the framework that work well together with QAction.

    Obviously, QPushButtons ignore an attached QAction altogether. This fact is what started this thread in the first place. The suggestion to connect a QPushButton to a QAction and then the QAction to a slot makes the QAction an obsolete link in the chain according to my sense of simplicity. Perhaps it makes more sense in a mixed scenario, where QPushButtons, QToolButtons and QMenus are used in combination, but even then, the QPushButton would stick out of the pattern, because you would have to manually set up things for them that you already defined in the QAction. I wonder how a QPushButton supporting a QAction (for example by at least triggering it), would impair its general purpose applicability in any way.

    Quote Originally Posted by anda_skoa View Post
    Ranting about a proposed solution without even trying, trying something totally unrelated instead and ranting about that and all based on a question you didn't even want an answer for.
    You are jumping to uninformed conclusions here. I have tried the QToolButton suggestion even before I made my second post in this thread. Yes, the QToolButton seems to be the only object that actually does the job of supporting QActions all the way. At least I have tested the tool tip and the checkable feature and whether it triggers the attached action or not. But adding a QToolButton to a QMenuBar clashes with QMenus and QActions added to the QMenuBar, because QToolButtons are widgets that would like to be inside a layout, while QMenus and QActions do their own thing automatically. So either you introduce an additional QToolBar with a layout to add your QToolButtons to, or you design some kind of layout hack that allows for QToolButtons to coexist with QMenus and QActions in a QMenuBar in some magic way. I didn't elaborate on it in this detail in my second post, since I focused on the wonderful possibility of adding QActions to a QMenuBar without ever defining a button, a layout, or even an additional tool bar. I wonder if I managed to convey the idea of this "totally unrelated" approach more clearly this time.

    Now, as it turns out, QActions in QMenuBars do not show the tool tip, nor do they render a visual feedback of checkability.

    Quote Originally Posted by ChrisW67 View Post
    Checkable does work with an action in the QMenuBar. The QAction is marked checked and any QToolButton or QMenu items attached to that action are rendered "checked" when the item in the QMenuBar is clicked. The QMenuBar does not expect a menu to be on/off and consequently does not render a distinct "checked" look.
    I understand that a QMenu in a QMenuBar does not need to be checkable, but a QAction in a QMenuBar is an entirely different thing. I don't see why it shouldn't be possible to visually support checkable and to show a tool tip in this case. Yes, QActions inside QMenus do support the checkable feature, but they also don't show the tool tip. And as tool tips and checkability are advertised parts of the QAction concept, I found these flaws disappointing.

    Quote Originally Posted by ChrisW67 View Post
    QPushButton and QToolButton are both QAbstractButtons [...] QMenuBar and QMenu is a hierarchical presentation of QActions [...] The range of options represents the range of common UI widgets on the various platforms Qt started on.
    While QToolBar and QToolButton, QPushButton, and QMenu and QMenuBar may have a slightly different purpose in UI widgets, their functionality is essentially the same. You click on them and you trigger an action. My "ranting" is an attempt to make the point that all these objects could support QAction in a unified way by implementing all the features (tool tip, checkable etc.) that are promised by its interface and documentation.

  15. #13
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QAction with QPushButton

    It's an open source project. If you want to change its behaviour then sign up, propose and gain agreement for the changes, write and submit them. Complaining about it endlessly here will not change anything. Fighting for changes that are visually different from the native UI look/guidelines for the respective platforms will be an uphill battle: tool tips on menu items being the obvious case in point.

  16. The following user says thank you to ChrisW67 for this useful post:

    anda_skoa (29th January 2014)

  17. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QAction with QPushButton

    Quote Originally Posted by Cruz View Post
    Obviously, QPushButtons ignore an attached QAction altogether.
    No. They just don't have any override implementation for actions, i.e. they treat QAction like any other widget.

    Quote Originally Posted by Cruz View Post
    I wonder how a QPushButton supporting a QAction (for example by at least triggering it), would impair its general purpose applicability in any way.
    I don't think it would. Have you tried?

    Quote Originally Posted by Cruz View Post
    You are jumping to uninformed conclusions here.
    Obviously I was jumping to a conclusion since there was strange change in topic. And of course it was uninformed since you did not provide any information.

    The original scenario was triggering an action through a QPushButton.
    And, given your insistence that it was always about menu bar: how did you add the QPushButton into the menu bar that does not work for the QToolButton?

    Quote Originally Posted by Cruz View Post
    So either you introduce an additional QToolBar with a layout to add your QToolButtons to
    Whatever worked for your QPushButton should also work for a QToolButton.

    Quote Originally Posted by Cruz View Post
    Now, as it turns out, QActions in QMenuBars do not show the tool tip, nor do they render a visual feedback of checkability.
    Have you checked if it is a style issue? Do non-Qt applications on the platform show tooltips or checkmarks in the menu bar?

    Cheers,
    _

Similar Threads

  1. Replies: 0
    Last Post: 22nd February 2010, 09:30
  2. How can i get QAction or QPushButton name
    By duduqq in forum Qt Programming
    Replies: 5
    Last Post: 30th July 2008, 05:09
  3. QPushButton QMenu QAction
    By hgedek in forum Newbie
    Replies: 2
    Last Post: 1st November 2007, 12:29
  4. Replies: 3
    Last Post: 26th September 2006, 12:16
  5. QAction
    By mickey in forum Qt Programming
    Replies: 7
    Last Post: 17th July 2006, 09:42

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.