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

tableView->setModel() does nothing



  • Hello,
    I've been trying to set the horizontal header of an existing tableWidget. But for some reason when applying it with setModel() nothing changes.
    However, applying the results of an SQL query works just fine.

        qm = new QSqlQueryModel();
        qm->setHeaderData(0, Qt::Horizontal, tr("Bezeichnung"));
        qm->setHeaderData(1, Qt::Horizontal, tr("Artikelnummer"));
        qm->setHeaderData(2, Qt::Horizontal, tr("Menge"));
        qm->setHeaderData(3, Qt::Horizontal, tr("Einzelpreis"));
        qm->setHeaderData(4, Qt::Horizontal, tr("Gesamtpreis"));
        //ui->tableView->horizontalHeader()->setModel(qm);
        ui->tableView->setModel(qm);
        //ui->tableView->show();
    


  • @SnuggleKat

        QSqlTableModel* qm = new QSqlTableModel(this);
    
         qm->setHeaderData (0,Qt::Horizontal, QObject::tr ("Bezeichnung"));
           qm->setHeaderData (1,Qt::Horizontal, QObject::tr ("Artikelnummer"));
             qm->setHeaderData (2,Qt::Horizontal, QObject::tr ("Menge"));
    
    ui->tableView->setModel(qm);
    
    

    try this.



  • @Vineela
    Still doesn't work



  • @SnuggleKat is it table view or table widget?



  • @Vineela said in tableView->setModel() does nothing:

    @SnuggleKat is it table view or table widget?

    Table view



  • @SnuggleKat are you fetching it from a particular table?



  • @Vineela said in tableView->setModel() does nothing:

    @SnuggleKat are you fetching it from a particular table?

    Nope. I want to set the table view's header if a certain push button is clicked. There's no dater inside the table



  • @SnuggleKat if yes use this

     QSqlTableModel* qm = new QSqlTableModel(this);
         qm->setTable(QStringLiteral("farmer"));
         qm->setFilter(("anyname = '"+yourvalue+"'"));
    
         qm->select();
         qm->setHeaderData (0,Qt::Horizontal, QObject::tr ("Bezeichnung"));
           qm->setHeaderData (1,Qt::Horizontal, QObject::tr ("Artikelnummer"));
             qm->setHeaderData (2,Qt::Horizontal, QObject::tr ("Menge"));
    
             ui->tableView->setModel(qm);
    


  • @Vineela no success. does it necessarily have to be a QSqlTableModel or QSqlQueryModel?



  • @SnuggleKat yes try QSqlTableModel that worked for me so.



  • @Vineela said in tableView->setModel() does nothing:

    s try QSqlTableModel that worked for me so.

    I see.. Can the setValue parameter be anything?



  • @Vineela Well, I have tried using QStandardItem and QStandardItemModel.

    QStandardItem* d = new QStandardItem("test");
    QStandardItemModel* im = new QStandardItemModel(this);
    im->setHorizontalHeaderItem(0, d);
    ui->tableView->setModel(im);

    It seems to be working

    EDIT: Well, Only the first cell of the header takes an actual value where the other 4 remaining cells only show their index number +1.

        QSqlTableModel* qm = new QSqlTableModel(this);
        QStringList str_list;
        str_list << "Bezeichnung" << "Artikelnummer" << "Menge" << "Einzelpreis" << "Gesamtpreis";
        QStandardItem* hItem = new QStandardItem("Bezeichnung");
        QStandardItemModel* im = new QStandardItemModel(this);
    
        for(int i = 0; i < 5; i++)
        {
            hItem->setData(str_list[i], 0);
            im->setHorizontalHeaderItem(i, hItem);
        }
        
        ui->tableView->setModel(im);
    


  • check the basic example in the docs as you can see you need to call at least setTable and select for the model to set up itself



  • @SnuggleKat if it is solved then mark it as Solved



  • @VRonin Still doesn't work.
    This is what I tried:

        QSqlTableModel* qm = new QSqlTableModel(this);
        qm->setTable(QStringLiteral("table"));
        qm->setEditStrategy(QSqlTableModel::OnManualSubmit);
        qm->select();
        qm->setHeaderData(0, Qt::Horizontal, QObject::tr("Bezeichnung"));
        qm->setHeaderData(1, Qt::Horizontal, QObject::tr("Artikelnummer"));
        qm->setHeaderData(2, Qt::Horizontal, QObject::tr("Menge"));
        qm->setHeaderData(3, Qt::Horizontal, QObject::tr("Einzelpreis"));
        qm->setHeaderData(4, Qt::Horizontal, QObject::tr("Gesamtpreis"));
        ui->tableView->setModel(qm);
        ui->tableView->show(); //don't think this is necessary since the tableView already exists
    

    @Vineela The method I have figured out doesn't work completely since it only shows the last header item at the first position



  • @SnuggleKat said in tableView->setModel() does nothing:

    Still doesn't work.

    Can you show up how you set up the default database?



  • @VRonin What do you mean by default database?
    I think it's QSqlDatabase::database() since I didn't specify anything but "this" inside the QSqlTableModel constructor.
    I have also tried using the connection database as parameter (without executing an SQL query). But it didn't help.
    This is the setup:

        QString username = ui->lineEdit_username->text();
        QString pw_decrypted = ui->lineEdit_pw->text();
        QString host = ui->lineEdit_ip->text();
    
        db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName(host);
        db.setPort(3306);
        db.setUserName(username);
        db.setPassword(pw_decrypted);
        db.setDatabaseName("bestellungen");
    
        if(db.open())
        { ui->label_status->setText("Verbunden über " + host + ":3306 \nals " + username); }
         else{ ui->label_status->setText("Verbindung fehlgeschlagen!"); }
    


  • @SnuggleKat
    I'm a little confused by what you're saying/reporting, so please excuse if this is incorrect.

    I believe you are saying you get to see the column headers when you use QStandardItemModel but not when you use QSql{Query/Table}Model. Is that right?

    Because my thought would be: when you use QStandardItemModel you are in charge of telling in what columns you want it to have. Whether that does or not, when you do a SQL query (Query or Table) it is not up to you to pick what/how many columns there are. That is determined by the result set returned from the query, So what/how many columns are there in the actual underlying SQL table or query you are executing?



  • @JonB said in tableView->setModel() does nothing:

    I believe you are saying you get to see the column headers when you use QStandardItemModel but not when you use QSql{Query/Table}Model. Is that right?

    Exactly. Even though when using QStandardItemModel I only get the last header item in the first header cell and the remaining header cells just contain numbers.

    I'm executing an SQL query from another function and write the results into this tableView. It works just fine and also generates the table head alongside its entries. But I'd also like to use this tableView to create new tables from scratch and save them into my database. This is why I want to initialize it with a table head.

    query->setQuery("SELECT * FROM `" + table_name + "`;");
        ui->tableView->setModel(query); //works fine
    

    EDIT:
    Also tried the following. Maybe this helps to identify the problem. I tried outputting what is found inside the header cells. It works for the QSqlQueryModel-one.
    qDebug() << query->headerData(0, Qt::Horizontal, Qt::DisplayRole);
    prints: "QVariant(QString, "Bezeichnung")"

    But it doesn't for the QSqlTableModel-one:
    qDebug() << qm->headerData(0, Qt::Horizontal, Qt::DisplayRole);
    prints: "QVariant(int, 1)"



  • @SnuggleKat

    But I'd also like to use this tableView to create new tables from scratch and save them into my database.

    Slightly unusual, but if you say so.... So if you want to use a QTableView to actually create a table which does not yet exist:

    • You cannot use a QSqlQuery or similar, as there is nothing in the existing database for the new table.

    • You will need to use a QStandardItemModel, no SQL.

    • Start with no columns, bind your QTableView to that model.

    • Invent a way for the user to specify he wants to insert a new column.

    • Depending on your chosen architecture, either store the desired ultimate SQL columns in rows in your QStandardItemModel, or if you want the designer to look more like what the new SQL table will look like use http://doc.qt.io/qt-5/qstandarditemmodel.html#insertColumn to insert new columns into your QStandardItemModel, which will show up as such in the QTableView.

    • When the user is happy and finally clicks some Create SQL Table from this button, bundle up the information you have stored in your QStandardItemModel's rows or columns so that you can generate the necessary SQL statement CREATE TABLE ... with the desired column definitons and execute that as a SQL command.

    • After that, once the table has been created, you can then attach a QTableView to it and you will get your view onto the new table with its columns.

    P.S.
    If you are thinking: "I'd like to use a QSqlTableModel to fetch all existing rows & columns from a current table to show to the user, and then I'd like to use http://doc.qt.io/qt-5/qabstractitemmodel.html#insertColumn to cause a new column to be created in the actual SQL table", you won't be able to do that. You need to follow some method along the lines ("CREATE TABLE ..." or "ALTER TABLE ..." SQL statement) I outlined to actually create new columns in the database table.



  • @JonB oof.. Ok, gonna try this. Would QTableWidgets work? (Is QSqlQuery the non-model counterpart to QSqlQueryModel?)



  • @SnuggleKat
    QTableWidget is just a specialised, configured convenience wrapper around QTableView for certain purposes. QTableWidget cannot do anything more than QTableView can do.

    Try to remember that the views are not really the place to "do" anything, at least to the backend. They just show a view on the model. When you want to "alter" things it is the backend model where you need to make your changes.

    Yes, QSqlQuery is the non-model counterpart to QSqlQueryModel (which in turn is the "non-table" counterpart to QSqlTableModel), though I'm not sure why you're asking that/relevance.

    P.S.
    If you're really saying you want to offer a "designer" to the user for creating new tables/columns, take a look at whatever tool you have for your database which lets users do that, e.g. MySQL Workbench. See how they do it and what interface they present, and bear that in mind as you design yours.



  • Well, I made it perfectly working by using QTableWidget and QSqlQuery instead!

        QSqlQuery* query = new QSqlQuery("SELECT * FROM `" + table_name + "`;");
        query->exec(query_str);
        qDebug() << "record: " << query->record();
    
        ui->tableWidget->setRowCount(query->size());
    
        for(int y = 0; y < query->size(); y++)
        {
            if(y == 0){query->first();}
            else{query->next();}
    
            for(int x = 0; x < 5; x++)
            {
               ui->tableWidget->setItem(y,x, new QTableWidgetItem(query->value(x).toString()));
            }
        }
    
        delete query;
    

    The table is now editable, can receive data from my SQL database and send them back :)


Log in to reply