Yasser Sobhy
Yasser Sobhy

Reputation: 155

What is the best way to set/read UI values in Qt Quick

I am writing a new C++ application and I decided to use Qt Quick instead of traditional Qt widgets, I know QML well but I am facing some trouble regarding the best way to read and set UI controls' values

in my application, it's called DOO, I have two QML files for each display, the first defines the UI elements and the second is a helper class to read/set UI values and it has a save() function to save to a database

for example lets take an object that is called Son and see how it is defined

in SonDisplay.qml

import QtQuick 2.0
import QtQuick.Layouts 1.1

import DOO.Entities.Son 1.0
import DOOTypes 1.0

import "../UIElements"
import "../UIElements/DOOTheme.js" as DOOTheme
import "../DOO"

Display {

    id:sonDisplay

    contentHeight: 350
    contentWidth: 800

    // this is a QObject derived class, that I use as an entity to a table in a MySQL database
    // I use it here to set/read UI from/to it
    property Son son : Son{}
    property int disMode : DOO.Show
    property bool inEditMode : false
    ....

in the helper file SonHelper.qml

    import QtQuick 2.0
import DOO.Commands.Son 1.0
import DOOTypes 1.0

QtObject {

    // read a Son object values into local son
    function readValues(pSon)
    {
        son.sonID = pSon.sonID
        son.name = pSon.name
        son.image = pSon.image
        son.age = pSon.age
        son.entryDate = pSon.entryDate
        son.commingFrom = pSon.commingFrom
        son.disabilityKind.kind = pSon.disabilityKind.kind
        son.caseDescription = pSon.caseDescription
        son.more = pSon.more
    }

    // copy local son values into a Son object
    function copyValues(pSon)
    {
        pSon.sonID = son.sonID
        pSon.name = son.name
        pSon.image = son.image
        pSon.age = son.age
        pSon.entryDate = son.entryDate
        pSon.commingFrom = son.commingFrom
        pSon.disabilityKind.kind = son.disabilityKind.kind
        pSon.caseDescription = son.caseDescription
        pSon.more = son.more

    }

    // read ui values into local son
    function readUIValues()
    {
        son.name = sonName.text
        son.image = sonImage.picture
        son.age = sonAge.text
        son.entryDate = Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy")
        son.commingFrom = sonCommingFrom.text
        son.disabilityKind.kind = sonDisabilityKind.currentIndex
        son.caseDescription = sonCaseDescription.text
        son.more = sonMore.text

    }

    function validateUIValues()
    {
        if (Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy") == "Invalid Date") return false
        //if(!sonSonID.acceptableInput) return false
        //if(!sonAge.acceptableInput) return false
        //if(!sonDisabilityKind.acceptableInput) return false

        return true
    }

    // save or update a son into database
    function save()
    {
        var v_son =  SonFactory.createObject()

        if (!validateUIValues())
        {
            dooNotifier.showMessage("Error","You Have some invalid input")
            return
        }

        readUIValues()
        copyValues(v_son) // copy local son values into v_son

        if(disMode === DOO.CreateNew)
        {
            if(SonCommands.insert(v_son))
            {
                dooNotifier.showMessage("Success","Son added successfully ")
                SonResultsModel.update()
                sonDisplay.hide()
            }
            else
            {
                dooNotifier.showMessage("Failed","Error adding son")
                DOOLogger.log(SonCommands.lasrErrorText())
            }
        }
        else
        {
            if(SonCommands.update(v_son))
            {
                dooNotifier.showMessage("Success","Son updated successfully ")
                SonResultsModel.update()
                sonDisplay.hide()
            }
            else
            {
                dooNotifier.showMessage("Failed","Error updating son")
                DOOLogger.log(SonCommands.lasrErrorText())
            }
        }

        v_son.destroy()
    }

}

As you can see, I use a function to read a Son object values into local son object, a second one to copy local son object's values into a Son object, and a third function to read UI values into local son object

Now I am wondering if is there any better way to handle this scenario instead of readValues(pSon), copyValues(pSon), and readUIValues() functions

or this is a good pattern to do that

Edit

I think I could use a QAbstractItemModel derived class to read/ save to databaase and pass UI values to it as a JavaScript object or read UI values into local son object and pass it to a C++ save() function that will validate and save data like this:

    var uivalues = {
    name : sonName.text ,
    image : sonImage.picture ,
    age : sonAge.text ,
    entryDate : Date.fromLocaleDateString(Qt.locale(), sonEntryDate.text, "dd-MM-yyyy") ,
    commingFrom : sonCommingFrom.text ,
    disabilityKind : sonDisabilityKind.currentIndex ,
    caseDescription : sonCaseDescription.text ,
    more : sonMore.text ,
    }

    SonResultsModel.save(uivalues)

Upvotes: 1

Views: 629

Answers (1)

DragonLich
DragonLich

Reputation: 86

First:

I think you should move more logic to the C++ code. For the best performance it's better to use minimum js code as possible.

Create your son as C++ class with properties then bind this properties to UI if it's possible.

Second:

Last method in helper class save() could be in the special class. That can be usefull when you use more classes like son because the work with that classes will be simillar.

EDIT:

I think it's better now. See comments below.

Upvotes: 1

Related Questions