Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] NULL Model Pointer when passed through custom Widgets
QtWS25 Last Chance

[Solved] NULL Model Pointer when passed through custom Widgets

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BitFrog
    wrote on last edited by BitFrog
    #1

    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.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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 ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • B Offline
        B Offline
        BitFrog
        wrote on last edited by
        #3

        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);
        }
        
        1 Reply Last reply
        0
        • B Offline
          B Offline
          BitFrog
          wrote on last edited by
          #4

          Now I feel foolish...I can't believe I forgot to store the pointer in setModel. No wonder it's invalid.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            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 :)

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • B Offline
              B Offline
              BitFrog
              wrote on last edited by
              #6

              Thanks for the advice. I saw other posts marked the same way, but wasn't sure how to do so.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved