Results 1 to 11 of 11

Thread: QAction signal: want to send int

  1. #1
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default QAction signal: want to send int

    I've a button with menus like so:
    Qt Code:
    1. pButton2 = new QPushButton(tr("&Terrain"));
    2. menu = new QMenu(this);
    3. action1 = menu->addAction(tr("Topography"));
    4. action2 = menu->addAction(tr("Landsat"));
    5. pButton2->setMenu(menu);
    6.  
    7. connect(action1, SIGNAL(triggered()), this, SLOT(mySlot(1))); //wrong
    8. connect(action2, SIGNAL(triggered()), this, SLOT(mySlot(2)));
    To copy to clipboard, switch view to plain text mode 

    I know why this doesn't work: triggered() has no parameters, mySlot(int) has one. I could fix this by making 2 separate mySlot() functions that don't take parameters, but I'm going to have alot of these and was wondering if there's another, better way to do it... a way such that I can create a single SLOT function.

  2. #2
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QAction signal: want to send int

    That is a common mistake. Signals and slots don't work that way. You could of course create a custom slot for each signal, as you said. But there is a better way. Check out the QSignalMapper class.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  3. #3
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QAction signal: want to send int

    thanks Michiel. I'm trying out QSignalMapper now but having a problem. This is my first attempt at subclassing:

    my .h file:
    Qt Code:
    1. #ifndef TEXTUREACTION_H
    2. #define TEXTUREACTION_H
    3.  
    4. #include <QWidget>
    5. #include <QSignalMapper>
    6. #include <QAction>
    7. //class QSignalMapper;
    8. //class QAction;
    9.  
    10. class TextureAction : public QAction
    11. {
    12.  
    13. Q_OBJECT
    14.  
    15. public:
    16. TextureAction(QObject *parent);
    17.  
    18. signals:
    19. void clicked(int value);
    20.  
    21. private:
    22. QSignalMapper *signalMapper;
    23.  
    24. };
    25.  
    26. #endif
    To copy to clipboard, switch view to plain text mode 

    my .cpp file:
    Qt Code:
    1. #include "textureAction.h"
    2.  
    3. #include <QAction>
    4.  
    5. TextureAction::TextureAction(QObject *parent)
    6. : QAction(parent)
    7. {
    8.  
    9. signalMapper = new QSignalMapper(this);
    10.  
    11. QAction *act = new QAction; //chokes here
    12.  
    13. // connect(action, SIGNAL(triggered()), signalMapper, SLOT(map()));
    14. // signalMapper->setMapping(action, value);
    15.  
    16.  
    17. }
    To copy to clipboard, switch view to plain text mode 

    compilation chokes on the QAction line above (with comment). The error message is:
    error C2512: 'QAction' : no appropriate default constructor available
    As I said, this is my first attempt at subclassing. I looked on the web and "C++ GUI Programming with Qt4" for examples of subclassing QAction; I couldn't find any. I'm not sure why, for example, in the QSignalMapper link you provided, why they subclass from QWidget instead of QPushButton. I tried subclassing from QObject instead of QAction, but it still wouldn't compile.

    Any tips?

  4. #4
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QAction signal: want to send int

    The error has nothing to do with your subclass. You simply forgot the parent parameter for the QAction constructor.

    The example subclassed from a QWidget because the result is supposed to be a keypad with multiple QPushButtons. Not a single QPushButton. (The keypad IS-A widget. It's not a pushbutton.)
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  5. The following user says thank you to Michiel for this useful post:

    vonCZ (2nd July 2007)

  6. #5
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QAction signal: want to send int

    oh yeah... my bad. Thanks.

    I'm still stuck (predictably). In short, what I'm trying to do is create a class--TextureAction--that is a subclass of QAction and behaves exactly like QAction, except for two things:

    1) TextureAction will have a variable, int myValue, that can be set by a member function, mySetVariable.

    2) my TextureAction class will have a QSignalMapper object to take QAction's triggered() SIGNAL, pass it to my QSignalMapper SLOT, and then signal this back out as an integer. Sounds simple enough, but when I instantiate a TextureAction object, I get the following error:

    error C2440: '=' : cannot convert from 'QAction *' to 'TextureAction *'
    Cast from base to derived requires dynamic_cast or static_cast
    textureAction.h and .cpp look like this:
    Qt Code:
    1. #include <QSignalMapper>
    2. #include <QAction>
    3.  
    4. //#include <QWidget>
    5. //class QSignalMapper;
    6. //class QAction;
    7.  
    8. class TextureAction : public QAction
    9. {
    10.  
    11. Q_OBJECT
    12.  
    13. public:
    14. // TextureAction(int value, QObject *parent);
    15. TextureAction(QAction *parent);
    16.  
    17. void setValue(int x) { Value = x; }
    18.  
    19. signals:
    20. void myClicked(int value);
    21.  
    22. private:
    23. QSignalMapper *signalMapper;
    24. int Value;
    25.  
    26. };
    27.  
    28. //+++ and .cpp below
    29. #include "textureAction.h"
    30.  
    31. #include <QAction>
    32.  
    33.  
    34. TextureAction::TextureAction(QAction *parent)
    35. : QAction(parent)
    36. {
    37.  
    38. signalMapper = new QSignalMapper(this);
    39.  
    40. QAction *myAction = new QAction(this);
    41.  
    42. // connect(myAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
    43. // signalMapper->setMapping(myAction, Value);
    44.  
    45. // connect(signalMapper, SIGNAL(mapped(Value)), this, SIGNAL(myClicked(Value)));
    46.  
    47.  
    48. }
    To copy to clipboard, switch view to plain text mode 

    In my Window.cpp code (my main Qt application window) I'm declaring a TextureAction object like so:

    Qt Code:
    1. pButton2 = new QPushButton(tr("&Terrain\n Texture"));
    2. menu = new QMenu(this);
    3. tAction1 = menu->addAction(tr("Topography")); // TextureAction *tAction1; declared in .h file
    4. //tAction1 = new TextureAction; //this also fails
    To copy to clipboard, switch view to plain text mode 

    If my TextureAction class is derived from QAction, can't I use a TextureAction object in nearly the same way as I could a QAction object? (like add it to the QMenu, as I've done above?)

  7. #6
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QAction signal: want to send int

    There is no need to subclass QAction for this:
    Qt Code:
    1. QSignalMapper* mapper = new QSignalMapper(pButton2);
    2. mapper->setMapping(action1, 1);
    3. mapper->setMapping(action2, 2);
    4. connect(action1, SIGNAL(triggered()), mapper, SLOT(map()));
    5. connect(action2, SIGNAL(triggered()), mapper, SLOT(map()));
    6. connect(mapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  8. The following user says thank you to jpn for this useful post:

    vonCZ (2nd July 2007)

  9. #7
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QAction signal: want to send int

    jpn: BEAUTIFUL! my apologies for being such an idiot.

  10. #8
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QAction signal: want to send int

    Oh, so that's why you wanted a subclass.

    For good measure, you should be able to add your QAction subclass to a QMenu, no problem. You were just doing it wrong.

    QMenu::addAction(QString), as you've used, creates a new action (a QAction), places it in the menu and returns a pointer to it. It doesn't use your own class. The assignment there is what causes your error.

    What causes the second error ('this also fails') is that you forgot the parent argument of the constructor again.

    Back to adding it to the menu, though. There's a function for adding an action that you've already created yourself. QWidget::addAction(QAction*).

    Good luck.
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  11. #9
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QAction signal: want to send int

    Quote Originally Posted by Michiel View Post
    Oh, so that's why you wanted a subclass.
    yeah... as you've probably guessed, I'm pretty new at this stuff, so often when I find an example of how I might solve a problem, I tend to stick to it... often too closely. Trolltech's example on their QSignalMapper page uses a subclassed Widget to implement the class... so i figured, why not?

    Quote Originally Posted by Michiel View Post
    QMenu::addAction(QString), as you've used, creates a new action (a QAction), places it in the menu and returns a pointer to it. It doesn't use your own class. The assignment there is what causes your error.
    This should've been obvious.

    Quote Originally Posted by Michiel View Post
    What causes the second error ('this also fails') is that you forgot the parent argument of the constructor again.
    I tried a variety of options, including:

    Qt Code:
    1. tAction(pButton2) = new TextureAction;
    2. tAction(menu) = new TextureAction;
    3. tAction(this) = new TextureAction;
    4. tAction(parent) = new TextureAction;
    To copy to clipboard, switch view to plain text mode 
    none of which worked.


    Quote Originally Posted by Michiel View Post
    Back to adding it to the menu, though. There's a function for adding an action that you've already created yourself. QWidget::addAction(QAction*).
    Thanks. I will try this when I need to add a subclass QAction. Thanks for your help.

  12. #10
    Join Date
    Mar 2006
    Location
    The Netherlands
    Posts
    300
    Thanks
    9
    Thanked 29 Times in 29 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QAction signal: want to send int

    Quote Originally Posted by vonCZ View Post
    yeah... as you've probably guessed, I'm pretty new at this stuff,
    Your mistakes indicate you just need some more C++ experience. I always say it's a mistake to start off with event-driven programming and/or big fat OOP libraries (so, Qt). You should first understand classes, pointers and all those other good things.

    Quote Originally Posted by vonCZ View Post
    This should've been obvious.

    I tried a variety of options, including:

    Qt Code:
    1. tAction(pButton2) = new TextureAction;
    2. tAction(menu) = new TextureAction;
    3. tAction(this) = new TextureAction;
    4. tAction(parent) = new TextureAction;
    To copy to clipboard, switch view to plain text mode 
    none of which worked.

    Qt Code:
    1. tAction = new TextureAction(this);
    To copy to clipboard, switch view to plain text mode 
    "The strength of a civilization is not measured by its ability to wage wars, but rather by its ability to prevent them." - Gene Roddenberry

  13. #11
    Join Date
    Apr 2007
    Location
    Rakovnik, Czech Republic
    Posts
    175
    Thanks
    43
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QAction signal: want to send int

    Quote Originally Posted by Michiel View Post
    I always say it's a mistake to start off with event-driven programming and/or big fat OOP libraries (so, Qt).
    perhaps, depending on one's situation. I've been writing command-line, data-processing programs for years... compiling w/gcc, but rarely making use of even the simplest OOP functionality, because I could get by without it. No longer: Qt forces one's hand.

    anyhow, thanks again for the tips. & trust me: i'm consulting my Schildt book along with Blanchette/Summerfield.

Similar Threads

  1. Manually send signal to slot
    By donmorr in forum Qt Programming
    Replies: 1
    Last Post: 29th May 2006, 15:03
  2. Replies: 2
    Last Post: 17th May 2006, 21:01
  3. send signal from QCombobox
    By raphaelf in forum Qt Programming
    Replies: 22
    Last Post: 28th February 2006, 14:18

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.