Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Access QML elements from C++ classes

Access QML elements from C++ classes

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 4 Posters 2.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • KillerSmathK Offline
    KillerSmathK Offline
    KillerSmath
    wrote on last edited by KillerSmath
    #2

    @DavidM29
    Can you show me an example of how are you trying to do that ?

    Because depending of your implemention, you can expose a c++ object to qml and acess the proprieties of qml components using this object.

    @Computer Science Student - Brazil
    Web Developer and Researcher
    “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

    1 Reply Last reply
    0
    • D Offline
      D Offline
      DavidM29
      wrote on last edited by
      #3

      For example I have a two state option with a label it look like that :

      0_1529410500784_0504c349-7dc1-455c-b3bf-b7a022478e77-image.png

      This is a Component to me wich I called OptionSwitch. My OptionSwitch has 2 properties :

      • The label of the option wich is a String
      • The switch wich is an alias in order to access it states

      From my option page I have implement a Component a FileIO wich is my C++ class to read my text file.
      In my main.cpp I added this line to give access to my FileIO as a component in QML :

          qmlRegisterType<FileIO, 1>("FileIO", 1, 0, "FileIO");
      

      In my QML I just have to set the location of my file and then I access to the value of by calling FileIO functions.

      This is just for one option but I want to handle it in a more generic way. Here is an example of what I want to do :

      Example of properties file :
      "element.property01=value01
      element.property02=value02
      element2.property01=value03
      "

      The QML option page would contains many OptionSwitch for example :

      OptionSwitch{
            id: element
            property01: value01
            property02: value02
      }
      OptionSwitch {
            id: element2
            property01=value03
      }
      

      When I load my QML element I read the value from my file wich works at the moment.
      Then to save I would like to use a button that call my C++ write function.

      When I read my value from my file I use a map of strings where the Key is the name of the property and the value is the value of the property.

      I'm not sure to be very clear on everything, so if I'm not or you want more information please ask me.

      1 Reply Last reply
      0
      • KillerSmathK Offline
        KillerSmathK Offline
        KillerSmath
        wrote on last edited by
        #4

        @DavidM29

        Okay, you could write and read information from .json file but after few time googling, i noticed that QT have a class to work with set and get of properties of application.

        QSettings C++ Documentation

        You could to use the QSettings Class to set and get values of .ini file in your application. But QSettings is a c++ class, so you need to create a custom class and reimplement the methods to be callable from QML.

          1. Create a setting class derived of QSettings
          1. Reimplement the basic methods: setValue, value and construtors
          1. Create a object of custom settings and expose to context of qml

        Below is an example of how you can implement:

        customsettings.h file

        #ifndef CUSTOMSETTINGS_H
        #define CUSTOMSETTINGS_H
        
        #include <QObject>
        #include <QSettings>
        #include <QVariant>
        
        class CustomSettings : public QSettings
        {
            Q_OBJECT
        public:
            CustomSettings(QObject *parent = nullptr);
            CustomSettings(const QString &fileName, QSettings::Format format, QObject *parent = nullptr);
            Q_INVOKABLE void setValue(const QString &key, const QVariant &value);
            Q_INVOKABLE QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
        
            Q_INVOKABLE void sync();
        };
        
        #endif // CUSTOMSETTINGS_H
        
        

        customsettings.cpp file

        #include "customsettings.h"
        
        CustomSettings::CustomSettings(QObject *parent) : QSettings(parent)
        {
        
        }
        
        CustomSettings::CustomSettings(const QString &fileName, QSettings::Format format, QObject *parent) : QSettings(fileName, format, parent)
        {
        
        }
        
        void CustomSettings::setValue(const QString &key, const QVariant &value)
        {
            QSettings::setValue(key, value);
        }
        
        QVariant CustomSettings::value(const QString &key, const QVariant &defaultValue) const
        {
            return QSettings::value(key, defaultValue);
        }
        
        void CustomSettings::sync()
        {
            QSettings::sync();
        }
        

        main.cpp file

        #include <QApplication>
        #include <QQmlApplicationEngine>
        #include <QQmlContext>
        #include "customsettings.h"
        
        int main(int argc, char *argv[]) {
            QApplication app(argc, argv);
        
            QCoreApplication::setOrganizationName("YourOrganization");
            QCoreApplication::setOrganizationDomain("yourorganization.com");
            QCoreApplication::setApplicationName("Your Application Name");
        
            CustomSettings settings("mysettings.ini", QSettings::IniFormat);
        
            QQmlApplicationEngine engine;
        
            engine.rootContext()->setContextProperty("settings", &settings);
        
            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            if (engine.rootObjects().isEmpty())
                return -1;
        
            return app.exec();
        }
        

        main.qml file

        import QtQuick 2.4
        import QtQuick.Window 2.1
        import QtQuick.Layouts 1.2
        import QtQuick.Controls 2.0
        
        Window {
            id: window
            width: 800
            height: 600
            minimumHeight: 350
            minimumWidth: 500
            visible: true
            color: "#222222"
        
            function saveSettings(){
                settings.setValue("nametextfield/text", nameTextField.text);
                settings.setValue("switch01/checked", switch01.checked);
                settings.setValue("switch02/checked", switch01.checked);
        
                settings.sync(); // necessary to force the saving as permanenty data
            }
        
            function loadSettings(){
                nameTextField.text = settings.value("nametextfield/text", nameTextField.text);
                switch01.checked = settings.value("switch01/checked", switch01.checked);
                switch02.checked = settings.value("switch02/checked", switch02.checked);
            }
        
            ColumnLayout{
                width: 450
                height: 250
                anchors.centerIn: parent
        
                RowLayout{
                    Item{ Layout.fillWidth: true }
        
                    Text {
                        text: "Name: "
                        color: "white"
                    }
                    TextField{
                        id: nameTextField
                        text: "Insert Your Name"
                    }
        
                    Item{ Layout.fillWidth: true }
                }
        
                Item{  Layout.fillHeight: true }
        
                RowLayout{
                    Item{ Layout.fillWidth: true }
        
                    Text {
                        text: "Switch 01: "
                        color: "white"
                    }
                    Switch {
                        id: switch01
                        checked: false
                    }
        
                    Item{ Layout.fillWidth: true }
                }
        
                RowLayout{
                    Item{ Layout.fillWidth: true }
        
                    Text {
                        text: "Switch 02: "
                        color: "white"
                    }
                    Switch {
                        id: switch02
                        checked: false
                    }
        
                    Item{ Layout.fillWidth: true }
                }
        
                Item{ Layout.fillHeight: true }
        
                RowLayout{
                    Item{ Layout.fillWidth: true  }
        
                    Button{
                        id: saveButton
                        text : "Save Data"
                        onClicked: window.saveSettings(); // call Save Function
        
                    }
        
                    Button{
                        id: loadButton
                        text: "Load Data"
        
                        onClicked: window.loadSettings(); // call Load Function
                    }
        
                    Button{
                        id: reset
                        text: "Reset Data"
                        onClicked: {
                            switch01.checked = false
                            switch02.checked = false
                            nameTextField.text = "Insert Your Name"
                        }
                    }
        
                    Item{ Layout.fillWidth: true }
                }
            }
        }
        

        @Computer Science Student - Brazil
        Web Developer and Researcher
        “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

        1 Reply Last reply
        2
        • GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote on last edited by
          #5

          or http://doc.qt.io/qt-5/qml-qt-labs-settings-settings.html

          1 Reply Last reply
          0
          • D Offline
            D Offline
            DavidM29
            wrote on last edited by DavidM29
            #6

            @KillerSmath
            Thank you for your answer it is a good solution. Almost everything works fine !
            I have only one issue. When I load my settings I do it like that in my QML :

                
                Component.onCompleted: {
                    loadSettings()
                }
            

            But when I do that the value it reads is good but it does not apply it to my component. Here is my loadSettings method :

               function loadSettings(){
                    console.log(settings.value("Gen/night", night.checked))
                    night.checked = settings.value("Gen/night", night.checked)
                    console.log(night.checked)
                }
            

            When I launch it the console print : "qml: false" at first so the read value is false (wich is the expected value) then it is supposed to change the state of my component. But it keep its value at true. The console show "qml:true" on the second console.log

            I don't really understand why it behave like that, do you have any clues ?

            1 Reply Last reply
            0
            • KillerSmathK Offline
              KillerSmathK Offline
              KillerSmath
              wrote on last edited by KillerSmath
              #7

              @DavidM29
              This is a problem of convertion between the set and get of data.

              When you use settings.setValue("Name", bool), this boolean is saved as String in .ini file but when you recover this value and tries to convert to bool again, occours a conversion error.

              When you use settings.setValue("Name", bool), this boolean is saved as String in .ini file but when you try to recover, this value is returned as Qvariant of string and because it, occours a conversion error.

              setValue()   ->      value()
              bool         ->      "bool"
              false        ->      "false"
              132442       ->      "132442"
              "121415"     ->      "121415"
              

              Javascript language implements some of ECMA-262 specifications

              http://www.ecma-international.org/ecma-262/5.1/#sec-9.2

              Notice that:

              The result is false if the argument is the empty String (its length is zero); otherwise the result is true.

              Settings QML Type already implement a feature to solve this problem but with limitation.

              Settings QML Type Notes:

              The current implementation is based on QSettings. This imposes certain limitations, such as missing change notifications. Writing a setting value using one instance of Settings does not update the value in another Settings instance, even if they are referring to the same setting in the same category.

              So, if this limitation is a problem for your application, you can implement a feature to fix this problem in c++ QSettings.

              QVariant CustomSettings::value(const QString &key, const QVariant &defaultValue)
              {
                  QVariant value = QSettings::value(key, defaultValue);
                  
                  if (QString(value.typeName()) == "QString" &&  (value.toString() == "false" || value.toString() == "true"))
                      return QVariant(value.toBool());
                  
                  return value;
              }
              

              Extra: if you need to save settings and load in all instances of your application, i recommend you to implement another method of storage as .json that can difference true boolean of "true" string

              References:
              QML engine not implicitly converting a bool-string QVarient to bool property - StackOverFlow

              @Computer Science Student - Brazil
              Web Developer and Researcher
              “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

              1 Reply Last reply
              2
              • D Offline
                D Offline
                DavidM29
                wrote on last edited by
                #8

                If I wan't to implement another method of storage I will not be able to use QSettings anymore as long as it does not support .json format. Am I wrong ?

                1 Reply Last reply
                0
                • KillerSmathK Offline
                  KillerSmathK Offline
                  KillerSmath
                  wrote on last edited by
                  #9

                  @DavidM29 the problem is not the file type but the Json Sintaxe

                  @Computer Science Student - Brazil
                  Web Developer and Researcher
                  “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

                  edipE 1 Reply Last reply
                  1
                  • D Offline
                    D Offline
                    DavidM29
                    wrote on last edited by
                    #10

                    Yes I understand because in .json the string value are encapsulated in " " but to do that I will have to make my own json reader and writer I will not be able to use the QSettings.

                    1 Reply Last reply
                    0
                    • KillerSmathK KillerSmath

                      @DavidM29 the problem is not the file type but the Json Sintaxe

                      edipE Offline
                      edipE Offline
                      edip
                      wrote on last edited by
                      #11

                      @KillerSmath Thank you so much! Very useful answer.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved