Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved Problem to access QStandardItemModel object

    General and Desktop
    2
    3
    151
    Loading More Posts
    • 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.
    • C
      Combas last edited by

      I have built a class which contains an object "QTreeView" linked to an object "QStandardItemModel".
      Inside this class, a button is linked to a "slot function" which inserts lines in the "QTreeView" and it works very well.
      But if I call this function from outside this object, it crashes because the functions of the object "QStandardItemModel" are not accessible anymore. And I don't understand why...

      The image below shows the very simple interface:

      • The object "QTreeView" with 2 columns
      • The left button "Insert Line" which belongs to the same class as the "QStandardItemModel" and the "QTreeView". This button is linked to a function "void InsertLine()" with QObject::connect process. This button works.
      • The button at the bottom "Test" does not belong to this class: it is connected to an intermediate function which calls the method "InsertLine()". This button does not work.
        0_1567190382667_View_interface.png

      The line which causes the crash is:

      nbColumns = SIM_table.columnCount();
      

      The header file of the main class "mainwindow.h" is:

      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include "blocktablefields.h"
      
      #include <QMainWindow>
      #include <QPushButton>
      #include <QStandardItemModel>
      #include <QTreeView>
      
      QT_BEGIN_NAMESPACE
      class QAction;
      class QLabel;
      class QMenu;
      QT_END_NAMESPACE
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          MainWindow();
      
      private slots:
          void Test();
      
      
      private:
          QWidget *centralWidget;
          QVBoxLayout *vertLayout_Main;
      
          BlockTableFields *BTF_test;
          QPushButton *BT_test;
      
      };
      
      #endif
      

      The corresponding .cpp file:

      
      #include <QtWidgets>
      
      #include "mainwindow.h"
      
      MainWindow::MainWindow()
      {
      
          QString titleTest;
          QList<QString> *listHeaders;
      
          // Initializations
          titleTest = QString("Tests");
          listHeaders = new QList<QString>;
          listHeaders->push_back("Field 1");
          listHeaders->push_back("Field 2");
      
          vertLayout_Main = new QVBoxLayout();
          BlockTableFields *BTF_test = new BlockTableFields(this, &titleTest, listHeaders);
          vertLayout_Main->addWidget(BTF_test);
      
          BT_test = new QPushButton("Test");
          QObject::connect(BT_test, SIGNAL(clicked()), this, SLOT(Test()));
          vertLayout_Main->addWidget(BT_test);
      
          centralWidget = new QWidget;
          setCentralWidget(centralWidget);
          centralWidget->setLayout(vertLayout_Main);
      
          setWindowTitle(tr("Test"));
          resize(400, 200);
      }
      
      void MainWindow::Test()
      {
          BTF_test->InsertLine();
      }
      
      

      The header file of the class which contains the objects "QTreeView" and "QStandardItemModel" is:

      #ifndef BLOCKTABLEFIELDS_H
      #define BLOCKTABLEFIELDS_H
      
      #include <QWidget>
      #include <QLabel>
      #include <QBoxLayout>
      #include <QPushButton>
      #include <QStandardItemModel>
      #include <QTreeView>
      
      class BlockTableFields : public QWidget
      {
          Q_OBJECT
      public:
          explicit BlockTableFields(QWidget *parent = nullptr, QString *blockTitle = nullptr, QList<QString> *listHeaders = nullptr);
      
      signals:
      
      
      public slots:
          void InitTable();
          void InsertLine();
      
      private:
          QLabel *LB_title;
          QStandardItemModel SIM_table;
          QTreeView *TV_table;
      
          QPushButton *BT_AddLineBefore;
      
          // Layouts
          QHBoxLayout *horizLayout_All;
          QVBoxLayout *vertLayout_Text;
          QVBoxLayout *vertLayout_Buttons;
      };
      
      #endif // BLOCKTABLEFIELDS_H
      
      

      The corresponding .cpp file:

      #include "blocktablefields.h"
      
      BlockTableFields::BlockTableFields(QWidget *parent, QString *blockTitle, QList<QString> *listHeaders) : QWidget(parent)
      {
          int numHeader;
      
          // Title
          LB_title = new QLabel();
          if (blockTitle != nullptr)
          {
              LB_title->setText(*blockTitle);
          }
      
          // Headers
          // if no header is given, a table with only 1 column is built, with an empty header
          // else, the number of columns is fixed by the number of headers
          if ((listHeaders != nullptr) && (listHeaders->size() > 0))
          {
              SIM_table.setColumnCount(int(listHeaders->size()));
              for (numHeader = 0; numHeader < int(listHeaders->size()); numHeader++)
              {
                  SIM_table.setHeaderData(numHeader, Qt::Horizontal, listHeaders->at(numHeader));
              }
          }
          else
          {
              SIM_table.setColumnCount(1);
              SIM_table.setHeaderData(0, Qt::Horizontal, QObject::tr(""));
          }
      
          // Creation of the first line
          InitTable();
      
          // Creation of the link between SIM_table and TV_table
          TV_table = new QTreeView;
          TV_table->setRootIsDecorated(false);
          TV_table->setAlternatingRowColors(true);
          TV_table->setModel(&SIM_table);
      
          // Buttons
          vertLayout_Buttons = new QVBoxLayout();
          // Add new line before the current line
          BT_AddLineBefore = new QPushButton("Insert Line");
          QObject::connect(BT_AddLineBefore, SIGNAL(clicked()), this, SLOT(InsertLine()));
          vertLayout_Buttons->addWidget(BT_AddLineBefore);
      
          // Spaces at the beginning and the end
          vertLayout_Buttons->insertStretch(0);
          vertLayout_Buttons->addStretch();
      
          // Vertical Layout (Title and field for text)
          vertLayout_Text = new QVBoxLayout();
          vertLayout_Text->addWidget(LB_title);
          vertLayout_Text->addWidget(TV_table);
      
          // Main Layout
          horizLayout_All = new QHBoxLayout();
          this->setLayout(horizLayout_All);
          horizLayout_All->addLayout(vertLayout_Buttons);
          horizLayout_All->addLayout(vertLayout_Text);
      
      }
      
      void BlockTableFields::InitTable()
      {
          int numColumn;
          QStandardItem *defaultItem = new QStandardItem(QString(""));
          QList<QStandardItem *> defaultLine;
          for (numColumn = 0; numColumn < SIM_table.columnCount(); numColumn++){ defaultLine.push_back(defaultItem); }
          SIM_table.insertRow(0, defaultLine);
      }
      
      void BlockTableFields::InsertLine()
      {
          QModelIndex tableIndex;
          int numLine = 0, numColumn, nbColumns;
          QStandardItem *defaultItem = new QStandardItem(QString(""));
          QList<QStandardItem *> defaultLine;
          nbColumns = SIM_table.columnCount();
          for (numColumn = 0; numColumn < nbColumns; numColumn++){ defaultLine.push_back(defaultItem); }
      
          tableIndex = TV_table->currentIndex();
          if (tableIndex.isValid())
          {
              numLine = tableIndex.row();
              SIM_table.insertRow(numLine, defaultLine);
              tableIndex = SIM_table.index(numLine, tableIndex.column());
              TV_table->setCurrentIndex(tableIndex);
          }
          else
          {
              numLine = 0;
              SIM_table.insertRow(numLine, defaultLine);
              tableIndex = SIM_table.index(numLine, 0);
              TV_table->setCurrentIndex(tableIndex);
          }
      }
      
      

      The complete project (very light) can be downloaded here:
      Complete_project

      If someone can tell me why it does not work, it would be very usefull for me!
      Thank you in advance for your help!
      Laurent

      1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        Your member MainWindow ::BTF_test is not initialized.
        Apart from this you're leaking listHeaders (don't know why you need a pointer here) and your InitTable does not set anything correct since you're setting the same item on more than one cell which is not allowed.

        Qt has to stay free or it will die.

        C 1 Reply Last reply Reply Quote 2
        • C
          Combas @Christian Ehrlicher last edited by

          @christian-ehrlicher
          Thank you very much for your answer !
          Indeed, there was a double declaration of "BTF_test" which was the cause of my problem.
          I will check the other points you mentionned to avoid new bugs.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post