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 适合所有分辨率的屏幕的主要内容,如果未能解决你的问题,请参考以下文章