Using enum as parameter to slot functions
I've run into some trouble with signals and slots. I've successfully used them in my application so far but when I wanted to call a slot function with an enum things seemed to get a lot harder. After reading around the net trying to understand what difference an enum parameter make I came up with the following code I thought was gonna work.
I created a new header file just for my enum:
Arrows.h
Code:
#ifndef ARROWS_H
#define ARROWS_H
#include <QtCore>
enum Arrow
{
NO_ARROW,
DIAG_DOWN_RIGHT,
DIAG_DOWN_LEFT,
DIAG_UP_RIGHT
};
Q_DECLARE_METATYPE(Arrow)
#endif // ARROWS_H
The header file which declares the slot function looks like this:
CrosswordArea.h
Code:
#ifndef CROSSWORDAREA_H
#define CROSSWORDAREA_H
#include "Arrows.h"
(...)
class CrosswordArea
: public QWidget{
Q_OBJECT
Q_ENUMS(Arrow)
(...)
public slots:
(...)
void setArrow(Arrow a);
(...)
};
#endif // CROSSWORDAREA_H
Slot implementation (I'm not sure if I need qRegisterMetaType here)
CrosswordArea.cpp
Code:
#include "Arrows.h"
#include "CrosswordArea.h"
(...)
CrosswordArea
::CrosswordArea(QString str
){
qRegisterMetaType<Arrow>("Arrow");
(...)
}
(...)
void CrosswordArea::setArrow(Arrow a)
{
marked->setArrow(a);
}
The slot is connected to a couple of buttons.
ButtonArea.cpp
Code:
#include "Arrows.h"
#include "CrosswordArea.h"
(...)
ButtonArea::ButtonArea(CrosswordArea *cwArea)
{
qRegisterMetaType<Arrow>("Arrow");
(...)
connect(letter2clue, SIGNAL(clicked()), cwArea, SLOT(setClue())); //works
connect(clue2letter, SIGNAL(clicked()), cwArea, SLOT(setLetter())); //works
connect(merge, SIGNAL(clicked()), cwArea, SLOT(merge())); //works
connect(yellowMark, SIGNAL(clicked()), cwArea, SLOT(yellowMark())); //works
connect(diagDRArrow, SIGNAL(clicked()), cwArea, SLOT(setArrow(Arrow))); //doesn't work
connect(diagDLArrow, SIGNAL(clicked()), cwArea, SLOT(setArrow(Arrow))); //doesn't work
connect(diagURArrow, SIGNAL(clicked()), cwArea, SLOT(setArrow(Arrow))); //doesn't work
(...)
}
Running this doesn't cause an error but rather a warning.
Code:
QObject::connect: Incompatible sender
/receiver arguments
QPushButton::clicked() --> CrosswordArea
::setArrow(Arrow
) QObject::connect: Incompatible sender
/receiver arguments
QPushButton::clicked() --> CrosswordArea
::setArrow(Arrow
) QObject::connect: Incompatible sender
/receiver arguments
QPushButton::clicked() --> CrosswordArea
::setArrow(Arrow
)
I'm doing something terribly wrong. Before I start to guess solutions, messing up my code in hope to get lucky I thought I'd ask you guys first.
What have I done wrong and how can I make my slot function call correct?
Thanks!
Re: Using enum as parameter to slot functions
You are trying to connect signal without parameter to slot with parameter. This is impossible. Parameters of signal and slot must be the same type. I think that QSignalMapper is what you need.
Re: Using enum as parameter to slot functions
Thanks Lesiok, a QSignalMapper worked great. I didn't know the parameters of the signal had to be the same as the parameters for the slot. Thanks for the clarification!
My button connection now looks like this.
ButtonArea.cpp
Code:
#include "Arrows.h"
#include "CrosswordArea.h"
(...)
ButtonArea::ButtonArea(CrosswordArea *cwArea)
{
qRegisterMetaType<Arrow>("Arrow");
(...)
connect(diagDRArrow, SIGNAL(clicked()), sigMapper, SLOT(map()));
connect(diagDLArrow, SIGNAL(clicked()), sigMapper, SLOT(map()));
connect(diagURArrow, SIGNAL(clicked()), sigMapper, SLOT(map()));
sigMapper->setMapping(diagDRArrow, "DIAG_DOWN_RIGHT");
sigMapper->setMapping(diagDLArrow, "DIAG_DOWN_LEFT");
sigMapper->setMapping(diagURArrow, "DIAG_UP_RIGHT");
connect(sigMapper,
SIGNAL(mapped
(QString)), cwArea,
SLOT(setArrow
(const QString &)));
(...)
}
It feels a bit weird to use enums now though because in my CrosswordArea.cpp I have to map strings to their corresponding enum.
CrosswordArea.cpp
Code:
(...)
CrosswordArea
::CrosswordArea(QString str
){
qRegisterMetaType<Arrow>("Arrow");
arrowMap = new QMap<QString, Arrow>;
arrowMap->insert("DIAG_DOWN_RIGHT", DIAG_DOWN_RIGHT);
arrowMap->insert("DIAG_DOWN_LEFT", DIAG_DOWN_LEFT);
arrowMap->insert("DIAG_UP_RIGHT", DIAG_UP_RIGHT);
(...)
}
void CrosswordArea
::setArrow(const QString &str
) {
marked->setArrow(arrowMap->take(str));
}
This works perfectly fine.
Problem SOLVED!
Re: Using enum as parameter to slot functions
You could also use setMapping(QObject*, int) using the enum values for the int argument and connect to the mapped(int) signal
Cheers,
_
Re: Using enum as parameter to slot functions
Oh of course! That saves a lot of code. Thanks anda_skoa! :)