Search code examples
c++qtqtableviewqsqltablemodel

Access qtableview qsqltablemodel from slot


I have seen a lot of tutorials / explanations that discuss similar problems, but I cannot figure out, how to apply it to this situation.

I am a Qt/C++ novice and trying to build simple GUI application that connects to an SQLite database. I have UI form, that was built using Qt Creator designer.

UI form contains QTableView widget that is connected to my table - all seems to work fine.

I also have a pushbutton, that should - eventually - add a row to the table. I have read, that I should not run “INSERT” query, but use methods exposed by QSqlTableModel instead. Unfortunately I cannot access my TableView data model from slot.

Here is my code:

1) mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QtSql>
#include <QFileInfo>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:


    void on_pushButtonChange_clicked();

    void on_pushButtonAdd_clicked();

private:
    Ui::MainWindow *ui;
    QSqlDatabase db;

};

#endif // MAINWINDOW_H

2) main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();

}

3) mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString dbType = "QSQLITE";
    QString dbName = “my.db";
    QString dbTable = “myTable”;

    db = QSqlDatabase::addDatabase(dbType);
    db.setDatabaseName(dbName);
    db.open();

    QSqlTableModel *model = new QSqlTableModel(this, db);
    model->setTable(dbTable);
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();

    ui->myTableView->setModel(model);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButtonAdd_clicked()
{

    //This is just to show, that I want to access QSqlTableModel from here:
    QSqlTableModel model = ui->myTableView->model();

}

When I run debug I am getting following error message:

error: no viable conversion from 'QAbstractItemModel *' to 'QSqlTableModel' QSqlTableModel model = ui->myTableView->model();

I understand the problem - I know that I could cast QAbstractItemModel to SQLTableModel, but this seems to be rather a workaround than the proper solution.

Could you please advise, how/where should I declare/define/instantiate my objects, so that I get access to QSqlTableModel feeding data to my TableView from mentioned Slot?


Solution

  • You can either keep the model as a MainWindow member data and access it from the slot, or qobject_cast<QSqlTableModel*>(model()) and check pointer is not null.

    Or even remove on_pushButtonAdd_clicked() method and connect directly the button event to the model insert method (using a lambda if needed), although this is probably not the better way to start with Qt (because slots connections are automagically disconnected when one of the two objects are deleted whereas connections to lambdas are not and thus are less error-prone).