PDA

View Full Version : Segmentation fault and lost ui pointer?



poporacer
18th December 2010, 23:42
Let me see if I can somehow make my mud clear. I have a mainwindow widget with a stacked widget. Each stack of the stacked widget is a class that is loaded when the mainwindow is constructed. I have a combo box on two of the stacked widgets that I need to sychronize. I use almost identical code to reload the QSettings info on the first stacked widget and then it passes the information to the second stacked widget but in doing so I get a segmentation fault. So a brief overview of the program is this.
1. Get the id of the last person used via QSettings.
2. Pass this id to the class of the first stacked widget.
3. The first stacked widget will get the corresponding index of the combobox and set it as the current index.
4. The combobox in the first stacked widget creates a signal on the combo box being changed calling the method from the class for the second stacked widget, passing the id.
5. The combobox in the second stacked widget will get the corresponding index of the combobox and set it as the current index.
The code in #3 and #5 are identical.
The problem seems to be that the pointer to the ui class of the second stacked widget gets lost (this is my guess, maybe not even a good guess).

In the class for the second stacked widget, I access the ui classes and manipulate them sucessfully until I call this from the other stacked widget, then I get the segmentation fault. The method gets called sucessfully but it seems like the pointer to the method gets lost.
Here is the relevant code for the main window that references the first stacked widget.
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>

//Forward declaration of classes used
class NamePage;
class ProjectPage;

namespace Ui {
class MainWindow;

}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

protected:
void changeEvent(QEvent *e);
void closeEvent (QCloseEvent *event);

private:
Ui::MainWindow *ui;
NamePage *name;
ProjectPage *project;

};

mainwindow.cpp

#include <QtSql>
#include <QSqlError>
#include <QDebug>
#include <QtGui>
#include "namepage.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "database.h"
#include "projectpage.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
name=new NamePage(this);
project = new ProjectPage(this);
ui->MainStackWidget->setCurrentIndex(0);
ui->MainStackWidget->addWidget(name);
ui->MainStackWidget->addWidget(project);
readSettings(); //this reads the last used id from the names in the database

void MainWindow::readSettings()
{
QSettings settings ("QT Test","Project Manager");
int indexId=settings.value("lastName",0).toInt();
name->restoreName(indexId);//this calls the method to set the combobox to the correct name in the first stacked widget.
}
}

namepage.h

#ifndef NAMEPAGE_H
#define NAMEPAGE_H
#include <QWidget>
class ProjectPage;

namespace Ui {
class NamePage;
}

class NamePage : public QWidget
{
Q_OBJECT

public:
explicit NamePage(QWidget *parent = 0);
~NamePage();
void restoreName(int);
int getLastName();

private:
Ui::NamePage *ui;
NamePage *name;
ProjectPage *project;
void updateNameComboBox();

};

#endif // NAMEPAGE_H

namepage.cpp

#include <QtGui>
#include <QtSql>
#include "namepage.h"
#include "ui_namepage.h"
#include "projectpage.h"

NamePage::NamePage(QWidget *parent) :
QWidget(parent),
ui(new Ui::NamePage)
{
ui->setupUi(this);
}

void NamePage::restoreName(int id)
{
if (id>=0)
{
int index = ui->cmbName->findData(id);
ui->cmbName->setCurrentIndex(index);
}
else
{
ui->cmbName->setCurrentIndex(0);
}
}
void NamePage::on_cmbName_currentIndexChanged()
{
project->restoreNameCombo(ui->cmbName->itemData(ui->cmbName->currentIndex()).toInt());//this works fine here!

}



projectpage.h

#ifndef PROJECTPAGE_H
#define PROJECTPAGE_H
#include <QWidget>

class NamePage;

namespace Ui {
class ProjectPage;

}

class ProjectPage: public QWidget
{
Q_OBJECT

public:
explicit ProjectPage(QWidget *parent = 0);
~ProjectPage();
void restoreName(int);
void restoreNameCombo(int);

private:
Ui::ProjectPage *ui;
ProjectPage *project;
NamePage *name;
void updateNameComboBox();

};

#endif // PROJECTPAGE_H


projectpage.cpp

#include <QDate>
#include <QtGui>
#include <QtSql>
#include <QDebug>
#include "projectpage.h"
#include "ui_projectpage.h"
#include "namepage.h"

ProjectPage::ProjectPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::ProjectPage)
{
ui->setupUi(this);
name=new NamePage;
ui->lblDate->setText(QDate::currentDate ().toString());//this ui class reference works
updateNameComboBox();
}
void ProjectPage::updateNameComboBox()
{

QSqlQuery query; //all appropriate references were previously implemented not shown for brevity
query.exec("SELECT id,LName, FName FROM name");
ui->cmbSecName->blockSignals(true);
ui->cmbSecName->clear();


while (query.next())
{
ui->cmbSecName->addItem(query.value (2).toString()+ " "
+ query.value (1).toString(),query.value (0).toInt());
ui->cmbSecName->blockSignals(false);

}// the above ui methods work
}
void ProjectPage::restoreNameCombo(int cmbId) //this is where the problem lies
{
if (cmbId>=0)
{
int cmbIndex=ui->cmbSecName->findData(cmbId);
ui->cmbSecName->setCurrentIndex(cmbIndex);
}
else
{
ui->cmbSecName->setCurrentIndex(0);
}
}

The above method works fine if called within the class itself, but when called from another class it creates the segmentation fault. I am using QT Creator and I searched on how to do a backtrace to post here, but I couldn't find anything that I could figure out. In debugging mode, when I get the segmentation fault at any ui reference the value for the this pointer is "unavailable sychroneous data".

Any ideas what might be going on?