Skalierung von QML Components

Alles rund um die Programmierung mit Qt Quick und QML
Antworten
scheka
Beiträge: 4
Registriert: 3. April 2018 21:02

Skalierung von QML Components

Beitrag von scheka »

Hallo zusammen,

ich bin neu in der QML Welt und benötige ein wenig Hilfe. Und zwar soll es eine kleine App sein, die später auf einem Raspi und einem 7" display laufen soll. Das Funktioniert soweit alles, jedoch passt irgendwie die Darstellung nicht.

Das 7" Display hat eine Auflösung von 1024x600. Also hab ich ein ApplicationWindow von 1024x600 erstellt und meine QML Objekte dort entsprechend platziert. Grob gesagt es sind 6 Rechtecke die etwas Anzeigen. Alle sind von der Größe so, dass das AppWin. sauber ausgefüllt wird. Wenn ich es jedoch auf dem Raspi laufen lassen (eglfs Fullscreen) sind die 6 Rechtecke alle etwas zu klein und sind im oberen linken Eck. Das gleich passiert, wenn ich das AppWin auf dem Rechner maximiere.

Ich habe nun ein wenig mit Row Layouts experimentiert, jedoch ohne großen Erfolg. Er verteilt die Objekte zwar gleichmäßig über den gesamten Screen, aber die sind dann immer noch zu klein. Wenn ich sage er soll die Breite und die Höhe ausfüllen, dann sind die Objekte zwar so groß, dass der Screen komplett ausgefüllt ist, jedoch passt dann das Seitenverhältnis nicht mehr. Und da auf dem Rechteck ein halber Kreis mit Hilfe von Canvas und Painter gezeichnet wird, passt dann da natürlich auch nix mehr.

Ich hoffe ich konnte es halbwegs verständlich beschreiben, was mir Probleme bereitet.

Vielen Dank

Gruß scheka
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Skalierung von QML Components

Beitrag von hilefoks »

Moin,

mir fehlt an deiner Problembeschreibung leider noch wie du aktuell deine Items positionierst. Wenn ich dich richtig verstehe, möchtest du ein bestimmtes Aspect-Ratio erhalten. In dem Fall kannst du deine Items natürlich nicht direkt in ein Grid/Row/Column-Layout mit Layout.fillHeight/fillWidth ablegen. Idealerweise posted du deinen Code bzw. ein minimales aber komplettes Beispiel.

Trotzdem schon einmal ein Beispiel:

Code: Alles auswählen

import QtQuick 2.0
import QtQuick.Layouts 1.3

Item {
    id: root
    implicitHeight: 400
    implicitWidth: 400

    Item {
        width: childrenRect.width
        height: childrenRect.height
        anchors.centerIn: parent

        Rectangle {
            y: 0
            x: 0
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }

        Rectangle {
            y: 0
            x: width
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }

        Rectangle {
            y: 0
            x: 2 * width
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }

        Rectangle {
            y: height
            x: 0
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }

        Rectangle {
            y: height
            x: width
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }

        Rectangle {
            y: height
            x: 2 * width
            color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
            width: Math.min(root.width / 3, root.height / 2)
            height: width
        }
    }
}
Falls ich dich richtig verstehe, kommt dies deinem Problem zumindest nahe. ;-)
Im Beispiel positioniere ich alles per Hand. Das ist nicht unbedingt ideal und kann schnell unübersichtlich werden, ist aber hier noch vertretbar.

MfG
Hilefoks
scheka
Beiträge: 4
Registriert: 3. April 2018 21:02

Re: Skalierung von QML Components

Beitrag von scheka »

Hi,

Danke für deine Antwort! Anbei der Code wie ich meine Items platziere:

