QML 适合所有分辨率的屏幕

Posted

技术标签:

【中文标题】QML 适合所有分辨率的屏幕【英文标题】:QML fit screen on all resolutions 【发布时间】:2012-03-03 23:38:57 【问题描述】:

大家好,我的 QML 代码有问题。 我犯了错误,我给元素设置了一定的大小,现在将应用程序放在其他设备上时出现问题。 我会将我的代码粘贴到我有宽度和高度的地方,以便您可以更改它以向我展示如何使用动态调整大小。

我需要说我是用这个代码从 qt 调用 qml 文件:

 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();

这是我的 QML 代码:

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
        


]
 

我已将所有代码的宽度和高度放在一起,这样您就可以看到我做错了什么。如果有人能告诉我如何让它动态填充,请告诉我。

【问题讨论】:

【参考方案1】:

不幸的是,要完美是很棘手的,因为随着屏幕尺寸的缩小,您可能实际上希望按钮更大,并从屏幕上删除内容以确保用户可以访问和阅读一切正常。

但是一般的做法其实是在C++端设置一个比例因子:

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

然后在 QML 方面,使用每个人来缩放所有对象:

Rectangle 

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

这样你就可以调整比例变量来改变一切的大小。话虽如此,但根据平台大小,许多人最终会得到不同的 QML 文件。

【讨论】:

你能给我举个例子吗,你的意思是如何计算?所以我在 C++ 中确定了我的大小,然后我测量了比例?你对公式有一些想法吗? 一般来说,它会涉及一些#ifdefs 来确定它是什么类型的设备。例如,如果它是一个小型设备,那么您将比例因子设置为一个较小的值,等等。我一直想写一篇关于我在 Qt Widgets 与 QML 之间进行选择的博客文章。它也对你有用......我会在这周尝试完成它并在此处发布链接。 您可以直接更改父 qml 文件的 'scale' 属性,从而自动缩放所有后续子 qml 文件,而不是做这么多。 (假设画布以相同的宽度和高度比例变化)【参考方案2】:

我建议您阅读当前 Qt (4.8) 文档中的 Scalability 页面:它正是关于这个主题。

它推荐了这些技术(我在这里引用了页面),然后提供了更多细节。

为每个外形尺寸创建单独的***布局定义。

保持布局小,让组件相对于它们的缩放 直系父母。

定义独立于设备的测量,例如 dp(设备 独立像素),并使用这些来缩放组件和布局 测量。

使用内置布局按比例定义布局 QML 的特点。


2014-11-18 更新 这篇视频文章看起来确实非常有用: Supporting Multiple Screen Sizes & Screen Densities with Qt and V-Play

2017-01-24 更新上面提到的可扩展性页面有一个updated Qt 5.8 version。

【讨论】:

【参考方案3】:

更改设备,实际上是在更改屏幕像素密度。如果您的设备显示质量较低,则每英寸或每厘米的像素数会低于显示质量高的设备。

了解这一点后,我们可以轻松设计一种方法来根据像素密度缩放我们的内容。例如,在我的情况下,我有一台使用 Qt creator 的笔记本电脑。它的像素密度为 4。但我的 android 手机质量高,密度为 16(是笔记本电脑的 4 倍)。这意味着如果一个项目在我的笔记本电脑上显示时具有宽度 'X' 和高度 'Y' ,在我的手机上它将显示为宽度 'X'/4 和高度 'Y'/4 。因此,我必须将高度和宽度缩放 4。

现在,如何实现呢?在 QML 中,我们在对象 Screen 下有一个属性“pixelDensity”,它将为您提供运行应用程序的屏幕的像素密度。将其除以您测试应用程序的屏幕密度将为您提供比例因子。所以现在您无需担心其他设备,您只需找到您当前正在使用的屏幕的像素密度。

以下代码非常适合我。

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

【讨论】:

那么,对于 Samsung Galaxy Tab 3 10.1,default_pix_density 应该是 149 ppi pixel density 规范? @KernelPanic 你可以通过'Screen.pixelDensity'找到屏幕密度。仅当您用于开发/测试的设备与您要部署应用程序的设备具有不同的像素密度时,此方法才有用。 'default_pix_density' 是您正在测试/开发的设备的像素密度。

以上是关于QML 适合所有分辨率的屏幕的主要内容,如果未能解决你的问题,请参考以下文章

QT怎么解决不同分辨率

更改分辨率时,Qml 应用程序不合适

CSS使图像调整大小并适合任何屏幕

创建适合任何屏幕分辨率的母版页

如何调整我的vb6程序以使其自动适合任何屏幕分辨率?

如何根据设备/屏幕分辨率调整屏幕?