dimanche 28 août 2022

How to dynamically save data into a database file .db and show them into a QTableView

I have a small GUI where I have a QTableView and a QPuchButton. The function of the QPushButton is mainly dinamyc, which means that the operations that needs to happen when clicking the button would be following:

void writeTemporaryFilesOnDatabase::on_addMsgBtn_clicked() {}

  1. Create a database file dynamically (.db)
  2. Create a temporary Database connection
  3. Create some dinamically tabular data using the subclassed QAbstractTableModel
  4. Store the data into the database file created at 1)
  5. Read the file.db with the data and show it into the QTableView on the ui

The problem is that the database does not open and consequenlty, no files are temporarliy stored in the NewFile.db and I cannot read/show the data in the QTableView

void writeTemporaryFilesOnDatabase::on_addMsgBtn_clicked()
{

    // 1 - Create a database file dinamically and store the file.db in the following document folder as an example

    QString path("/home/to/Documents/");
    QDir dir; // Initialize to the desired dir if 'path' is relative

    // We create the directory if needed
    if (!dir.exists(path))
        dir.mkpath(path); // You can check the success if needed

    QFile file(path + "NewFile.db");
    file.open(QIODevice::WriteOnly); // Or QIODevice::ReadWrite

    // 2 - Create a table in runtime mode and fill out with temporary data
    QList<QString> contactNames;
    QList<QString> contactPhoneNums;

    contactNames.append("Thomas");
    contactNames.append("Richard");
    contactNames.append("Harrison");
    contactPhoneNums.append("123");
    contactPhoneNums.append("222");
    contactPhoneNums.append("333");

    // 3 - Create a database in runtime mode and fill out with temporary data just created

    QSqlDatabase *database = new QSqlDatabase();
    database->QSqlDatabase::addDatabase("QSQLITE","/home/to/Documents/NewFile.db");
    database->open();
    if (database->open()) {
        qDebug() << __LINE__ << QString("Open Db!");
    } else {
        qDebug() << __LINE__ << QString("Db not opening!");
    }

    // Create Phone Book with subclassed QAbstractTableModel:
    TestModel *PhoneBookModel = new TestModel(this);
    // Populate model with data:
    PhoneBookModel->populateData(contactNames,contactPhoneNums);

    // Connect model to table view:
    QSqlTableModel  *tableModel = nullptr;
    QTableView *tView = new QTableView;
    tView->setModel(PhoneBookModel);

    // Make table header visible and display table:
    tView->horizontalHeader()->setVisible(true);  // <-- This run correctly and appears as soon as I launch the application (I did it for debugging reasons and the table is correctly created)
    tView->show();

    if (database->open()) {
        qDebug() << __LINE__ << QString("Open Db or not?????");
        QSqlQuery query;
        query.exec("DROP TABLE items");
        query.exec(
                    "CREATE TABLE items ("
                        "Name TEXT NOT NULL,"
                        "Phone INTEGER NOT NULL ''"
                    ")"
                    );

        query.prepare("INSERT INTO items (Name, Phone) VALUES (?,?)");
        query.addBindValue(newItem->name());
        query.addBindValue(newItem->phone().toInt());

        tableModel = new QSqlTableModel(this, *database);
        tableModel->setTable("items");
        tableModel->setEditStrategy(QSqlTableModel::OnFieldChange);
        tableModel->select();
        tView->setModel(PhoneBookModel);

       // Read the data created in the `TestModel *PhoneBookModel = new TestModel(this);`

        if( file.open( QIODevice::WriteOnly ) )
        {
            QTextStream ts( &file );
            QStringList strList;

            for (int i=0; i<PhoneBookModel->rowCount(); i++)
            {
                strList.clear();

                for (int j=0; j<PhoneBookModel->columnCount(); j++)
                    strList << PhoneBookModel->data(PhoneBookModel->index(i,j)).toString();

                ts << strList.join(" ") + "\n";
            }
            ts << &strList;
            file.close();
        }
    } else {
        qDebug() << __FUNCTION__ << QString("Error!");
        return;
    }


    // 4 - LOOP THROUGH THE HEADERS OF THAT FILE AND SHOW THE TABLE
    for(int i=0; i< ui->tableWidget->rowCount(); i++)
        {
            QString viewFieldName = ui->tableView->item(i, 0)->text();
            mModel->setHeaderData(i, Qt::Horizontal, viewFieldName);
            mModel->submitAll();
        }
}

Specifically, the Qt Objects QAbstractTableModel (sub-classed in this example) and QTableView are used mostly for practice on how to use the QAbstractTableModel but I am not sure what I am doing wrong here. Any help would be very appreciated.

In case you are wondering how I subclassed the QAbstractTableModel see below:

class TestModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    TestModel(QObject *parent = 0);

    void populateData(const QList<QString> &contactName,const QList<QString> &contactPhone);

    int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
    int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;

    bool addItem(itemExample *newItem);

private:
    QList<QString> tm_contact_name;
    QList<QString> tm_contact_phone;
    QString mError;
};

Thanks for any help! Sources I consulted to help me but without solving the problems are: this, this one and also this one.

Aucun commentaire:

Enregistrer un commentaire