QAction signal: want to send int
I've a button with menus like so:
Code:
action1 = menu->addAction(tr("Topography"));
action2 = menu->addAction(tr("Landsat"));
pButton2->setMenu(menu);
connect(action1, SIGNAL(triggered()), this, SLOT(mySlot(1))); //wrong
connect(action2, SIGNAL(triggered()), this, SLOT(mySlot(2)));
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.
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.
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:
Code:
#ifndef TEXTUREACTION_H
#define TEXTUREACTION_H
#include <QWidget>
#include <QSignalMapper>
#include <QAction>
//class QSignalMapper;
//class QAction;
class TextureAction
: public QAction{
Q_OBJECT
public:
signals:
void clicked(int value);
private:
};
#endif
my .cpp file:
Code:
#include "textureAction.h"
#include <QAction>
TextureAction
::TextureAction(QObject *parent
){
// connect(action, SIGNAL(triggered()), signalMapper, SLOT(map()));
// signalMapper->setMapping(action, value);
}
compilation chokes on the QAction line above (with comment). The error message is:
Quote:
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?
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.)
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:
Quote:
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:
Code:
#include <QSignalMapper>
#include <QAction>
//#include <QWidget>
//class QSignalMapper;
//class QAction;
class TextureAction
: public QAction{
Q_OBJECT
public:
// TextureAction(int value, QObject *parent);
void setValue(int x) { Value = x; }
signals:
void myClicked(int value);
private:
int Value;
};
//+++ and .cpp below
#include "textureAction.h"
#include <QAction>
TextureAction
::TextureAction(QAction *parent
){
// connect(myAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
// signalMapper->setMapping(myAction, Value);
// connect(signalMapper, SIGNAL(mapped(Value)), this, SIGNAL(myClicked(Value)));
}
In my Window.cpp code (my main Qt application window) I'm declaring a TextureAction object like so:
Code:
tAction1 = menu->addAction(tr("Topography")); // TextureAction *tAction1; declared in .h file
//tAction1 = new TextureAction; //this also fails
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?)
Re: QAction signal: want to send int
There is no need to subclass QAction for this:
Code:
mapper->setMapping(action1, 1);
mapper->setMapping(action2, 2);
connect(action1, SIGNAL(triggered()), mapper, SLOT(map()));
connect(action2, SIGNAL(triggered()), mapper, SLOT(map()));
connect(mapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));
Re: QAction signal: want to send int
jpn: BEAUTIFUL! my apologies for being such an idiot.:o
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.
Re: QAction signal: want to send int
Quote:
Originally Posted by
Michiel
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? :rolleyes:
Quote:
Originally Posted by
Michiel
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
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:
Code:
tAction(pButton2) = new TextureAction;
tAction(menu) = new TextureAction;
tAction(this) = new TextureAction;
tAction(parent) = new TextureAction;
none of which worked.
Quote:
Originally Posted by
Michiel
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.
Re: QAction signal: want to send int
Quote:
Originally Posted by
vonCZ
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
This should've been obvious.
I tried a variety of options, including:
Code:
tAction(pButton2) = new TextureAction;
tAction(menu) = new TextureAction;
tAction(this) = new TextureAction;
tAction(parent) = new TextureAction;
none of which worked.
:p
Code:
tAction = new TextureAction(this);
Re: QAction signal: want to send int
Quote:
Originally Posted by
Michiel
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.:D