1
votes

I am writing a small application that is working as follows:

1) I launch the application and I select a robot to which I will connect. See print screen below of the small app:

connA

2) That will lead me to another page where I can actually choose the robot to connect to as shown in the print screen below:

connB

3) Finally after selecting the robot the application brings me back to the initial screen that will show me an additional Button showing the chosen robot.

connC

The problem: I have is that after I choose the robot and I am back to the initial screen and I push the button the color of the button should turn into a (for example) green color and changing the text into (for example) Connecting...

The code I am using is the following for which I am only putting the related part:

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls.Styles 1.4

Page {
    property int dialogId: -1
    signal selectDialog()
    ColumnLayout {
           anchors.fill: parent
           spacing: 5

           Button {
               id: button1
               text: "Select Robot"
               onClicked: selectDialog()
               Layout.fillWidth: true
               font.pointSize: 20
           }

           Button {
           id: dialogA
           text: "FreddieMercury: Connect";
           visible: dialogId === 1
           Layout.fillWidth: true
           font.pointSize: 20
           function buttonClick()
           {
           console.log("Button "+ dialogA.text +" is clicked!")
           }
           Rectangle {
               id: button
               color: "red"
               width: 96; height: 24; anchors.centerIn: parent
               MouseArea {
                 id: region
                   anchors.fill: parent;
                   onClicked: console.log("clicked()")
                   onPressed: dialogA.color = "green"
                   onReleased: dialogA.color = "red"
               }
              Text {
                  id: st_text
                  anchors.centerIn: parent
                  text: "Connecting..."
                  font.bold: true
                  font.pointSize: 20
                  color: "green"
              }

             }
           }

           // Other Buttons
    }
}

What I tried so far

I went through this source and also this post which I followed. As you can see from the point 3) I am close to the good functioning but there is clearly something I am not doing right.

Also this was useful and in fact I used the MouseArea option exactly from that post. However I still don't see the whole color extended into the button.

Finally the text changed after the click event happened I included it in the Button as shown and thought that the property text: "Connecting..." was enough to overwrite the existing text but without success.

Please advise on what I am missing that is keeping me from a full working example.

1

1 Answers

2
votes

I think the base issue is that you're trying to use examples for QtQuick Controls 1 with QtQuick Controls 2. They're completely different animals and you cannot style the v2 controls using QtQuick.Controls.Styles.

For customizing Controls 2 styles, like Button, see here. I also find it useful to look at the source code for the included controls (they're in your Qt library install folder inside /qml/QtQuick/Controls2/ directory). Though personally I find needing to re-create a whole new Button (or whatever) just to change a color or font is a bit much, especially if I want it to work across all the included QtQuick Controls2 Styles.

An alternative is to "hack" the properties of the built-in Control styles. This certainly has some drawbacks like if you want to be able to reset the control style back to default bindings, you'd have to save the original bindings and re-create them to reset the style. OTOH it beats creating customized controls for each style. YMMV.

Anyway here's an example of what i think you're looking for. This is based on our previous exercise with the buttons. :) Specifically, I just modified the Page1.qml code and the other 2 files are exactly the same as before. In this page I added buttonClick() handler and the Button::onClicked calls to trigger it from each button (and the button texts of course :).

Page1.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.impl 2.12  // for IconLabel
import QtQuick.Layouts 1.12

Page {

    property int dialogId: -1;

    signal selectDialog()

    function buttonClick(button) 
    {
        button.text = qsTr("Connecting to %1...").arg(button.text);
        button.enabled = false;  // prevent repeat clicks
        // If Button has a background Rectangle object then we can set properties on it.
        // note: `instanceof` was added in Qt 5.10
        if (button.background && button.background instanceof Rectangle) {
            button.background.color = "red";  // override style color
            button.background.gradient = null;  // some styles use a gradient
            button.background.visible = true;   // some styles may hide it in some situations
        }
        // Similar with the label element, IconLabel is used by all included QML styles.
        if (button.contentItem && button.contentItem instanceof IconLabel) {
            button.contentItem.color = "blue";  // override style color
            button.contentItem.font.bold = true;
            button.contentItem.font.pointSize = 20;
        }
    }

    ColumnLayout {
        anchors.fill: parent
        spacing: 5

        Button {
            id: button1
            text: "Select"
            onClicked: selectDialog()
            Layout.fillWidth: true
        }

        // These buttons should appear only after the user selects the choices on `Page2`
        Button {
            id: dialogA
            text: "Freddie Mercury"
            visible: dialogId === 1
            Layout.fillWidth: true
            onClicked: buttonClick(this)
        }
        Button {
            id: dialogB
            text: "David Gilmour"
            visible: dialogId === 2
            Layout.fillWidth: true
            onClicked: buttonClick(this)
        }
        Button {
            id: dialogC
            text: "Mick Jagger"
            visible: dialogId === 3
            Layout.fillWidth: true
            onClicked: buttonClick(this)
        }
    }
}

If you had a customized Button (like in the Qt docs example) then you could still do basically the same thing in buttonClick() but probably w/out worrying about the if (button.background ...) stuff (since you'd be sure your button has valid background/contentItem Items).

A better implementation of a "default" (Style-specific) Button but with custom colors/text properties would involve a subclass which uses Binding and/or Connections QML elements to control the properties and be able to reset them back to the current QtQuick Style defaults.