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

QSqlTableModel and QTableView wont populate or even show headers



  • I've never used the QSqlTableModel before and haven't done much SQL with QT either. I have built out the following:

    #include "editwidget.h"
    // This is the editwidget.cpp file
    EditWidget::EditWidget()
    {
    
        main_view = new QTableView();
        view_button = new QPushButton();
        close_button = new QPushButton();
        primary_layout = new QGridLayout();
    
    }
    
    
    QWidget* EditWidget::initialize_widget()
    {
        return create_widget(primary_layout, main_view, view_button, close_button);
    }
    
    QWidget* EditWidget::create_widget(QGridLayout *layout, QTableView *view, QPushButton *button_one, QPushButton *button_two)
    {
        button_one->setText("View");
        button_one->setToolTip("Click here to load the page where you can view your entries.");
        button_two->setText("Close");
        button_two->setToolTip("Click here to close the program.");
    
        QSqlTableModel *model = new QSqlTableModel;
    
        model->setTable("Tracking");
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        model->select();
        model->setHeaderData(0, Qt::Horizontal, tr("INR"));
        model->setHeaderData(1, Qt::Horizontal, tr("Dose"));
        model->setHeaderData(2, Qt::Horizontal, tr("Date"));
        model->setHeaderData(3, Qt::Horizontal, tr("Time"));
    
        view->setModel(model);
        view->hideColumn(0);
        view->show();
    
        layout->addWidget(view, 0, 0);
        layout->addWidget(view_button, 1, 0);
        layout->addWidget(close_button, 2, 0);
        QWidget *primary_widget = new QWidget();
        primary_widget->setLayout(layout);
        layout->setAlignment(Qt::AlignHCenter);
        return primary_widget;
    }
    
    
    // This is tyhe editwidget.h file
    #ifndef EDITWIDGET_H
    #define EDITWIDGET_H
    #include "QLayout"
    #include "QPushButton"
    #include "QLineEdit"
    #include "QLabel"
    #include "QCheckBox"
    #include "QFormLayout"
    #include "QButtonGroup"
    #include "QStackedWidget"
    #include "QWidget"
    #include "QSqlTableModel"
    #include "QTableView"
    
    class EditWidget : public QWidget
    {
        Q_OBJECT
    public:
        EditWidget();
        QWidget* initialize_widget();
    
        QTableView *main_view;
        QPushButton *view_button;
        QPushButton *close_button;
    
    
    private:
        QWidget* create_widget(QGridLayout *layout, QTableView *view, QPushButton *button_one, QPushButton *button_two);
    
        QGridLayout *primary_layout;
    };
    
    #endif // EDITWIDGET_H
    
    

    When I run the program I have no issues, the user is presented with two options. The first is to Input data and the second is to view data, the code above is for inputting data. When the user clicks the button edit data the above widget should kick in. The widget shows up both of my buttons are there but there is an empty white view with no rows or columns or header data.

    The DB is opened in MainWindow.cpp when it runs so I thought

    QSqlTableModel *model = new QSqlTableModel;
    

    would just pull from the active connection but I guess not? Can anyone point me in the right direction.


  • Lifetime Qt Champion

    Your code does not compile at all.
    What should initialize_widget() do? Why does it create a new widget? I would guess it should initialize the current one, or?



  • @Christian-Ehrlicher I'm sorry I didn't post all of the code, only that particular widget because I wasn't sure if there would be something just totally blatantly wrong. Yes, the initialize_widget() returns the result of create_widget() which is where everything gets setup. I've posted everything below, thank you for your help!

    1. MainWindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        main_frame = new QFrame(this);
        key_widget = new QStackedWidget();
        key_widget->addWidget(mainwidget.initialize_widget());
        key_widget->insertWidget(1, editwidget.initialize_widget());
        initialize_main_window();
        initialize_connections();
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(get_database_path());
        verify_integrity();
    
    
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    
    void MainWindow::initialize_main_window()
    {
        setCentralWidget(key_widget);
    }
    
    
    void MainWindow::initialize_connections()
    {
       connect(mainwidget.edit_button, &QPushButton::clicked, this, &MainWindow::load_edit_window);
    }
    
    
    void MainWindow::load_view_window()
    {
    
    }
    
    void MainWindow::load_edit_window()
    {
        key_widget->setCurrentIndex(1);
    }
    
    void MainWindow::verify_integrity()
    {
        if(QSysInfo::productType() == "windows")
        {
            if(!QDir(QDir::toNativeSeparators((QDir::homePath() + "/Documents/ITracker/"))).exists())
            {
               QDir().mkdir(QDir().toNativeSeparators(QDir::homePath() + "/Documents/ITracker/"));
               QFile db_file(QDir::toNativeSeparators(QDir::homePath() + "/Documents/ITracker/Data.db"));
               db_file.open(QIODevice::WriteOnly);
               create_tables();
    
            }
            else
            {
                // Die here
            }
        }
        else if(QSysInfo::productType() == "linux")
        {
    
        }
        else if(QSysInfo::productType() == "osx")
        {
    
        }
        else
        {
            //die here
        }
    }
    
    
    void MainWindow::create_tables()
    {
        QString tables = ("create table Tracking("
                          "INR REAL primary key,"
                          "Dose REAL,"
                          "Date TEXT,"
                          "Time TEXT)");
        add_tables(tables);
    
    }
    
    
    void MainWindow::add_tables(QString str)
    {
          QSqlDatabase n_db = QSqlDatabase::database();
          n_db.transaction();
          QSqlQuery query;
          query.exec(str);
          n_db.commit();
    }
    
    QString MainWindow::get_database_path()
    {
        if(QSysInfo::productType() == "windows")
        {
            return QDir::toNativeSeparators(QDir::homePath() + "/Documents/ITracker/Data.db");
        }
        else if(QSysInfo::productType() == "linux")
        {
    
        }
        else if(QSysInfo::productType() == "osx")
        {
    
        }
        else
        {
            // die here
        }
    }
    
    1. MainWindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QFrame>
    #include <QStackedWidget>
    #include <QDir>
    #include <QString>
    #include <QSqlQuery>
    
    
    #include "mainwidget.h"
    #include "editwidget.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    
    private:
        Ui::MainWindow *ui;
        MainWidget mainwidget;
        EditWidget editwidget;
    
        QFrame *main_frame;
        QStackedWidget *key_widget;
        //QSqlDatabase db;
    
        void initialize_main_window();
        void initialize_connections();
        void load_view_window();
        void load_edit_window();
        void verify_integrity();
        void create_tables();
        void add_tables(QString str);
        QString get_database_path();
    
    
    };
    #endif // MAINWINDOW_H
    
    
    1. Mainwidget.cpp
    #include "mainwidget.h"
    
    MainWidget::MainWidget()
    {
      edit_button = new QPushButton();
      view_button = new QPushButton();
      primary_layout  = new QVBoxLayout();
    }
    
    
    QWidget* MainWidget::initialize_widget()
    {
        return create_widget(edit_button, view_button, primary_layout);
    }
    
    
    QWidget* MainWidget::create_widget(QPushButton *button_one, QPushButton *button_two, QVBoxLayout *layout)
    {
    
        button_one->setText("Input");
        button_one->setToolTip("Clicking this button will bring you to a new page. You can enter your values on that page.");
    
        button_two->setText("View");
        button_two->setToolTip("Clicking this button will bring you to a new page. On that page you can choose how to view your data and then view it.");
    
        layout->addWidget(button_one);
        layout->addWidget(button_two);
    
        QWidget *main_widget = new QWidget();
        main_widget->setLayout(layout);
        primary_layout->setAlignment(Qt::AlignHCenter);
        return main_widget;
    }
    
    
    1. Mainwidget.h
    #ifndef MAINWIDGET_H
    #define MAINWIDGET_H
    #include "QLayout"
    #include "QPushButton"
    #include "QLineEdit"
    #include "QLabel"
    #include "QCheckBox"
    #include "QFormLayout"
    #include "QButtonGroup"
    #include "QStackedWidget"
    #include "QWidget"
    
    
    class MainWidget : public QWidget
    {
        Q_OBJECT
    public:
        MainWidget();
    
    
        QPushButton *edit_button;
        QPushButton *view_button;
    
    
        QWidget* initialize_widget();
    
    private:
    
        //QWidget *primary_widget;
        QVBoxLayout *primary_layout;
        QWidget* create_widget(QPushButton *button_one, QPushButton *button_two, QVBoxLayout *layout);
    
    
    
    };
    
    #endif // MAINWIDGET_H
    
    
    1. Editwidget.cpp
    #include "editwidget.h"
    
    EditWidget::EditWidget()
    {
    
        main_view = new QTableView();
        view_button = new QPushButton();
        close_button = new QPushButton();
        primary_layout = new QGridLayout();
    
    }
    
    
    QWidget* EditWidget::initialize_widget()
    {
        return create_widget(primary_layout, main_view, view_button, close_button);
    }
    
    QWidget* EditWidget::create_widget(QGridLayout *layout, QTableView *view, QPushButton *button_one, QPushButton *button_two)
    {
        button_one->setText("View");
        button_one->setToolTip("Click here to load the page where you can view your entries.");
        button_two->setText("Close");
        button_two->setToolTip("Click here to close the program.");
    
        QSqlTableModel *model = new QSqlTableModel;
    
        model->setTable("Tracking");
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        model->select();
        model->setHeaderData(0, Qt::Horizontal, tr("INR"));
        model->setHeaderData(1, Qt::Horizontal, tr("Dose"));
        model->setHeaderData(2, Qt::Horizontal, tr("Date"));
        model->setHeaderData(3, Qt::Horizontal, tr("Time"));
    
        view->setModel(model);
        view->hideColumn(0);
        view->show();
    
        layout->addWidget(view, 0, 0);
        layout->addWidget(view_button, 1, 0);
        layout->addWidget(close_button, 2, 0);
        QWidget *primary_widget = new QWidget();
        primary_widget->setLayout(layout);
        layout->setAlignment(Qt::AlignHCenter);
        return primary_widget;
    }
    
    
    1. Editwidget.h
    #ifndef EDITWIDGET_H
    #define EDITWIDGET_H
    #include "QLayout"
    #include "QPushButton"
    #include "QLineEdit"
    #include "QLabel"
    #include "QCheckBox"
    #include "QFormLayout"
    #include "QButtonGroup"
    #include "QStackedWidget"
    #include "QWidget"
    #include "QSqlTableModel"
    #include "QTableView"
    
    class EditWidget : public QWidget
    {
        Q_OBJECT
    public:
        EditWidget();
        QWidget* initialize_widget();
    
        QTableView *main_view;
        QPushButton *view_button;
        QPushButton *close_button;
    
    
    private:
        QWidget* create_widget(QGridLayout *layout, QTableView *view, QPushButton *button_one, QPushButton *button_two);
    
        QGridLayout *primary_layout;
    };
    
    #endif // EDITWIDGET_H
    
    

    the .pro is default generated with the exception of

     QT       += sql
    

  • Lifetime Qt Champion

    I still don't get your idea with create_widget() at all - what's the reason for such a strange initialization? Apart from this it will crash on the second call. You really should consider using the Qt way on how to create and use widgets.

    You create QSqlTableModel before opening the db connection.



  • @Christian-Ehrlicher If you have advice on how to do that appropriately I'm happy to view it, I'm still learning... Thanks for the advice I'll get the model setup first. Also it doesn't crash when switching between widgets in the StackedWidget but maybe that'll lead to memory issues down the road.


  • Lifetime Qt Champion



  • @Christian-Ehrlicher Wow so not only are you not helpful but you're rude. All three of your comments have been unhelpful and generally unpleasant; you've wasted your own time not mine. I'll just close this out and carry on!

    Rather than say "Hey buddy, why not try this instead" followed by an explanation as to why your method works better, is more efficient etc.. all you want to do is ask me why I'm doing things strangely and link me to documentation that doesn't help because all you care about is how I did something and what I named it. Thanks buddy!


  • Lifetime Qt Champion

    Ok - you create an instance of a QWidget just to call a function which creates another widget for no reason. It's simply useless and not really what object oriented programming stands for. Qt has enough examples on how to create a simple QDialog or QWidget.


  • Lifetime Qt Champion

    Hi,

    One thing I can see is the missing opening of the database connection. You create one database, you assign it some path but I did not see any code opening the connection.


Log in to reply