Stanimirovv
Stanimirovv

Reputation: 3172

Qt Runtime Error when using a derived class

I Simply want to make a program in Qt, where you press one of two buttons and the text of a QLabel changes depending on the button you've changed. I am getting a runtime error when running the script. I made a "custom" window class for this program:

This is the header file:

#ifndef MW_H
#define MW_H
#include <QString>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QDialog>

class MW: public QDialog
{
 Q_OBJECT
    private:
    QPushButton* one;
    QPushButton* two;
    QLabel* three;
    QGridLayout* mainL;
public:
    MW();
    private slots:
    void click_1();
    void click_2();

};

#endif // MW_H

This is the .cpp for the header:

#include "MW.h"

MW :: MW()
{

    //create needed variables
    QGridLayout* mainL = new QGridLayout;
    QPushButton* one = new QPushButton("Set1");
    QPushButton* two = new QPushButton("Set2");
    QLabel* three = new QLabel("This text will be changed");

    //connect signals and slots

    connect(one, SIGNAL(clicked()), this, SLOT(click_1()));
    connect(two, SIGNAL(clicked()), this, SLOT(click_2()));

    // create layout
    mainL->addWidget(one, 1, 0);
    mainL->addWidget(two, 1, 1);
    mainL->addWidget(three, 0, 1);
    setLayout(mainL);
}


void MW :: click_1()
{
    three->setText("One Clicked me!");
}

void MW :: click_2()
{
    three->setText("Two Clicked me!");
}

And finally this is the main function:

#include <QApplication>
#include "MW.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MW w;
    w.setAttribute(Qt::WA_QuitOnClose);
    w.show();

    return a.exec();
}

This is the third or so small learning program I am doing and I am getting stuck at the same problem. It is starting to get a bit annoying. Any help will be appreciated.

Upvotes: 0

Views: 240

Answers (2)

Mat
Mat

Reputation: 206689

Your problem is this:

QGridLayout* mainL = new QGridLayout;
QPushButton* one = new QPushButton("Set1");
QPushButton* two = new QPushButton("Set2");
QLabel* three = new QLabel("This text will be changed");

You're creating four new variables with the same name as your class members. These new variables hide the class member. So with the above code, you never initialize MW::three in particular. When your slot is called, three->setText(...) dereferences an uninitialized pointer and stuff breaks.

Replace that code with:

mainL = new QGridLayout;
one = new QPushButton("Set1");
two = new QPushButton("Set2");
three = new QLabel("This text will be changed");

Upvotes: 1

Refugnic Eternium
Refugnic Eternium

Reputation: 4291

The error rests within your constructor.

QLabel* three = new QLabel("This text will be changed");

This line stores the new QLabel to a local variable instead of the class variable. As such, your class variable three remains empty. (As do the other three variables, but that's not the issue here, since you don't access them outside of the constructor)

To make long things short, amend your code like this:

MW :: MW()
{

    //create needed variables
    mainL = new QGridLayout;
    one = new QPushButton("Set1");
    two = new QPushButton("Set2");
    three = new QLabel("This text will be changed"); //This line, actually.

    //connect signals and slots

    connect(one, SIGNAL(clicked()), this, SLOT(click_1()));
    connect(two, SIGNAL(clicked()), this, SLOT(click_2()));

    // create layout
    mainL->addWidget(one, 1, 0);
    mainL->addWidget(two, 1, 1);
    mainL->addWidget(three, 0, 1);
    setLayout(mainL);
}

Like this, the variables in the class will be filled and your code should work as expected.

Upvotes: 3

Related Questions