QML fit screen on all resolutions

孤者浪人 提交于 2021-02-06 10:16:18

问题


Hi all I have problem with my QML code. I made mistake and I went to put certain size to elements and now I have problem when putting app on other devices. I will paste you my code where I have width and height so you can change it to show me how to work with dynamic resizeing.

I need to say that I am calling qml file from qt with this code:

 QDeclarativeView *view= new QDeclarativeView;
    ui->setupUi(this);

    setCentralWidget(view);

    QDeclarativeContext *ctxt = view->rootContext();
    ctxt->setContextProperty("funkcije",this);
    ctxt->setContextProperty("myModel", QVariant::fromValue(MainWindow::dataList));

    view->setSource(QUrl("qrc:/gui.qml"));
    view->setResizeMode(QDeclarativeView::SizeRootObjectToView);
    showFullScreen();

And here goes my QML code:

Rectangle {

    id:window
    width: 602
    height: 1000
    anchors.fill: parent
     radius: 0
     .....


     ListView {
         id: listview1
         x: 0
         y: 219
        // width: 574
        // height: 967
         width: window.width
         height: window.height
         visible: true
         keyNavigationWraps: false
         boundsBehavior: Flickable.DragAndOvershootBounds
         opacity: 1
         maximumFlickVelocity: 2500
         anchors.leftMargin: 0
         highlightMoveSpeed: 489
         contentWidth: 0
         preferredHighlightEnd: 2
         spacing: 5
         highlightRangeMode: ListView.NoHighlightRange
         snapMode: ListView.SnapToItem
         anchors.bottomMargin: 0
         anchors.rightMargin: 0
         anchors.topMargin: 219
              anchors.fill: parent
              model: myModel
              delegate:Component {
                  //id: contactDelegate
                  Item {
                      id:it;
                      property variant myData: model
                      width: 574; height: 220
                      Column {
                          id:col
                          x: 12
                          y: 0
                          width: 561
                          height: 164
                          smooth: true
                          anchors.rightMargin: 0
                          anchors.bottomMargin: 7
                          anchors.leftMargin: 13
                          anchors.topMargin: 7
                          anchors.fill: parent
                          spacing: 15
                          ......


              highlight: Rectangle
              {
                  width: 600
                  height: 222
                  color:"black"; radius: 5; opacity: 0.7

              focus: true

              }
}

          Rectangle {
              id: rectangle1
              x: 0
              y: 0
              width: 602
              height: 219
              ......

          //dodaj korisnika
          Flipable {
              id: flipable
              x: 6
              y: 32
              width: 173
              height: 179
              .......

                   MouseArea {
                       x: 10
                       y: 9
                       width: 146
                       height: 150
                       anchors.rightMargin: 7
                       anchors.leftMargin: 10
                       anchors.topMargin: 9
                       anchors.bottomMargin: 9
                       hoverEnabled: false
                       anchors.fill: parent
                       ........

          //Brisanje korisnika
          Flipable {
              id: flipable1
              x: 408
              y: 32
              width: 175
              height: 179
              .......

                   MouseArea {
                       x: 7
                       y: 9
                       width: 153
                       height: 151
                       anchors.rightMargin: 8
                       anchors.leftMargin: 7
                       anchors.topMargin: 9
                       anchors.bottomMargin: 8
                       hoverEnabled: false
                       anchors.fill: parent
                       .......

          //promjeni korisnika
          Flipable {
              id: flipable2
              x: 208
              y: 32
              width: 176
              height: 179
             .......

                   MouseArea {
                       x: 7
                       y: 9
                       width: 73
                       height: 76
                       anchors.rightMargin: 7
                       anchors.leftMargin: 7
                       anchors.topMargin: 9
                       anchors.bottomMargin: 9
                       hoverEnabled: false
                       anchors.fill: parent
                       .......

            Text {
                id: text1
                x: 200
                y: 212
                font.pixelSize: 12
                opacity: 0
            }

            Rectangle {
                id: rectangle2
                x: 259
                y: 510
                width: 200
                height: 200
                color: "#ffffff"
                opacity: 0
            }

            TextInput {
                id: text_input1
                x: 331
                y: 233
                width: 80
                height: 20
                font.pixelSize: 12
                opacity: 0
            }

            Text {
                id: text2
                x: 136
                y: 228
                font.pixelSize: 12
                opacity: 0
            }

            Text {
                id: text3
                x: 152
                y: 314
                font.pixelSize: 12
                opacity: 0
            }

            Rectangle {
                id: rectangle3
                x: 256
                y: 293
                width: 200
                height: 200
                color: "#ffffff"
                opacity: 0
            }

            Rectangle {
                id: rectangle4
                x: 339
                y: 787
                width: 200
                height: 200
                color: "#ffffff"
                opacity: 0
            }

            Rectangle {
                id: rectangle5
                x: 270
                y: 456
                width: 200
                height: 200
                color: "#ffffff"
                opacity: 0
            }

            TextInput {
                id: text_input2
                x: 269
                y: 316
                width: 80
                height: 20
                font.pixelSize: 12
                opacity: 0
            }

            TextInput {
                id: text_input3
                x: 269
                y: 401
                width: 80
                height: 20
                font.pixelSize: 12
                opacity: 0
            }

            TextInput {
                id: text_input4
                x: 269
                y: 495
                width: 80
                height: 20
                font.pixelSize: 12
                opacity: 0
            }



            TextInput {
                id: text_input5
                x: 143
                y: 465
                width: 80
                height: 20
                text: qsTr("text")
                font.pixelSize: 12
                opacity: 0
            }



states: [
    State {
        name: "State1"

        PropertyChanges {
            target: listview1
            x: 0
            y: 1049
            width: 574
            height: 967
            visible: false
            anchors.topMargin: 1049
            anchors.rightMargin: 0
            anchors.bottomMargin: 0
            anchors.leftMargin: 0
        }



        PropertyChanges {
            target: rectangle1
            x: 0
            y: 0
            width: 602
            height: 253
            visible: true
        }

        PropertyChanges {
            target: text1
            x: 187
            y: 253
            width: 247
            height: 71
            color: "#c48d17"
            text: qsTr("Unesite novog korisnika")
            styleColor: "#e61717"
            style: "Raised"
            font.pixelSize: 31
            font.family: "Lucida Handwriting"
            verticalAlignment: "AlignVCenter"
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: rectangle2
            x: 251
            y: 353
            width: 258
            height: 42
            color: "#777e79"
            radius: 15
            smooth: true
            opacity: 1
        }

        PropertyChanges {
            target: text_input1
            x: 251
            y: 360
            width: 258
            height: 29
            font.pixelSize: 17
            font.family: "Lucida Handwriting"
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: text2
            x: 127
            y: 362
            width: 101
            height: 25
            color: "#fd0606"
            text: qsTr("Ime")
            style: "Raised"
            font.family: "Lucida Handwriting"
            font.pixelSize: 22
            verticalAlignment: "AlignVCenter"
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: text3
            x: 119
            y: 519
            color: "#f70606"
            text: qsTr("Prezime")
            style: "Raised"
            font.pixelSize: 20
            font.family: "Lucida Handwriting"
            verticalAlignment: "AlignVCenter"
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: rectangle3
            x: 251
            y: 514
            width: 258
            height: 40
            color: "#777e79"
            radius: 15
            opacity: 1
        }

        PropertyChanges {
            target: rectangle4
            x: 251
            y: 669
            width: 258
            height: 38
            color: "#777e79"
            radius: 15
            opacity: 1
        }

        PropertyChanges {
            target: rectangle5
            x: 251
            y: 823
            width: 258
            height: 36
            color: "#777e79"
            radius: 15
            opacity: 1
        }

        PropertyChanges {
            target: text_input2
            x: 251
            y: 519
            width: 258
            height: 29
            font.family: "Lucida Handwriting"
            font.pixelSize: 17
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: text_input3
            x: 251
            y: 674
            width: 258
            height: 29
            horizontalAlignment: "AlignHCenter"
            font.pixelSize: 17
            font.family: "Lucida Handwriting"
            opacity: 1
        }

        PropertyChanges {
            target: text_input4
            x: 251
            y: 827
            width: 258
            height: 29
            font.family: "Lucida Handwriting"
            font.pixelSize: 17
            horizontalAlignment: "AlignHCenter"
            opacity: 1
        }

        PropertyChanges {
            target: text4
            x: 127
            y: 669
            width: 85
            height: 31
            color: "#f70606"
            text: qsTr("Broj")
            style: "Raised"
            font.family: "Lucida Handwriting"
            font.pixelSize: 20
            horizontalAlignment: "AlignHCenter"
            verticalAlignment: "AlignVCenter"
            opacity: 1
        }


]
 }

I have put all the code with width and height so you can see what I have done wrong. And please if someone can say me how to make it dynamically fill.


回答1:


It's unfortunately tricky to get perfect, as it's likely that as the screen size shrinks you might actually want the buttons to be bigger and to drop content from the screen to ensure the user can access and read everything ok.

But the general approach is actually to set a scale factor in the C++ side:

ctxt->setContextProperty("scale", /* put calculated scale factor here */);

And then on the QML side, use that everyone to scale all the objects:

Rectangle {

    id:window
    width: 602 * scale
    height: 1000 * scale

That way you can adjust the scale variable to change everything's size. Having said that, many people end up with different QML files depending on the platform size though.




回答2:


I recommend you read the Scalability page in the current Qt (4.8) documentation: it is on exactly this topic.

It recommends these techniques (I'm quoting the page here), and then supplies much more detail.

  • Create separate top-level layout definitions for each form factor.

  • Keep the layouts small and let components scale relative to their immediate parent.

  • Define device independent measurements, such as dp (device independent pixels), and use these to scale components and for layout measurement.

  • Define layouts in a proportional way using the built-in layout features of QML.


Update 2014-11-18 This and video article looks very useful indeed: Supporting Multiple Screen Sizes & Screen Densities with Qt and V-Play

Update 2017-01-24 There is an updated Qt 5.8 version of the Scalability page mentioned above.




回答3:


Changing the device, you are actually changing the screen pixel density. If you have a device with low quality display it will have lower number of pixels per inch or pixels per centimeter than a device with high quality display.

Understanding this we can easily devise a method to scale our content according to the pixel density. For example in my case I have a laptop on which I use Qt creator. It has pixel density of 4. But my android phone is of high quality which has density of 16(4 times more than my Laptop). It means if an item has a width 'X' and height 'Y' when displaying on my Laptop, on my phone it will appear with a width 'X'/4 and height 'Y'/4 . Thus I have to scale height and width by 4.

Now, How to implement this? In QML we have a property "pixelDensity" under object Screen which will give you the pixel density of the screen where you are running your application. Dividing this by the screen density of screen where you tested your application will give you the scale factor. So now you don't need to worry about other devices you have just find the pixel density of screen you are currently working on.

Following code works perfectly for me.

property int default_pix_density: 4  //pixel density of my current screen
property int scale_factor: Screen.pixelDensity/default_pix_density
Rectangle
{
    width: 50*scale_factor
    height: 20*scale_factor
}


来源:https://stackoverflow.com/questions/9550847/qml-fit-screen-on-all-resolutions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!