Which database to use in combination with Qt for a simple desktop application on windows 7?
-
I did have a look at a couple of examples yet (e.g. books, relationaltablemodel, cachedtable and sqlwidgetmapper), but did not find an example which inserts new rows or update existing rows using userinput.
Do you know one?Regards,
Gerrit
-
QDataWidgetMapper::submit is the tool for that.
To add a new row, do it on the model and then set the mapper on that row.
-
QDataWidgetMapper::submit is the tool for that.
To add a new row, do it on the model and then set the mapper on that row.
@SGaist Thanks again. I got it working for one form on one table.
Now something else:
I want to have a program with one form per database table.So there is a main.cpp (just standard),
a mainwindow.cpp with buttons for opening the other windows
a driver_form.cpp for managing the table contents of a drivers table
a cars_form.cpp for managing the cars table
etc.I created a little initdb.h containing:
#ifndef INITDB_H
#define INITDB_H#include <QtSql>
QSqlError initDb()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("c:/sqlite/Slotrace.db");if (!db.open()) return db.lastError(); return QSqlError();
}
#endif // INITDB_H
If I include this initdb.h in driver_form.cpp and call initdb in the constructor there, I can edit the contents of my table.
I would like to include initdb.h in my mainwindow.cpp and call the initdb function there to open my database only once and have it available for driver_form and the car_form. But if I use the same code. The database will not be available in the driver_form. The form does not display data from the table and I can't commit any changes.
How can I include the initdb correctly. I don't see examples of database programs using more than one form. . .
Regards,
Gerrit -
Do you open the database before creating these two widgets ?
-
@SGaist
I'm not sure if I understand your question.
When are the widgets created normally?
(I'm relatively new to Qt.)I've put breakpoints in the constructor of SRMmainwindow and Form_drivers which is called by the mainwindow. For some reason the constructor of Form_driver is executed before the contructor of the main window.
If I look at the include statements, I see that the SRMmainwindow.h is always on top of the form_drivers.h
Is this normal?
Could it be the problem that the database is opened in the constructor of my main window, after the execution of the constructor of my form_drivers?
How can I influence the sequence in which the constructors are called?Regards Seal,
Another question: Is there an easy way of mapping a database field for Gender values: (M)ale of (F)emale to a couple of radio buttons in a form?
-
Usually they are created at the start of the application. Take a look at Qt's documentation in the tutorial section as well as examples and demos.
Not knowing your code, I can't tell why it's happening like that.
Yes you can. You can write a custom GenderChooserWidget and use QDataWidgetMapper to use it against a filed of your database table.
-
I've placed my code in my dropbox:
https://www.dropbox.com/sh/h2w70cvjchx3xib/AAD9x7Q8BVIsi2KHTqNz31XWa?dl=0
I did find out why the constructors are called in the specific order (1: form_drivers, 2: form_cars, 3: SRMmainwindow) i think it has to do with the declaration of the driverwindow and carwindow in smrmainwindow.h as private functions while the mainwindow is declared in the main() in line 10.
Now my problem:
If I open the database in form_drivers, only that form shows data. The same kind of thing happens if I open the database in form_cars. If I open the database in SRM_mainwindow, both forms don't show any data. (because the constructor of the form is called befor the opening of the database?)How can I open the database just once, so that both forms will show the data in the tables? (The form_cars is not ready yet, buttons are not working on this form. But it does show the first record in my database.)
Thanks again for your help,
Regards Seal.
-
Just do it before creating any widget then. You can do it in the main function or have a class dedicated to that that you instantiate before any widget.
-
Just do it before creating any widget then. You can do it in the main function or have a class dedicated to that that you instantiate before any widget.
@SGaist
I've inserted the following line in my main.cpp just before declaring my mainwindow.
QSqlError err = initDb();It does open my database correctly and the forms for the drivers and the cars do show the data.
But what if something goes wrong in opening the database.
The code I used in form_drivers was:
if (!QSqlDatabase::drivers().contains("QSQLITE"))
QMessageBox::critical(this, "Unable to load database", "This program needs the SQLITE driver");// initialize the database QSqlError err = initDb(); if (err.type() != QSqlError::NoError) { showError(err); return; }
But I can't call the QmessageBox in main(), because I can't use the this pointer to a parent Widget. main() is not a widget.
What messagebox could I use instead in main(), in case there is an error opening the database?
-
Just use
nullptr
to tell it it has no parent.