Search code examples
c++qtqmainwindow

qt Program crush with segmentation fault while switching cental widget


I tried maybe everything but I just don't see a mistake in this code. I made two windows inherited from QMainWindow: one with qt designer and another just in constructor. I'm trying to switch these windows in the MainWindow class depending on what buttons you press.

  1. LoginWindow.cpp
LoginWindow::LoginWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::LoginWindow) {
    ui->setupUi(this);
}

LoginWindow::~LoginWindow() {
    delete ui;
}


void LoginWindow::on_confirmButton_clicked() {
    emit confirmButton_clicked();
}

  1. RegistrationWindow.hpp
RegistrationWindow::RegistrationWindow(QWidget* parent): QMainWindow(parent) {

    label = new QLabel("Fast Typing"); //variable in .hpp
    label->setAlignment(Qt::AlignCenter);
    label->setFont(QFont("Lucida Console", 12, 2));
    QVBoxLayout * l = new QVBoxLayout();
    l->addWidget(label);
    l->addWidget(new QLabel("Login", this));
    l->addWidget(new QLineEdit(this));
    l->addWidget(new QLabel("Password", this));
    l->addWidget(new QLineEdit(this));
    p = new QPushButton("Confirm", this); //variable in .hpp
    l->addWidget(p);
    w = new QWidget(); //variable in .hpp
    w->setLayout(l);
    setCentralWidget(w);

    connect(p, &QPushButton::clicked, this, &RegistrationWindow::on_confirmButton_clicked);
}

void RegistrationWindow::on_confirmButton_clicked() {
    emit confirmButton_clicked();
}

RegistrationWindow::~RegistrationWindow() { }
  1. MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    //variables in .hpp
    logWindow = new LoginWindow();
    regWindow = new RegistrationWindow();
    goToReg();

    connect(logWindow, SIGNAL(confirmButton_clicked()), this, SLOT(goToReg()));
    connect(regWindow, SIGNAL(confirmButton_clicked()), this, SLOT(goToLog()));
}

void MainWindow::goToReg() {
    qDebug() << "goToReg";
    resize(regWindow->size());
    qDebug() << "goToReg";
    setCentralWidget(regWindow);
    setWindowTitle("Registration");
    qDebug() << "registration: " << regWindow;
    qDebug() << "login: " << logWindow;
}

void MainWindow::goToLog() {
    qDebug() << "goToLog";
    resize(logWindow->size());
    qDebug() << "goToLog";
    setCentralWidget(logWindow);
    setWindowTitle("Login");
    qDebug() << "registration: " << regWindow;
    qDebug() << "login: " << logWindow;
}

All I could say is it switches windows no matter what I make a starting window and for second time it's crashes on the line setCentralWidget() in slot with SEGV runtime error.


Solution

  • From the documentation of QMainWindow::setCentralWidget:

    Note: QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time.

    The widgets that logWindow and regWindow point to start life unowned. Then you call goToReg(), which calls setCentralWidget(regWindow) - now the main window owns *regWindow. Then you call goToLog(), which calls setCentralWidget(logWindow) - now the main window takes ownership of *logWindow and destroys *regWindow, so regWindow becomes a dangling pointer. Next time you attempt to use it, the program exhibits undefined behavior.