Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Why I get "MainWindow does not refer to a value" when I trying to connect signal to a slot from another class?



  • Hello all,

    I get that error when I try to connect a signal from Menu Class to a slot from MainWindow class. why I get that error and how to solve it?

    Edited again:
    I dont know if I Explain well... I have a class A that has a QPushButton that emits a signal which the slot from class B who will receive it. please check my code.

    here my code:

    main.cpp

    #include "mainwindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "mainmenu.h"
    #include "gamemodepvp.h"
    
    #include <QGraphicsView>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setWindowState(Qt::WindowFullScreen);
        setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
        MainMenu *mainMenu = new MainMenu;
        setCentralWidget(mainMenu);
    }
    
    void MainWindow::modeVersusPlayer()
    {
            GameModePVP *scene = new GameModePVP;
            QGraphicsView *view = new QGraphicsView;
            view->setScene(scene);
            setCentralWidget(view);
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QApplication>
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    signals:
    
    public slots:
        void modeVersusPlayer();
    };
    
    #endif // MAINWINDOW_H
    

    mainmenu.cpp

    #include "mainmenu.h"
    
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QPushButton>
    #include <QPainter>
    #include <QStyleOption>
    
    MainMenu::MainMenu(QWidget *parent) : QWidget(parent)
    {
        setStyleSheet("background-color: white;");
    
        QPushButton *singlePlayer = new QPushButton;
        singlePlayer->setText("Single Player Game");
        QPushButton *doublePlayer = new QPushButton;
        doublePlayer->setText("Double Player Game");
        QPushButton *versusPlayer = new QPushButton;
        versusPlayer->setText("Player vs Player Game");
        QPushButton *buttonLoad = new QPushButton;
        buttonLoad->setText("Load Game");
        QPushButton *buttonExit = new QPushButton;
        buttonExit->setText("Exit");
    
        QVBoxLayout *menuLayout = new QVBoxLayout;
        menuLayout->addStretch();
        menuLayout->addWidget(singlePlayer);
        menuLayout->addWidget(doublePlayer);
        menuLayout->addWidget(versusPlayer);
        menuLayout->addWidget(buttonLoad);
        menuLayout->addWidget(buttonExit);
        menuLayout->addStretch();
    
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addStretch();
        mainLayout->addLayout(menuLayout);
        mainLayout->addStretch();
    
        setLayout(mainLayout);
    
        connect(buttonExit,SIGNAL(clicked()),this,SLOT(quitApplication()));
        connect(versusPlayer,SIGNAL(clicked()),MainWindow,SLOT(modeVersusPlayer())); <--here I get the error
    }
    
    void MainMenu::quitApplication()
    {
        qApp->quit();
    }
    
    void MainMenu::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QStyleOption opt;
        opt.initFrom(this);
        style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
    }
    

    mainmenu.h

    #ifndef MAINMENU_H
    #define MAINMENU_H
    
    #include "mainwindow.h"
    
    #include <QWidget>
    
    class MainMenu : public QWidget
    {
        Q_OBJECT
    
    private:
        void paintEvent(QPaintEvent*) override;
    
    public:
        explicit MainMenu(QWidget *parent = nullptr);
    
    signals:
    
    public slots:
        void quitApplication();
    };
    #endif // MAINMENU_H
    

  • Lifetime Qt Champion

    Because MainWindow is a class, not an object. You want this.



  • it doesnt work =(, now It say I dont have such slot. I cant see the public slot from MainWindow.


  • Lifetime Qt Champion

    @HelloWorld88

    So you got
    connect(versusPlayer,SIGNAL(clicked()),this,SLOT(modeVersusPlayer()));

    so if it complains try clean all, rebuild all.
    (or delete all in build folder, and rebuild)

    wait.,
    class MainMenu : public QWidget
    dont have this slot ?

    Its in MainWindow ?

    In that case, it will be easier to do the connect in MainWindow where you create the MainMenu.
    Else you will need a MainWindow Pointer inside MainMenu.

    Hmm you MainWindow seems very empty besides that slot.

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    .......
    public slots:
        void modeVersusPlayer();
    };
    

    So you did mean to connect from MainMENU to MainWindow and not simply have the slot in menu ?



  • @mrjj

    When I run the program it will show the MainWindow that contain the MainMenu in the Center:
    Capture.PNG
    mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setWindowState(Qt::WindowFullScreen);
        setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
        MainMenu *mainMenu = new MainMenu;
        setCentralWidget(mainMenu);
    }
    

    but when I click for example Player vs Player Game button I want it to change the Central Widget of MainWindow to a QGraphicsView Widget. So I write this function in MainWindow to set another widget on the center.

    void MainWindow::modeVersusPlayer()
    {
            GameModePVP *scene = new GameModePVP;
            QGraphicsView *view = new QGraphicsView;
            view->setScene(scene);
            setCentralWidget(view);
    }
    

    but I dont know how to connect it from MainMenu.

    MainMenu::MainMenu(QWidget *parent) : QWidget(parent)
    {
        setStyleSheet("background-color: white;");
    
        QPushButton *singlePlayer = new QPushButton;
        singlePlayer->setText("Single Player Game");
        QPushButton *doublePlayer = new QPushButton;
        doublePlayer->setText("Double Player Game");
        QPushButton *versusPlayer = new QPushButton;
        versusPlayer->setText("Player vs Player Game");
        QPushButton *buttonLoad = new QPushButton;
        buttonLoad->setText("Load Game");
        QPushButton *buttonExit = new QPushButton;
        buttonExit->setText("Exit");
    
        QVBoxLayout *menuLayout = new QVBoxLayout;
        menuLayout->addStretch();
        menuLayout->addWidget(singlePlayer);
        menuLayout->addWidget(doublePlayer);
        menuLayout->addWidget(versusPlayer);
        menuLayout->addWidget(buttonLoad);
        menuLayout->addWidget(buttonExit);
        menuLayout->addStretch();
    
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addStretch();
        mainLayout->addLayout(menuLayout);
        mainLayout->addStretch();
    
        setLayout(mainLayout);
    
        connect(buttonExit,SIGNAL(clicked()),this,SLOT(quitApplication()));
    }
    
    void MainMenu::quitApplication()
    {
        qApp->quit();
    }
    

    I only know how to connect the signal to a slot that is in the same class. also with MainWindow Pointer inside MainMenu it crash the program.



  • @HelloWorld88 said in Why I get "MainWindow does not refer to a value" when I trying to connect signal to a slot from another class?:

    but when I click for example Player vs Player Game button I want it to change the Central Widget of MainWindow to a QGraphicsView Widget. So I write this function in MainWindow to set another widget on the center.

    You should use QStackedWidget for this.

    but I dont know how to connect it from MainMenu.

    Don't. Connect it from MainWindow, using MainWindow::mainMenu to access the widget for the signal. Connect that to your slot in MainWindow, if that's what you want to do.

    also with MainWindow Pointer inside MainMenu it crash the program.

    :) You don't need or want that. No need for MainMenu to know it's inside MainWindow.


Log in to reply