Need Help with My First Separate Class



  • Newbie here. So, I created a GUI app with a settings tab, and learned how to make it read and write settings using the proper technique with QSettings. The way I was doing it, however, was inside my mainwindow.cpp file with this:

    void MainWindow::readSettings()
    {
        QSettings settings;
        settings.setPath(settings.NativeFormat,settings.UserScope,"");
        settings.beginGroup("General");
        ui->checkBox1->setChecked(settings.value("checkBox1",0).toBool());
        settings.endGroup();
    }
    
    void MainWindow::writeSettings()
    {
        QSettings settings;
        settings.setPath(settings.NativeFormat,settings.UserScope,"");
        settings.beginGroup("General");
        settings.setValue("checkBox1",ui->checkBox1->isChecked());
        settings.endGroup();
    }
    

    Now I want to create a settings class called ctSettings (ctsettings.cpp/ctsettings.h) and have the load of the main window call ctSettings::readSettings(), and have the click of an update button call ctSettings::writeSettings(). To start, I used File > New File or Project > C++ > C++ Class. I didn't make it inherit any other class.

    I'm a bit stuck for a few reasons:

    1. Do I put my class methods inside ctsettings.h after the line that reads "private:" ?

    2. How do I pass the ui object to the ctSettings class?

    3. So that I don't get errors, what includes will I need at the top of which file to make this work?

    4. Does the slot code in mainwindow.cpp call my new class statically, or does it need to create an actual object? For instance, calling ctSettings::readSettings() versus creating an object settings and then doing settings->readSettings().



  • I figured it out.

    ctsettings.h

    #ifndef CTSETTINGS_H
    #define CTSETTINGS_H
    
    #include <QObject>
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "QSettings"
    
    class ctSettings : public QObject
    {
        Q_OBJECT
    public:
        explicit ctSettings(QObject *parent = 0);
        static void readSettings(Ui::MainWindow *ui);
        static void writeSettings(Ui::MainWindow *ui);
    
    signals:
    
    public slots:
    };
    
    #endif // CTSETTINGS_H
    

    ctsettings.cpp

    #include "ctsettings.h"
    
    ctSettings::ctSettings(QObject *parent) : QObject(parent)
    {
    }
    
    void ctSettings::readSettings(Ui::MainWindow *ui)
    {
        QSettings settings;
        settings.setPath(settings.NativeFormat,settings.UserScope,"");
        settings.beginGroup("General");
        ui->checkBox1->setChecked(settings.value("checkBox1",0).toBool());
        settings.endGroup();
    }
    
    void ctSettings::writeSettings(Ui::MainWindow *ui)
    {
        QSettings settings;
        settings.setPath(settings.NativeFormat,settings.UserScope,"");
        settings.beginGroup("General");
        settings.setValue("checkBox1",ui->checkBox1->isChecked());
        settings.endGroup();
    }
    

    Then, I included #include "ctsettings.h" in my mainwindow.h file, and then was able to call my class methods statically like so in any class method of mainwindow.cpp:

    ctSettings::readSettings(ui);
    ctSettings::writeSettings(ui);



  • Lets forget for a moment about ctSettings for simplicity.

    A push button emits the signal clicked(). (If you need reaction on different button, you might need another signal)
    This means that to react on the click you need to connect slot of QObject derived class instance to this signal.
    Your MainWindow is such QObject derived class. So you can use it for such purpose.
    I assume it also has access to the button pointer (for example ui->pushButton)
    So now you need a slot. If writeSettings is a regular function just convert it to a slot.

    Now we need to connect signal to slot.
    In MainWindow constructor right after ui element are initialized (setuUi()?) add :
    bool ok = connect(pushButton, SIGNAL(clicked()), this, SIGNAL(writeSettings ())); Q_ASSERT( ok);

    Now writeSettings will be called when button is clicked and settings will be saved.

    About ctSettings. There is no need to use custom class at least for this purpose,

    but you can place all functionality in your custom class and use it if you prefer

    void MainWindow::writeSettings()
    {
    ctSettings s;
    s.writeSettings( ... );
    }

    Now you will need to pass parameters to ctSettings ::writeSettings( ... )
    This better not be pointer to ui, cause you will introduce dependency ctSettings on the ui class which will be changed dynamically during development. Better to limit such dependency to MainWIndow.
    ( This is why you did not want to have ctSettings class )
    In this case you would pass pass individual control like:

    ctSettings s;
    s.writeSettings( const QCheckBox* checkBox1 );

    For all other questions I would recommend C++ book.
    I can't explain what "private" is better than there.
    Just understand that as soon in the code you see variable of specific type (class) mentioned,
    it means compiler needs to know about this class already. Normally this means you have to include proper header file. (There is only one exception when incomplete class declaration is allowed, but book again will explain this much better than me).

    Regards,
    Alex


Log in to reply
 

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