Which database to use in combination with Qt for a simple desktop application on windows 7?



  • I want to create a simple desktop application on windows 7 for race management on a slotrace track. The program must have acces to a small database in which the data is stored about the drivers, cars and races.

    • Is there an embedded database which I can use or should I use an external database?
    • Which one is simple to use?
    • Can someone provide me with a start of my project?

    (I used to work with Oracle database, Forms en Developer, but using Oracle would be an overkill for this little project.)



  • SQLite is an option?

    http://www.sqlite.org/

    Pretty fast when just one application accesses the data at the same time. No setup, no installation. Pretty good SQL



  • Thanks, I got it working, althought I haven't found out how to add rows to a table using a form. . .


  • Lifetime Qt Champion

    Hi,

    Using Qt's SQL module you have QDataWidgetMapper which is designed for such usage.



  • @SGaist Thanks I will have a look
    (First I was working on how to open a second form from my mainwindow,
    The second form will be used for managing the contents of the table. Adding new rows with a unique key and updating existing rows.)
    My database model will be quite simple:
    Tables: drivers, cars, tournaments and heats
    a heat will link to 1 or 2 drivers and 1 or 2 cars.
    a tournament will have a link heats (minimum of two heats and a max of about 40)
    and also a link to 2 till 8 drivers.
    a heat does not have to be linked to a tournament. I will be possible to drive single heats/ practise laps
    I will need management forms on: drivers and cars first then I can create the basic race window which will show the driver and car info during a heat. Then I can add the tournament functionality.


  • Lifetime Qt Champion

    Then take the time to look a the QDataWidgetMapper related examples. That should give you a good starting point.



  • 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


  • Lifetime Qt Champion

    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


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    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.


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    Just use nullptr to tell it it has no parent.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.