Search code examples
qtqthreadqpushbuttonqt-signalsslots

Slot is not detected when QPushbutton is released


I am currently making a main menu for a game, but when the button is clicked it does not seem to call the relevant slot (The button does not do anything). I have tried to move the button to a thread to ensure that nothing is keeping it from running immediately. I have written a simpler program where the button works, so it would seem the problem is not with the button or signal itself. Therefore it must be something keeping it from running? The source file is given as:

    #include <QGraphicsScene>
    #include <QGraphicsView>
    #include <QObject>
    #include <QBrush>
    #include"game.h"
    #include <QMediaPlayer>
    #include <QImage>
    #include<QGraphicsPixmapItem>
    #include <QPixmap>
    #include<QGraphicsItem>
    #include <QPushButton>
    #include <QLineEdit>
    #include <QPalette>
    #include <QMessageBox>
    #include <QLabel>
    #include <QComboBox>

    Game::Game(QWidget*parent)
    {
    //adding the background

    QGraphicsScene *scene=new QGraphicsScene();//to create a new graphics scene
    scene->setSceneRect( 0,0,1366,768);
    setBackgroundBrush(QBrush(QImage(":/images/Back_1_withlogo.jpg")));
    setScene(scene);
    show();
    setFixedSize(1366,768);

    //adding logo
        //setPixmap(QPixmap(":/images/Logo.png"));
    //adding the soundtrack

    music=new QMediaPlayer();
    music->moveToThread(&MusicThread);
    music->setMedia(QUrl("qrc:/sounds/Surreal-Game-Menu.mp3"));
    music->play();
    MusicThread.start();


    //add GUI
    this->setFixedSize(1366,768);
    this->move(-7,-5);
    //start button and username edit box
    btnStart = new QPushButton(this);
    btnStart->moveToThread(&btnThread);

    UserName = new QLineEdit(this);
    UserName->setFixedSize(100,25);
    UserName->move(300,300);
    UserName->show();
    UserName->setMaxLength(12);

    btnStart->setText("Start");
    btnStart->setFixedSize(100,30);
    btnStart->show();
    btnStart->move(300,600);
    connect(btnStart, SIGNAL (released()),this, SLOT (btnStart_clicked()));
    btnThread.start();

    //label for username edit box
    QLabel *LblUsername= new QLabel(this);
    LblUsername->setStyleSheet("QLabel { color : white; }");
    LblUsername->setFixedSize(100,30);
    LblUsername->move(230,300);
    LblUsername->setText("Username:");
    LblUsername->show();

    QLabel *lblGameMode = new QLabel(this);
    lblGameMode->setStyleSheet("QLabel { color : white; }");
    lblGameMode->setFixedSize(100,30);
    lblGameMode->move(190,450);
    lblGameMode->setText("Select Game mode:");
    lblGameMode->show();

    //combobox to select players
    GameMode=new QComboBox(this);
    GameMode->move(300,450);
    GameMode->setFixedSize(100,30);
    QStringList Modelist=(QStringList()<<"singleplayer"<<"co-op"<<"multiplayer (3 players)");
    GameMode->addItems(Modelist);
    GameMode->show();
    }

    void Game::btnStart_clicked()
     {
     if (UserName->text()==NULL)
     {
         QMessageBox messageBox;
         messageBox.critical(0,"Error","Please insert username!");
         messageBox.setFixedSize(500,200);
     }
     else
     {
         numPlayers = GameMode->currentIndex();
         SUsername= UserName->text();
         UserName->setText("works");
     }
     }

And the header code is given as:

    #ifndef GAME_H
    #define GAME_H

    #include <QGraphicsScene>
    #include <QGraphicsView>
    #include <QWidget>
    #include <QPushButton>
    #include <QLineEdit>
    #include <QMediaPlayer>
    #include <QThread>
    #include <QComboBox>


    class Game:public QGraphicsView
    {
    public:
        Game(QWidget*parent=0);
        QGraphicsScene*scene;
    private slots:
        void btnStart_clicked();
    private:
        QPushButton *btnStart;
        QLineEdit *UserName;
        QMediaPlayer *music;
        QThread MusicThread;
        QString SUsername;
        QThread btnThread;
        QComboBox *GameMode;
        int numPlayers;

    };
    #endif // GAME_H

I received the following error:

    QObject::connect: No such slot QGraphicsView::btnStart_clicked() in game.cpp:57

Solution

  • add a Q_OBJECT macro as shown below:

    class Game:public QGraphicsView
        {
        Q_OBJECT
        public:
            Game(QWidget*parent=0);
            QGraphicsScene*scene;
        private slots:
            void btnStart_clicked();
        private:
            QPushButton *btnStart;
            QLineEdit *UserName;
            QMediaPlayer *music;
            QThread MusicThread;
            QString SUsername;
            QThread btnThread;
            QComboBox *GameMode;
            int numPlayers;
    
        };
    

    This macro helps compiler to determine that the class is using signals and slots mechanism. Basically it creates a entry of defined signals and slots in MOC (meta object compiler) file. Go through below link for info: http://www.bogotobogo.com/Qt/Qt5_Q_OBJECT_Macro_Meta_Object.php