Code: Alles auswählen

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 1024
    height: 600
  //  visibility: "FullScreen"

    title: qsTr("XXX")
    color: "black"
    id:mainwindow
    objectName: "MainWindow"



    Slider{
        id: slider
        x:314
        y:495
        width: 397
        height: 46
        anchors.horizontalCenterOffset: 1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 59
        value: -1.0
        from: -1.0
        to: 0.0
        stepSize: 0.01
    }

    RowLayout {
        id: rowLayout
        x: 120
        height: 251
        antialiasing: true
        scale: 1
        anchors.bottomMargin: 305
        spacing: 0
        anchors.right: parent.right
        anchors.rightMargin: 0
        anchors.leftMargin: 1
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        anchors.top: parent.top
        anchors.topMargin: 0

        Rect1 {
            id: rect1
            antialiasing: true
            Layout.maximumHeight: 800
            Layout.preferredHeight: 257
            Layout.fillHeight: true
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
            Layout.fillWidth: true
            Layout.minimumWidth: 50
            Layout.preferredWidth: 335
            Layout.maximumWidth: 800
            Layout.minimumHeight: 50
            value: slider.value

        }

        Rect2 {
            id: rect2
            antialiasing: true
            Layout.maximumHeight: 800
            Layout.preferredHeight: 257
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
            Layout.fillHeight: true
            Layout.fillWidth: true
            Layout.minimumWidth: 50
            Layout.preferredWidth: 335
            Layout.maximumWidth: 800
            Layout.minimumHeight: 50
        }

        Rect3 {
            id: rect3
            y: 0
            antialiasing: true
            Layout.maximumHeight: 800
            Layout.preferredHeight: 257
            Layout.fillHeight: true
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
            Layout.fillWidth: true
            Layout.minimumWidth: 50
            Layout.preferredWidth: 335
            Layout.maximumWidth: 800
            Layout.minimumHeight: 50
        }
    }

}
Du hast Recht ich benötige ein gewisses Seitenverhältnis der Items, sonst passt die Geschichte mit den Canvas nicht mehr. Jedoch soll er nach Möglichkeit den kompletten Screen je nach Größe voll ausfüllen.

Anbei auch ein Code Ausschnitt aus einem der Items

Code: Alles auswählen

import QtQuick 2.4
import QtGraphicalEffects 1.0


Rectangle{
    id: root
    //    height: parent.height
    //    width: parent.width
    color: "transparent"
    property double value: -1.0
    width: 335
    height: 257

    Image {
        width: parent.width
        height: parent.height
        fillMode: Image.PreserveAspectFit
        source: "pics/XXX.png"

        Text{
            id: realvalue
            x: 0
            y: 150
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            text: (((root.value)+1)*2).toFixed(0)
            anchors.topMargin: 100
            anchors.fill: parent
            font.pixelSize: 65
            fontSizeMode: Text.Fit
            minimumPointSize: 1
            color: "white"
        }

        SequentialAnimation {
            id:animation1
            loops: Animation.Infinite
            alwaysRunToEnd: true
            NumberAnimation { target: canvas; property: "opacity"; to: 0.0; duration: 250 }
            NumberAnimation { target: canvas; property: "opacity"; to: 1.0; duration: 250 }

       }

        Canvas {
            id: canvas

            // x: parent

            onValueChanged: canvas.requestPaint();
           // contextType: qsTr("")
            smooth: true
            antialiasing: true
            opacity: 1

            property color color1: "silver"
            property color color2: "red"
            property real value: root.value
            property real centerWidth: width / 2
            property real centerHeight: height / 2
            property real radius: Math.min(canvas.width, canvas.height) / 2
            anchors.topMargin: 0
            anchors.fill: parent




            onPaint: {
                var ctx = getContext("2d");
                ctx.save();

                var gradient2 = ctx.createRadialGradient((parent.width / 2),(parent.height * 0.76), 0, (parent.width / 2),(parent.height * 0.76),parent.height);
                gradient2.addColorStop(0.45, color1);
                gradient2.addColorStop(0.33, "transparent");

                var gradient3 = ctx.createRadialGradient((parent.width / 2),(parent.height * 0.76), 0, (parent.width / 2),(parent.height * 0.76),parent.height);
                gradient3.addColorStop(0.45, color2);
                gradient3.addColorStop(0.33, "transparent");   //unten

                //wechsel von silber zu Rot
                function getStrokeStyle ()
                {
                    var strokeStyle = gradient2
                    if(canvas.value >= -0.20) {
                        strokeStyle = gradient3
                    }
                    return strokeStyle
                }

                //starten / stopen des blinkens
                if(canvas.value >= -0.20){
                    animation1.start()
                }
                else
                    animation1.stop()


                ctx.clearRect(0, 0, canvas.width, canvas.height);

                ctx.beginPath();
                ctx.strokeStyle = getStrokeStyle()

                ctx.lineWidth = 70
                ctx.arc(canvas.centerWidth, canvas.height * 0.76, canvas.radius - (ctx.lineWidth / 1.82), Math.PI * (-1), Math.PI * (canvas.value), false)
                ctx.moveTo(10, 150);
                ctx.stroke();
                ctx.restore();

            }
            // - (ctx.lineWidth / 1.82)

            Behavior on value {
                NumberAnimation{
                    duration: 250
                    easing.type: Easing.OutCirc
                }
            }

        }
    }
}
Das ist der Canvas part. Vielleicht habe ich auch hier noch paar Bugs.

EDIT:

