[Solved] NULL Model Pointer when passed through custom Widgets
-
I have a hunch as to what's causing this problem, but I don't know how QT works well enough to be sure. In an effort to modularize my program, I've taken to creating three custom widgets that I'd like to "talk" to each other using signals and slots, all encapsulated within a single widget. Here's the breakdown:
WidgetA
- Owns a model (verified working)
- Has WidgetB
WidgetB
- Is intended to display and modify a given model
- Has a QListView, and QPushButtons for adding/removing items from the model
- Has a QAbstractListModel pointer called internal_model
- Has a method setModel(QAbstractListModel* model) which sets internal_model to model, and sets the model for the QListView
The following is observed:
- The QAbstractListModel, model, is created in WidgetA
- Items are added to model in WidgetA
- WidgetB's setModel() is called
- WidgetB's QListView displays added items properly. internal_model is set to model.
- The QPushButton in WidgetB is pressed to insert a new row into the model (using a signal from the button, and a slot from WidgetB), interal_model is NULL.
I feel like this is a threading problem, but I don't know if QWidgets have their own threads. This isn't a critical problem, since I can just remove WidgetB's controls and move them into WidgetA, but an answer would be helpful just to gain a deeper understanding of QT and avoid similar problems in the future. I figured one of the primary benefits of a model was that it could be passed and shared without losing consistency, but there's clearly a limitation here I don't know about.
-
Hi and welcome to devnet,
No there's no per-widget thread at all, widgets only live the GUI thread which is generally the main thread. Can you share the code of your widgets ? It will be easier to spot the error.
One thing to check though: are you shadowing internal_model in WidgetB anywhere ?
-
Thanks for the kindly welcome and the reply! The NULL problem throws when calling InsertLayer due to the pressing of the "+" push button. Here's the code for each part of the program:
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { model = new LayersModel(this); qDebug() << "LayersModel created in MainWindow"; model->insertLayer(0, LayerType::Tile, "Test"); LayersWidget* widget = new LayersWidget(this); widget->setModel(model); setCentralWidget(widget); }
LayersWidget
class LayersWidget : public QWidget { Q_OBJECT public: explicit LayersWidget(QWidget *parent = 0); void setModel(LayersModel* model); signals: public slots: private: //UI Elements QListView* ui_lsvLayers; QPushButton* ui_btnAdd; QPushButton* ui_btnRemove; //Models LayersModel* mdl_layers; private slots: void insertLayer(); void removeLayer(); }; LayersWidget::LayersWidget(QWidget *parent) : QWidget(parent) { qDebug() << "New LayersWidget created."; mdl_layers = NULL; ui_lsvLayers = new QListView(this); ui_btnAdd = new QPushButton("+"); ui_btnAdd->setEnabled(false); connect(ui_btnAdd, SIGNAL(clicked()), this, SLOT(insertLayer())); ui_btnRemove = new QPushButton("-"); ui_btnRemove->setEnabled(false); connect(ui_btnRemove, SIGNAL(clicked()), this, SLOT(removeLayer())); QHBoxLayout* buttonBar = new QHBoxLayout; buttonBar->addWidget(ui_btnAdd); buttonBar->addWidget(ui_btnRemove); QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(ui_lsvLayers); mainLayout->addLayout(buttonBar); setLayout(mainLayout); } void LayersWidget::insertLayer() { if(mdl_layers != NULL) { NewLayerDialog layerDlg(this); if(layerDlg.exec() == QDialog::Accepted) { if(ui_lsvLayers->currentIndex() == QModelIndex()) { mdl_layers->insertLayer(0, layerDlg.getType(), layerDlg.getName()); } else { } } } } void LayersWidget::removeLayer() { } void LayersWidget::setModel(LayersModel *model) { qDebug() << "Model assigned"; ui_lsvLayers->setModel(model); ui_btnAdd->setEnabled(true); ui_btnRemove->setEnabled(true); }
-
Don't worry, it's something everybody did at one point or another.
Since you have found the problem, please update the thread title prepending [solved] so other forum users may know a solution has been found :)