Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem to access QStandardItemModel object
Qt 6.12 LTS is out! See what's new in the release blog

Problem to access QStandardItemModel object

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 670 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.
  • C Offline
    C Offline
    Combas
    wrote on last edited by
    #1

    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
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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 Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      C 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        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.

        C Offline
        C Offline
        Combas
        wrote on last edited by
        #3

        @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
        0

        • Login

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