Habe eben dein Beispiel getestet. Genau so haben sich die Items zu Begin bei mir auch verhalten. In der Fester Ansicht den Screen nahezu ausgefüllt. Fenster maximiert, haben sich die Items nicht geändert und der halbe Screen ist leer.

Gruß scheka
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Skalierung von QML Components

Beitrag von hilefoks »

scheka hat geschrieben: 4. April 2018 20:51 Habe eben dein Beispiel getestet. Genau so haben sich die Items zu Begin bei mir auch verhalten. In der Fester Ansicht den Screen nahezu ausgefüllt. Fenster maximiert, haben sich die Items nicht geändert und der halbe Screen ist leer.
Also auf Windows, Linux und Mac verhält sich mein Beispiel wie ich es erwarte. Sprich, die Rechtecke füllen immer mindestens die volle Höhe oder Breite des Screens. Egal ob Fenster oder Fullscreen.

Wie lässt du deine Software auf dem Raspi laufen, welche Raspi-Hardware verwendest du, welche Distribution und welchen Grafik-Stack nutzt du dort (X11, eglfs, ...)? Laufen andere Programme im Fullscreen wie erwartet?

MfG
Hilefoks
scheka
Beiträge: 4
Registriert: 3. April 2018 21:02

Re: Skalierung von QML Components

Beitrag von scheka »

Hi,

also bei mir sieht es folgendermaßen aus:

Fenster Ansicht:
Bild

Full:
Bild

und der Code wie ich dein Beispiel eingebaut habe:

Code: Alles auswählen

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick 2.0
import QtQuick.Layouts 1.3

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")




    Item {
        id: root
        implicitHeight: 400
        implicitWidth: 400

        Item {
            width: childrenRect.width
            height: childrenRect.height
            anchors.centerIn: parent

            Rectangle {
                y: 0
                x: 0
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }

            Rectangle {
                y: 0
                x: width
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }

            Rectangle {
                y: 0
                x: 2 * width
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }

            Rectangle {
                y: height
                x: 0
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }

            Rectangle {
                y: height
                x: width
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }

            Rectangle {
                y: height
                x: 2 * width
                color: Qt.rgba(Math.random(), Math.random(), Math.random(), Math.random() + 0.3)
                width: Math.min(root.width / 3, root.height / 2)
                height: width
            }
        }
    }
}
Leider ist es mein erstes Projekt mit dem Raspi und Qt, hab leider nur dieses Programm. Auf dem Raspi ist aktuell ein Yocto Projekt Image mit Linux embedded mit den entsprechenden QT Paketen drauf. Das Ganze unter eglfs im Fullscreen mode.

Gruß scheka
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Skalierung von QML Components

Beitrag von hilefoks »

Ah, das erste Item in deinem Window (das mit der id root) hat eine fixe Größe:

Code: Alles auswählen

Item {
        id: root
        implicitHeight: 400
        implicitWidth: 400
Da willst du eigentlich etwa das Elternelement ausfüllen. Also die implicitHeight/implicitWidth raus und stattdessen anchors.fill: parent:

Code: Alles auswählen

Item {
        id: root
        anchors.fill: parent
MfG
Hilefoks
scheka
Beiträge: 4
Registriert: 3. April 2018 21:02

Re: Skalierung von QML Components

Beitrag von scheka »

Hi,

habe es hinbekommen Danke! Hast du vielleicht ein Beispiel, wie ich an die GPIO des Raspis komme. Würde gerne die wiringPi lib nutzen, bloß wie binde ich das am besten in den c++ Teil ein und vor allen Dingen wie bekomme eine Verbindung von c++ zum qml hin

Grüße scheka
maliya1
Beiträge: 1
Registriert: 6. Dezember 2023 07:38

Re: Skalierung von QML Components

Beitrag von maliya1 »

scheka hat geschrieben: 6. April 2018 21:41 Hi,

habe es hinbekommen Danke! Hast du vielleicht ein Beispiel, wie ich an die GPIO des Raspis komme. Würde gerne die wiringPi lib nutzen, bloß wie binde ich das am besten in den c++ Teil ein und vor allen Dingen wie bekomme eine Verbindung von c++ zum qml hin

Grüße scheka
Certainly, To access Raspberry Pi GPIO using WiringPi in a C++/Qt project, include the WiringPi library in your C++ code. Use the WiringPi functions for GPIO control. To connect C++ with QML, use Qt's signals and slots mechanism. Create a QObject-derived class with slots for GPIO interactions. Expose this class to QML using `qmlRegisterType`. In QML, instantiate the C++ object and connect its signals to QML functions. Update QML elements based on GPIO changes. Ensure proper threading if needed. This integration allows seamless communication between C++ and QML in your Raspberry Pi project.
Antworten