Model/view - removing rows



  • Hi everyone,
    if you read my previous thread, I'm implementing a database program which will let me manage maintenance programs and status.
    Basically there will be a couple of Windows; one of them, will let the user input the checks to be done, their frequencies, etc..
    My approach was to create a model, to be displayed with QTableView after a push button has been pressed; so far, everything works fine. The issue comes when I'm trying to delete a row, I just can't do it!
    I tried several ways, from a theoretical point of view I do understand that based upon which row is selected by the user and after pressing the "delete row" button, I should get "something" referring to what is currently selected, and pass it to mymodel->removeRow - but I just can't do it!
    Here is my code for you to review:

    //#include "addnewmaintenanceprogram.h"
    #include "ui_addnewmaintenanceprogram.h"
    #include <QSqlQuery>
    #include <QSqlQueryModel>
    #include <QFormLayout>
    #include <QGroupBox>
    #include <QStandardItemModel>
    #include <QSqlTableModel>
    #include <QString>
    #include <QModelIndexList>
    
    
    AddNewMaintenanceProgram::AddNewMaintenanceProgram(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::AddNewMaintenanceProgram)
    {
        ui->setupUi(this);
    
        ui->tableView->hide();
        ui->pushButton_insertRow->hide();
        ui->pushButton_deleteRow->hide();
    
        QStandardItemModel *modelcreate = new QStandardItemModel(10,4,this);
    
        modelcreate->setHeaderData(0,Qt::Horizontal, tr("Action to be performed"));
        modelcreate->setHeaderData(1,Qt::Horizontal, tr("Frequency type"));
        modelcreate->setHeaderData(2,Qt::Horizontal, tr("Frequency"));
        modelcreate->setHeaderData(3,Qt::Horizontal, tr("Last executed"));
    
        ui->tableView->setModel(modelcreate);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->setColumnWidth(0,250);
        ui->tableView->resize(450,300);
    }
    
    AddNewMaintenanceProgram::~AddNewMaintenanceProgram()
    {
        delete ui;
    }
    
    
    
    
    
    void AddNewMaintenanceProgram::on_pushButton_Create_clicked()
    {
        ui->tableView->show();
        ui->pushButton_insertRow->show();
        ui->pushButton_deleteRow->show();
        modelcreate->setHeaderData(0,Qt::Horizontal, tr("Action to be performed"));
        modelcreate->setHeaderData(1,Qt::Horizontal, tr("Frequency type"));
        modelcreate->setHeaderData(2,Qt::Horizontal, tr("Frequency"));
        modelcreate->setHeaderData(3,Qt::Horizontal, tr("Last executed"));
        modelcreate->setRowCount(10);
        ui->tableView->setModel(modelcreate);
    }
    
    void AddNewMaintenanceProgram::on_pushButton_insertRow_clicked()
    {
        modelcreate->insertRow(modelcreate->rowCount());
    }
    
    
    void AddNewMaintenanceProgram::on_pushButton_Cancel_clicked()
    {
        close();
    }
    
    void AddNewMaintenanceProgram::on_pushButton_deleteRow_clicked()
    {
    //delete a row
    
          }
    }```
    
    

    Thanks for any help on this!
    Next step would be to have all the values inserted from the user with the "save" button, and upload them into SQLITE database...which is another thing.
    M.



  • @MR_mn
    I believe you're asking how your AddNewMaintenanceProgram::on_pushButton_deleteRow_clicked() knows what row to delete? So where is the code that shows what that is connected to?

    Also, do you have just one insert/delete button for the whole table, or do you have them against every row you are showing?


  • Lifetime Qt Champion

    Hi,

    Since you are using SQLite, why not make use of QSqlTableModel ?



  • @JonB
    Yes you're right, I'm asking how to delete a SELECTED row with that pushbutton; the reason why there is no code connected to that pushbutton is that I tried several ways of deleting the selected row, all of them found over the internet, but none of them actually worked, so I'm stuck! I'm kindly asking if anyone can give a hint and/or a link to some resources to understand how to correctly perform such an operation!
    I have only one delete button for the whole table, my aim is to have that button delete an user-selected row.
    Of course I may make things a little bit more complicate, adding a QDialog asking the user if he/she does really want to delete that row..but that's something I will add later!
    Thanks
    M.



  • @SGaist
    I'm actually a VERY beginner of Qt and C++ in general. I've had a look at the examples like "simple widget mapper example", and "SQL widget mapper", but I found the QStandardItemModel to be the easiest thing to use at this point of my Qt knowledge; what would be the advantage to use QSqlTableModel over QStandardItemModel? Consider that some data will probably be "shared" among tables (for example, the name of the maintenance program associated with a certain equipment will be stored both in the table maintenance and in the table equipment".

    Thanks and sorry for such a confusion!
    M.



  • @MR_mn

    First, wrt QSqlTableModel vs QStandardItemModel. The former knows all about SQL columns, SELECT/INSERT/DELETE/UPDATEs etc. for you; using the latter you have to write all the SQL code to do everything. However, it is only to be used for reading/writing a single SQL table, if you are saying you are combining data from multiple tables into a single UI widget then it's not obviously useful. Even if you don't use QSqlTableModel, QSqlQuery/QSqlQueryModel etc. might still make it easier to manage. By picking QStandardItemModel you have chosen something which knows nothing about there being any kind of database, so you're going to be writing a lot more code.

    Second, wrt your existing on_pushButton_deleteRow_clicked(), and "my aim is to have that button delete an user-selected row". For a QTableView there is http://doc.qt.io/qt-5/qtableview.html#selectedIndexes to tell you which row(s) is/are "selected". That gives you a (list of) QModelIndex (http://doc.qt.io/qt-5/qmodelindex.html#details). From that you can get the actual row data in the model for the row, and from there you do whatever you want (e.g. get the "primary key" column value and use that to generate a DELETE statement to delete the correct corresponding row in the SQL table). Read through the documentation links & examples.

    P.S.
    Let me say again: although it is possible to use QStandardModelItem, for what you are aiming to achieve it seems "unlikely" that this is the right choice. I suggest you look again at your intended design and the QSql... classes and see if you can't be using them, else you'll be having to write a lot more code for the database side further down the line....



  • @JonB
    Thanks for your answer, I think I'll have a deeper look at QSqlRelationalTableModel, which in turns seems to be the best choice to work with datables with "shared" content. I'll try, for the sake of gaining some more knowledge, to implement anyway the solution to delete a row in my tableview - you know, just to learn something new.
    Thanks
    M.



  • @MR_mn
    So you're aware, QSqlRelationalTableModel may indeed be what you're looking for, but it's the "hardest"/"most advanced" of the QSql... class levels. It still requires that there is a single underlying table which you are reading/writing --- Qt does not have inbuilt support for multiple tables in any one class --- , what it adds is the ability for a column in that table to display values from another table by "look up", which may be what you are intending....



  • @JonB
    Yes, I know QSqlRelationalTableModel is the hardest/most advanced of the QSql.. classes....and that is exactly why it was not my first choice, but then reading your answers and reading some material online, I think it's the ONLY choice I have.
    Regarding the "limitation" of only one table (at a time, I suppose), I wasn't aware of that and so thanks for letting me know about this feature; in this particular dialog, I will be working on just one table, and after saving the relative data, I will be prompted back to the "Add new equipment window", which in turn will create a record on another table, and to populate it some data of the previous table will be presented as a choice to the user - hope I was clear on that!
    Thanks for your support!!
    M.



  • @MR_mn
    QSqlRelationalTableModel only adds the "foreign key lookup" to QSqlTableModel. Other than that they are the same. So you could ignore that to begin with, you need to get your principles working for QSqlTableModel + QTableView to allow inserting/deleting etc.



  • @JonB
    Ok I'll try with QSqlTableModel first, then I'll try with QSqlTableModel after I get everything working.
    Regarding QSqlRelationalTableModel I've checked online and it seems there is only one non-commented example; by any chance, can you point me out at some resources to study?
    Thanks a lot
    M.



  • @MR_mn
    Nope, 'fraid, not, I'm purely a Qt "end user" like you, not an "expert" here. I just read the docs and code.... :)


Log in to reply
 

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