Qt World Summit: Register Today!

Change property more than one time in an qml depend on input variables

  • hi guys,

    i have the following problem and maybe you can help me

    i got from C++ 4 bits (part of a bitmask) now i have to convert that bits to an integer value (0-15) to make future operations with this number.
    my idea was something like that

    if (boError === 0) return iCodeValue = 0;
    if (boCodePin1 === TRUE) return iCodeValue += 1;
    if (boCodePin2 === TRUE) return iCodeValue += 2;
    if (boCodePin3 === TRUE) return iCodeValue += 4;
    if (boCodePin4 === TRUE) return iCodeValue += 8;

    i know that this can't work. but i have no idea to solve it in an "nice" way.
    i found a way to solve it with "else if" but i don't like the coding because it will be hard to read.
    to change the c++ code to get an int value is not a option

    i would be grateful if someone has any ideas

  • Qt Champions 2017

    Try some thing like this.

    @ QString str = "1101";
    bool ok;
    int hex = str.toInt(&ok, 2); // hex == 255, ok == true
    qDebug() << hex;@

  • sorry no option for me. I want do the transformation just in qml.

  • Why? Would it not be easier to expose a simple object to QML from C++ that provides the API to do this properly and in a declarative way?

    Anyway, adding bitfields in itself is not wrong. Your code is. You need to add (or, really) each and every bit to the value if set, and then return the result.

  • the informations come not from the programm itself, it comes over an interface from another programm and this interface is defined (can't add or change it). the api just give the information forward to the qml and in 95% of the cases this is fine.

    my first solution is like you write andre. I already did it at other situations but the code gets hard to read. so i thought there is another easier way.

  • Moderators


    Are you looking for conversion of binary to decimal in javascript ? QML's can execute javascript functions.

  • no i have bit values and this i want transform to a number. not the matter if the number is hex, bin, dec.
    i do it now in that way i think it will work
    Text {
    id: elevatorName
    text: {
    if(boCodePin3 == FALSE && boCodePin4 == FALSE) return "MEC1";
    else if (boCodePin3 == TRUE && boCodePin4 == FALSE) return "MEC2";
    else if (boCodePin3 == FALSE && boCodePin4 == TRUE) return "MEC3";
    else if (boCodePin3 == TRUE && boCodePin4 == TRUE) return "MEC4";

  • Huh? What you are doing now is not converting to a number, but to a string.

    It seems you have a collection of booleans. I'd just make a simple element in C++ that you then expose to QML that has boolean properties for every bit position you want to support (8,16, perhaps more?) and an integer property for the numeric interpretation. You can then just bind your boolean values to this object hand use binding to the numeric value too. Or use it the other way around to set a number and get the induvidual bits directly. Edit: you could just make that component completely in QML too, if you want.

    What you now write is feasible (but not recommended) if you have just two, maybe three bits. After that, it gets rather long and easy to make mistakes in quickly. Doing this for 8 bits will already require 256 of these with 8 checks each. Good luck with that...

  • Moderators

    Still not able to understand. Can you give an example of what input you get and what you want it to be converted into ?

  • Andre:
    i know this solutionwill just work in that simple case,and i don't want it too. that was the reason to post the problem. :-)
    the solution will work because i just have 4 bits and so i can handle it.

    your idea i don't understand fully. can you please detail it more or give a example, link etc?

    a controller collect some differnt signals for controlling and visualization this are send over and interface to a control programm. some of this information are for the controlling, the rest is for visualization.
    the problem is i don't want to change the programm code, the code should be the same becuase in other cases i need the bits.

    this 4 bits are digital inputs and used for visualization.
    this 4 bits are the coding of 16 sockets. and i will make a view where the user can see wich socket is used.

  • Moderators

    So what numerical input you get when for eg socket no. 8 is used ? Do you get 1000 (considering each digit as a separate bit ofcourse)as the input ?

  • for socket 8 i get

    boBit0 = FALSE
    boBit1 = FALSE
    boBit2 = FALSE
    boBit4 = TRUE

  • I'd do something like this:

    Make new QML file BitField.qml, and put something like this in (untested):

    import QtQuick 2.2

    QtObject {
    id: BitField
    property bool bit0
    property bool bit1
    property bool bit2
    property bool bit3

    property int value;

    onBit0Changed: updateValue()
    onBit1Changed: updateValue()
    onBit2Changed: updateValue()
    onBit3Changed: updateValue()

    function updateValue() {
    int newVal = 0;
    newVal |= bit0 ? 1 : 0;
    newVal |= bit1 ? 2 : 0;
    newVal |= bit2 ? 4 : 0;
    newVal |= bit3 ? 8 : 0;
    value = newVal;

    onValueChanged: {
    bit0 = value && 1;
    bit1 = value && 2;
    bit2 = value && 4;
    bit3 = value && 8;

    You can then use the BitField element in your QML, and just bind to the properties however you like.

    Again: the code above is an idea only, I did not test it but just typed it into the forum editor directly.

  • this is my idea to solve it. (tested)

    function iTransformtoInt(bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7) {
    var calc = 0;
    if (bit0 === true) { calc +=1};
    if (bit1 === true) { calc +=2};
    if (bit2 === true) { calc +=4};
    if (bit3 === true) { calc +=8};
    if (bit4 === true) { calc +=16};
    if (bit5 === true) { calc +=32};
    if (bit6 === true) { calc +=64};
    if (bit7 === true) { calc +=128};
    return calc;
    Text {
    id: elevatorName
    text: iTransformtoInt(boCodePin1,boCodePin2, boCodePin3, boCodePin4,0,0,0,0)


  • thanks you both for give me some new ideas.

  • Moderators

    Or may be this one
    function convert(pinsArray) {
    var all = ""
    for(var i=0;i<pinsArray.length;i++)
    all += (pinsArray[i]*1).toString()

    console.log(all,parseInt(all, 2))


    Component.onCompleted: {
    var boCodePin1 = false
    var boCodePin2 = false
    var boCodePin3 = false
    var boCodePin4 = true

    var arr = [boCodePin4,boCodePin3,boCodePin2,boCodePin1];


    seems the earlier post was deleted.

Log in to reply