PDA

View Full Version : QObject::connect: No such slot



nemaider
19th April 2021, 21:55
Hello,

I creating small app for my university and I stucked at one problem - no such slot.

Maybe now I put some code and explain it later.



Game. h



class Game: public QGraphicsView{
Q_OBJECT
public slots:
void displayMainMenu();
void showHelp(Button &start,Button &score,Button &help,Button &quit);
};




Game.cpp



void Game::displayMainMenu() {
Button* playButton = new Button(QString("../Sources/Pictures/Menu/start-inactive.png"),
QString("../Sources/Pictures/Menu/start-active.png"));
connect(playButton,SIGNAL(clicked()), this, SLOT(start()));


Button* scoresButton = new Button(QString("../Sources/Pictures/Menu/scores-inactive.png"),
QString("../Sources/Pictures/Menu/scores-active.png"));
connect(scoresButton,SIGNAL(clicked()), this, SLOT(showScores()));


Button* helpButton = new Button(QString("../Sources/Pictures/Menu/help-inactive.png"),
QString("../Sources/Pictures/Menu/help-active.png"));
connect(helpButton,SIGNAL(clicked()), this, SLOT(showHelp(playButton, scoresButton, helpButton, quitButton)));


Button* quitButton = new Button(QString("../Sources/Pictures/Menu/quit-inactive.png"),
QString("../Sources/Pictures/Menu/quit-active.png"));
connect(quitButton,SIGNAL(clicked()), this, SLOT(close()));

}




void Game::showHelp(Button &play, Button &scores, Button &help, Button &quit) {
/* some stuff here with these buttons */
}



Above I show my code and now I will explain you what I want to do, so I want send these buttons in parameters and use them by my idea, but when I compile my program I getting this error message:
QObject::connect: No such slot Game::showHelp(playButton, scoresButton, helpButton, quitButton)

Button class is made by myself and with it class isn't any problem I guess.

I have tried all things which I found on the internet.
Of course I clean/rebuild my project before. I had Q_OBJECT macro in game.h too.

PS. I delete some unnecessary code but if you want I can update this any time

Any help would be appreciated

d_stranz
20th April 2021, 01:10
Look again at the documentation and examples for QObject::connect().

- First, you do not pass actual arguments to the SIGNAL or SLOT macros when you call connect(), you simply provide the declaration or signature of the signal or slot. So if your SLOT declaration was valid (and it isn't - see the next point) the connect() statement would be:



connect(helpButton,SIGNAL(clicked()), this, SLOT(showHelp(Button &, Button &, Button &, Button &)));


But the above code is STILL WRONG, because

- Second, you cannot add more parameters to a slot definition than there are in the signal connected to it. So a signal "clicked()" with no parameters can only be connected to a slot with no parameters.



connect(helpButton,SIGNAL(clicked()), this, SLOT(someSlot()));


So, your "showHelp()" slot has to be defined with no parameters if you want to connect it to a clicked() signal with no parameters.

- Third, your displayMainMenu() slot looks as if you intend to call it every time the main menu is to be displayed. If that is your intention, then not only is it misnamed based on the code it contains, but I hope you realize that each time it is called it will create a complete new set of buttons and a complete new set of signal / slot connections for those buttons. And because you haven't saved those Button instances as member variables in your Game class, those pointers become zombies, inaccessible from the rest of your program. So there won't be any "Help" button visible to click, whether it is connected to a slot or not.

This type of setup code should be executed once, usually in a class constructor. If you intend for the Button instances to be part of the UI for your Game class, then they need to either be assigned as member variables of your class or created as children of your Game class instance and placed into a layout managed by the class.

- And finally, even if your use of SLOT() had been allowed, your declaration of the slot:

void showHelp(Button &start,Button &score,Button &help,Button &quit);

does not match your use of it in the connect() statement:


connect(helpButton,SIGNAL(clicked()), this, SLOT(showHelp(playButton, scoresButton, helpButton, quitButton)));

since "playButton", "scoresButton", "helpButton", and "quitButton" are Button * pointers, not Button & references.

nemaider
20th April 2021, 09:31
After your post I realized what mistakes I did. At first I will try assign as member variables these buttons and later remake showHelp function.

Thanks for your reply.

When I fix all errors in my project I will put solution here.

nemaider
20th April 2021, 20:35
Okey, now I've fixed all my problems which I came in this thread. Thank you d_stranz for your suggestions about make these buttons as member variables in Game class and connecting signals with slots. It work well.

For future users I can give one advice - don't connect no arguments signals with no argument slots. It was my main problem in this example.

d_stranz
20th April 2021, 22:56
For future users I can give one advice - don't connect no arguments signals with no argument slots. It was my main problem in this example.

This is not good advice at all. It is always appropriate to connect a signal with no arguments to a slot with no arguments. In fact, it is the only way such a signal can be connected. QPushButton::clicked() and QAction::triggered() are two very, very common cases of such signals*, and connecting them to no-argument slots is the only way to handle those signals.

I think you still have a basic misunderstanding of signals and slots, otherwise you would not make such a statement.

*Edit: QAbstractButton::clicked() and QAction::triggered() are actually overloaded methods - they come in two forms, one with a bool "checked" argument and another with the bool argument defaulted to false. The signals are usually connected to no-argument slots, which means the bool argument is ignored.