[solved]Total amount of column in TableView/Model



  • Hi!

    How can I calculate the total amount of a column in a model-based tableview and show it in a label.

    I will show you my question in this picture: http://postimg.org/image/5fnhwo43x/

    Thanks a lot!

    Franz



  • Try using QAbstractItemModel::rowCount()

    Edit: I failed miserably at interpretion...

    Try something like:

    int val=0;
    for(int i=0; i<model->rowCount(); i++)
    {
        val+=model->data(model->index(i,COL_D,QModelIndex())).toInt();
    }

  • Moderators

    @Mr.-Kibu From the screenshot it seems you are trying to add the data of all rows and column 4. In that case you need to iterate through the model get the data of interest. You will need QAbstractItemModel::index and QAbstractItemModel::data to get the data. Iterate through the rows using rowCount. A typical example would be:

    for(int i=0; i<rowCount(); i++) {
        QModelIndex modelIndex = this->index(i,3); //your column
        qDebug() << modelIndex.data(MyRole).toInt(); //Use specific role in case of QML
    }
    


  • I do not want the quantity of rows. I want the total amount of the values in column D (in my example 11). Is this possible with QAbstractItemModel::rowCount()? If yes, how can I do it?


  • Moderators

    @Mr.-Kibu Did you try the above example ? You just have to add those values.



  • @Mr.-Kibu
    Hi! There is no special fucntion to calculate sum. Model is just an interface between your data and view. So if you want to calculate a sum of the column you could just implement special method in your QAbstractItemModel subclass. For example:

    int CalcColumnSum(int column)
    {
           int s=0;      
           for(int i=0;i<rowCount();++i)  
                  s+=index.(i,column,QModelIndex()).data(Qt::DisplayRole).toInt();
           return s;
    }
    

    But in fact, as I said before model is just an interface, so you don't need to interact with it to obtain data. You can obtain it directly, because you know your data structure. I don't, that why I made general example



  • Thank you to Harb! When I use your code like this, it works:

        QSqlTableModel *testTab = new QSqlTableModel(this, ConnProjectDB::db());
    
        testTab->setTable("Test");
        testTab->select();
        ui->tableView->setModel(testTab);
    
        int s=0;
        for(int i=0;i<testTab->rowCount();++i)
               s+=testTab->index(i,3,QModelIndex()).data(Qt::DisplayRole).toInt();
    
         QString c = QString::number(s);
         ui->label->setText(c);
    

    But if I subclass the code like this:

    h:

    private slots:
    
         int CalcColumnSum(int column, QSqlTableModel model);
    

    cpp:

        QSqlTableModel *testTab = new QSqlTableModel(this, ConnProjectDB::db());
    
        testTab->setTable("Test");
        testTab->select();
        ui->tableView->setModel(testTab);
    
        QString c = QString::number(CalcColumnSum(3,testTab));
        
        ui->label->setText(c);
    
    
    int CalcColumnSum(int column, QSqlTableModel model)
    {
           int s=0;
           for(int i=0;i<model.rowCount();++i)
                  s+=model.index(i,column,QModelIndex()).data(Qt::DisplayRole).toInt();
    
    }
    

    I get this error-message on building:

    "/home/franz/Dokumente/IT/QT/Projekte/BiFF/src/mainwindow.cpp:57: Fehler: no matching function for call to 'MainWindow::CalcColumnSum(int, QSqlTableModel*&)'
    QString c = QString::number(CalcColumnSum(3,testTab));
    ^"

    Is there a better way to obtain my data. Where can I obtain it directly (from the database, the tableview, )?
    In the future I want to subclass the tableview in a QSortfilterproxymodel like this:
    https://doc.qt.io/archives/4.6/itemviews-customsortfiltermodel.html

    Than I want to get the total amount from the filtered rows!

    Thank you!


  • Lifetime Qt Champion

    Hi,

    You slot signature is the problem. You can't copy a QSqlTableModel object, it's a QObject and their copy is not allowed
    .



  • Okay, and what is the correct slot signature instead of "int CalcColumnSum(int column, QSqlTableModel model);"?



  • Is it the right way to add a pointer to the signature like this:

    CalcColumnSum(int column, QSqlTableModel *model)
    

    But now I get the error

    undefined reference to `MainWindow::CalcColumnSum(int, QSqlTableModel)*

    at the position

    QString c = QString::number(CalcColumnSum(3,testTab));
    

    Thank's for help!!

    Franz


  • Moderators

    You have to change the definition of CalcColumnSum(int column, QSqlTableModel *model) in .cpp file as well:
    CalcColumnSum(int column, QSqlTableModel *model)
    {
    ...
    }

    Actually, you can use a reference instead of pointer: CalcColumnSum(int column, QSqlTableModel &model)



  • Sorry, I have not said that I have already changed the definition of CalcColumnSum in cpp to "CalcColumnSum(int column, QSqlTableModel *model)".

    But the error is still here!


  • Lifetime Qt Champion

    On a side note, it's not common practice for slots to return values



  • The difinition of CalcColumnSum is now:

    int CalcColumnSum(int column, QSqlTableModel *model)
    {
    
        int s=0;
           for(int i=0;i< model->rowCount();++i)
                  s+=model->index(i,column,QModelIndex()).data(Qt::DisplayRole).toInt();
    
    }
    

    But the error is still here ....



  • Very stupid mistake:
    I have forgotten to use "MainWindow::" in the definition. Here it is:

    void MainWindow::CalcColumnSum(int col,QSqlTableModel *model)
    {
    ...
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.