Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Trying to programatically fill a model for QTableView



  • Hello,

    I have this class as my model for QTableView:

    class CScoreModel
    {
    public:
        CScoreModel(){}
    
        QString m_fileName;
        float m_score;
        static const int ColumnCount = 2;
    };
    
    class CScoreTableModel : public QAbstractTableModel
    {
        Q_OBJECT
    public:
        CScoreTableModel(QObject *parent) {}
        int rowCount(const QModelIndex &parent = QModelIndex()) const { return m_data.size(); }
        int columnCount(const QModelIndex &parent = QModelIndex()) const { return CScoreModel::ColumnCount; }
    // Never gets called
        QModelIndex index(int row, int column, const QModelIndex &parent) const {
          return createIndex(row, column, nullptr);
        }
    // Never gets called
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
        {
            int row = index.row();
            int col = index.column();
            const CScoreModel score = m_data[row];
            if (role == Qt::DisplayRole)
            {
               return QString("%1, %2")
                       .arg(score.m_score)
                       .arg(score.m_fileName);
            }
            return QVariant();
        }
    
        void AppendData(CScoreModel scoreModel)
        {
            int newRow = m_data.count();
            beginInsertRows(QModelIndex(), newRow, newRow);
            m_data.push_back(scoreModel);
            endInsertRows();
        }
    
    private:
        QVector<CScoreModel> m_data;
    };
    
    

    Then in my main window this is what I do:

    void MainWindow::on_actionOpen_triggered()
    {
    
        //static QString dialogResult = QFileDialog::getOpenFileName(this,"", "", "Images (*.png *.jpg);;Text files (*.txt);;XML files (*.xml)");
        QStringList dialogResult = QFileDialog::getOpenFileNames(this,"", "", "Images (*.png *.jpg)");
       // The data model - I should also note that I did try making the tabletModel a member of MainWindow to check whether it's the life cycle that ends once we go out of this function but still results were the same.
        CScoreTableModel tableModel(this);
        ui->tableViewScore->setModel(&tableModel); // Setting that to the table
    
        for (int fileIdx = 0; fileIdx < dialogResult.size(); fileIdx++)
        {
            loadedPixMap.load(dialogResult[fileIdx]);
            ui->labelImage->setScaledContents(true);
            ui->labelImage->setPixmap(loadedPixMap);
    
             float score = 0;
            // doing stuff to calculate a float
            ....
           //
            
            CScoreModel score; // Making an item
            score.m_fileName = dialogResult[fileIdx];
            score.m_score = score;
            // Appending the item to the model
            tableModel.AppendData(score);
            // Showing the content of the table view
            ui->tableViewScore->show();
        }
    }
    

    The problem I have is the data() function in the CScoreTableModel never gets called.

    What am I doing wrong?

    Thanks.



  • Yes, the life cycle is definitely a problem.
    You should show the code when making the tabletModel a member of MainWindow.
    And there's no need to call show() when appending data.



  • Yes, the life cycle is definitely a problem.
    You should show the code when making the tabletModel a member of MainWindow.
    And there's no need to call show() when appending data.



  • @Bonnie said in Trying to programatically fill a model for QTableView:

    Yes, the life cycle is definitely a problem.
    You should show the code when making the tabletModel a member of MainWindow.
    And there's no need to call show() when appending data.

    It turns out I was not initializing the table model in the constructor when making it a member.
    and you are correct the show() isn't needed.

    Now it all works.
    Thanks again!