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. Multiple device application in QML
Forum Updated to NodeBB v4.3 + New Features

Multiple device application in QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
qt quickqml
7 Posts 3 Posters 646 Views 1 Watching
  • 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.
  • R Offline
    R Offline
    Ryna
    wrote on last edited by Ryna
    #1

    Hi,
    I am making an application which should work for Android tablet, Apple phone, Linux desktop and windows. I am using QML for UI. Whatever I try with anchors and layouts, UI doesn’t look the same on all devices. I have come to the conclusion that I should have shared qml like customised button and rest of the qmls should be specific to each OS.
    Looking for suggestions here. Thank you

    jsulmJ 1 Reply Last reply
    0
    • R Ryna

      Hi,
      I am making an application which should work for Android tablet, Apple phone, Linux desktop and windows. I am using QML for UI. Whatever I try with anchors and layouts, UI doesn’t look the same on all devices. I have come to the conclusion that I should have shared qml like customised button and rest of the qmls should be specific to each OS.
      Looking for suggestions here. Thank you

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Ryna Not sure what the problem is. All these platforms have their own UIs which do not look the same. Can you explain what exactly is not the way you want it to be?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      R 1 Reply Last reply
      0
      • jsulmJ jsulm

        @Ryna Not sure what the problem is. All these platforms have their own UIs which do not look the same. Can you explain what exactly is not the way you want it to be?

        R Offline
        R Offline
        Ryna
        wrote on last edited by
        #3

        @jsulm I have created an application which has graph on the home screen and drawer sliding in from the left. Drawer has it's own buttons and tabs.
        I had developed it for android tablet and it was looking fine. I am extending the scope and want to deliver the same app for Apple phones and Linux desktops. I understand that I can not give constant values in QML and have to prefer using layout and anchors now. Inspite of using all these techniques, app application looks different on these platforms like buttons will overlap in the drawer or whole layout goes out of the drawer.
        I do not prefer to have dfferent QMLs for Android, iOS and so but I can not find any other solution. Appreciate any ideas. Thank you

        jsulmJ 1 Reply Last reply
        0
        • R Ryna

          @jsulm I have created an application which has graph on the home screen and drawer sliding in from the left. Drawer has it's own buttons and tabs.
          I had developed it for android tablet and it was looking fine. I am extending the scope and want to deliver the same app for Apple phones and Linux desktops. I understand that I can not give constant values in QML and have to prefer using layout and anchors now. Inspite of using all these techniques, app application looks different on these platforms like buttons will overlap in the drawer or whole layout goes out of the drawer.
          I do not prefer to have dfferent QMLs for Android, iOS and so but I can not find any other solution. Appreciate any ideas. Thank you

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Ryna said in Multiple device application in QML:

          buttons will overlap in the drawer or whole layout goes out of the drawer.

          Sounds like you're doing something wrong with layouts.
          But without code who knows.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          R 1 Reply Last reply
          0
          • jsulmJ jsulm

            @Ryna said in Multiple device application in QML:

            buttons will overlap in the drawer or whole layout goes out of the drawer.

            Sounds like you're doing something wrong with layouts.
            But without code who knows.

            R Offline
            R Offline
            Ryna
            wrote on last edited by
            #5

            @jsulm Below is the reference code. I have six same size buttons in 3X2 grid of the drawer. Click of each button displays the current value in text edit, which is below the grid, along with unit scroll, on the right side of it. Then there is clear and apply. This layout looks different on all platforms. Appreciate any pointers.

            Item {
                id: trackerContainer
                width: parent.width
                height: parent.height
            
                property FeatureButton selectedFeatureButton: AFeatureButton
                property bool updatingComboBox: false
            
                property var featureButtons: [
                    {
                        parameterName: "A",
                        parameterReading: dataController.paramMap["A"] + " " + dataController.paramMap["AUnit"],
                        units: "m, n"
                    },
                    {
                        parameterName: "B",
                        parameterReading: dataController.paramMap["B"] + " " + dataController.paramMap["BUnit"],
                        units: "n, u, m"
                    },
                    {
                        parameterName: "C",
                        parameterReading: (isFinite(dataController.paramMap["C"]) ?
                                               dataController.paramMap["C"].toFixed(4) :
                                               "N/A") + " " + dataController.paramMap["CUnit"],
                        units: "H, G"
                    },
                    {
                        parameterName: "D",
                        parameterReading: (isFinite(dataController.paramMap["D"]) ?
                                               dataController.paramMap["D"].toFixed(1) :
                                               "N/A") + " " + dataController.paramMap["DUnit"],
                        units: "d"
                    },
                    {
                        parameterName: "E",
                        parameterReading: dataController.paramMap["E"] + " " + dataController.paramMap["EUnit"],
                        units: "W, P"
                    },
                    {
                        parameterName: "F",
                        parameterReading: dataController.paramMap["F"] !== undefined ? dataController.paramMap["F"] : "",
                        units: []
                    }
                ]
            
                ColumnLayout {
                    id: layout
                    anchors.fill: parent  // Fills both width and height of the parent
                    spacing: 5
                    clip: true
            
                    // RowLayout for back button and heading
                    RowLayout {
                        id: headerRow
                        Layout.fillWidth: true  // Ensure RowLayout fills width
                        Layout.preferredHeight: parent.height * 0.10  // Increase the header height to accommodate the taller button
            
                        // Back button (as Button)
                        Button {
                            id: backButton
                            Layout.preferredWidth: headerRow.height * 0.7  // Keep the button width smaller for balance
                            Layout.preferredHeight: headerRow.height * 1.0  // Double the height of the button relative to the header height
                            background: Rectangle {
                                color: "lightblue"
                                border.color: "black"
                                border.width: 1
                                radius: Math.min(parent.height, parent.width) * 0.15  // Keep rounded corners proportional
                            }
                            contentItem: Text {
                                text: "←"
                                color: "black"
                                anchors.centerIn: parent  // Center the arrow text inside the button
                                font.pixelSize: backButton.height * 0.6  // Adjust font size to 60% of button height
                                horizontalAlignment: Text.AlignHCenter  // Center text horizontally
                                verticalAlignment: Text.AlignVCenter  // Center text vertically
                            }
                        }
            
                        // Heading Text
                        Text {
                            id: title
                            text: "Track Frequency"
                            font.pixelSize: headerRow.height * 0.9 // Adjust font size based on new header height
                            color: "black"
                            Layout.fillWidth: true  // Fill remaining space
                            horizontalAlignment: Text.AlignHCenter  // Center horizontally
                            verticalAlignment: Text.AlignVCenter  // Center vertically
                            elide: Text.ElideRight  // Prevent overflow
                        }
                    }
            
                    // Line below the heading and back button
                    Rectangle {
                        id: headerLine
                        color: "black"
                        height: 1
                        Layout.fillWidth: true  // Ensure line takes full width
                    }
            
                    GridLayout {
                        id: gridLayout
                        rows: 3
                        columns: 2
                        columnSpacing: 4
                        rowSpacing: 2
                        Layout.fillWidth: true
                        Layout.preferredHeight: parent.height * 0.40 // Take 35% of parent height
            
                        Repeater {
                            model: featureButtons.length
                            delegate: FeatureButton {
                                width: gridLayout.width / gridLayout.columns  // Ensure same width for all buttons
                                height: gridLayout.height / gridLayout.rows  // Ensure same height for all buttons
                                nameFontSize: Math.min(parent.height * 0.15, parent.width * 0.10)
            
                                // Access the properties from the featureButtons array
                                parameterName: featureButtons[index].parameterName
                                parameterReading: featureButtons[index].parameterReading
                                onClicked: {
                                    fmsTrackerContainer.selectedFeatureButton = this
                                }
                            }
                        }
                    }
            
                    // Add a spacer to push down the following items
                    Item {
                        Layout.preferredHeight: parent.height * 0.10  // Adjust the space as needed
                    }
            
                    // Move displayParameter down by setting margins
                    Label {
                        id: displayParameter
                        color: "green"
                        text: "A"
                        anchors.top: gridLayout.bottom
                        font.pixelSize: parent.height * 0.06
                        Layout.preferredHeight: parent.height * 0.05
                        anchors.margins: 20
                    }
            
                    RowLayout {
                        id: inputRow
                        Layout.fillWidth: true  // Ensure RowLayout fills the available width
                        Layout.preferredHeight: parent.height * 0.20  // 10% of parent's height
                        spacing: 10  // Space between components
            
                        // TextField for parameter value input
                        TextField {
                            id: parameterVal
                            Layout.fillWidth: true
                            Layout.preferredWidth: 0.45 * parent.width  // 45% of parent width
                            Layout.preferredHeight: inputRow.height   // Ensure the TextField respects inputRow height
                            inputMethodHints: Qt.ImhDigitsOnly  // Only digits input allowed
            
                            onTextChanged: {
                                var validInput;
                                if (selectedFeatureButton.parameterName === "C") {
                                    validInput = /^-?\d*\.?\d{0,4}$/;
                                } else if (selectedFeatureButton.parameterName === "D") {
                                    validInput = /^-?\d*\.?\d{0,1}$/;
                                } else {
                                    validInput = /^-?\d{0,3}$/;
                                }
            
                                // Validate input
                                if (!validInput.test(parameterVal.text)) {
                                    parameterVal.text = parameterVal.text.slice(0, -1);
                                    parameterVal.select(parameterVal.text.length, parameterVal.text.length);
                                }
                                helper.updateUserInput();
                            }
                        }
            
                        // ComboBox for unit selection
                        ComboBox {
                            id: unitComboBox
                            Layout.preferredWidth: 0.20 * parent.width  // 20% of parent width
                            Layout.preferredHeight: inputRow.height   // Ensure ComboBox respects inputRow height
                            Layout.fillWidth: true
                            visible: selectedFeatureButton.parameterName !== "F"
                            model: ["m", "n"]
                            currentIndex: (dataController.paramMap["AUnit"] === "mV" ? 0 : 1)
            
                            onCurrentIndexChanged: {
                                Qt.callLater(function() {
                                    if (!fmsTrackerContainer.updatingComboBox) {
                                        helper.updateUserInput();
                                    }
                                });
                            }
                        }
            
                        // ComboBox for frequency selection
                        ComboBox {
                            id: frequencyComboBox
                            Layout.preferredWidth: 0.20 * parent.width  // 20% of parent width
                            Layout.preferredHeight: inputRow.height  // Ensure ComboBox respects inputRow height
                            Layout.fillWidth: true
                            visible: selectedFeatureButton.parameterName === "C"
                            model: ["LSB", "USB"]
                            currentIndex: dataController.paramMap[selectedFeatureButton.parameterName.replace(/ /g, "") + "IsLSB"] ? 0 : 1
            
                            onCurrentIndexChanged: {
                                Qt.callLater(function() {
                                    if (!fmsTrackerContainer.updatingComboBox) {
                                        helper.updateUserInput();
                                    }
                                });
                            }
                        }
                    }
            
                    RowLayout {
                        id: bottomButtonsRow
                        width: parent.width
                        anchors.bottom: parent.bottom
                        Layout.fillWidth: true
                        Layout.preferredHeight: parent.height * 0.15
                        spacing: 20
            
                        Button {
                            id: clearButton
                            Layout.preferredWidth: parent.width * 0.40  // Reduced width to 30% of parent width
                            Layout.preferredHeight: bottomButtonsRow.height * 1.1  // Height remains 110% of the row height
                            background: Rectangle {
                                color: "white"
                                border.color: "black"
                                border.width: 1
                                radius: Math.min(parent.height, parent.width) * 0.5  // Reduce the radius to prevent circular buttons
                            }
                            contentItem: Text {
                                text: "Clear"
                                color: "black"
                                anchors.centerIn: parent
                                font.pixelSize: clearButton.height * 0.5  // Adjust font size accordingly
                                horizontalAlignment: Text.AlignHCenter
                                verticalAlignment: Text.AlignVCenter
                            }
                        }
            
                        Button {
                            id: applyButton
                            Layout.preferredWidth: parent.width * 0.40  // Reduced width to 30% of parent width
                            Layout.preferredHeight: bottomButtonsRow.height * 1.1  // Height remains 110% of the row height
                            background: Rectangle {
                                color: "white"
                                border.color: "black"
                                border.width: 1
                                radius: Math.min(parent.height, parent.width) * 0.5  // Reduce the radius to prevent circular buttons
                            }
                            contentItem: Text {
                                text: "Apply"
                                color: "black"
                                anchors.centerIn: parent
                                font.pixelSize: applyButton.height * 0.5  // Adjust font size accordingly
                                horizontalAlignment: Text.AlignHCenter
                                verticalAlignment: Text.AlignVCenter
                            }
                        }
                    }
            
                }
            
                Connections {
                    target: dataController
            
                    function onIsApplyButtonEnabledChanged() {
                        applyButton.enabled = dataController.isApplyButtonEnabled
                    }
                }
            }
            
            1 Reply Last reply
            0
            • johngodJ Offline
              johngodJ Offline
              johngod
              wrote on last edited by
              #6

              Hi @Ryna
              I haven't checked your code with much attention, so I don't know what the problem is, but I have developed a app with the same qml code, that works for android, ios, mobile, tablets, windows, linux, macos. I even got it to work with the same code, for using only one window for mobile, and multi windows on desktop. If you want, check the code here https://bitbucket.org/joaodeusmorgado/mathgraphicaqml/src/master/
              and the app is this one https://mathgraphica.carrd.co/
              I have made my own buttons and other qml elements, so the app looks the same in all operation systems.
              Basically I use anchors, flickable elements, I use Screen.pixelDensity to apply the same size for all buttons and elements.
              Hope this helps

              R 1 Reply Last reply
              0
              • johngodJ johngod

                Hi @Ryna
                I haven't checked your code with much attention, so I don't know what the problem is, but I have developed a app with the same qml code, that works for android, ios, mobile, tablets, windows, linux, macos. I even got it to work with the same code, for using only one window for mobile, and multi windows on desktop. If you want, check the code here https://bitbucket.org/joaodeusmorgado/mathgraphicaqml/src/master/
                and the app is this one https://mathgraphica.carrd.co/
                I have made my own buttons and other qml elements, so the app looks the same in all operation systems.
                Basically I use anchors, flickable elements, I use Screen.pixelDensity to apply the same size for all buttons and elements.
                Hope this helps

                R Offline
                R Offline
                Ryna
                wrote on last edited by
                #7

                @johngod This is a great reference. I will check the code and compare what I am doing wrrong here.
                Thank you so much.

                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