在OpenGL术语中,我想要做的是修改Qt GUI的投影矩阵。
假装窗口是480x640。它显示为正常,并呈现为纹理。 然后我拍摄纹理,并在整个屏幕上拉伸它。
Qt有类似的东西吗?我不希望GUI看起来很好,并且在480x640平板电脑上有适当大小的文本,但随后它会在1536x2048平板电脑上加载,你需要一个放大镜来显示文本。
之前我在OpenGL中编写了自己的GUI,计算了vid.width / BASEWIDTH,vid.height / BASEHEIGHT比率,并将元素的模型视图矩阵相乘,以确保GUI始终填充屏幕并保持相同的大小 - - 显然这只能完美地提供宽高比是一样的,但我离题了。
我在Qt Quick中与布局混淆了一段时间,它提供了一些不错的锚定选项,但是如果父窗口较大,则无法扩展文本。或者我在这里遗漏了什么?
我写的OpenGL GUI有一些控制位置坐标的选项:
转换的原点(顶部,中间,底部,左侧,中间,右侧) PosIsPercentage(指定位置坐标是否被解释为屏幕宽度/高度的百分比)
这允许您将位置设置为距屏幕任意边缘的距离,或者您可以设置PosIsPercentage = true并将X值设置为75以使坐标始终为屏幕尺寸的3/4
还有一个SizeIsPercentage值,因此您可以将按钮设置为屏幕宽度的10%。
我在Qt Quick设计器中看到了其中的一些选项,但它们的表现并不像我期望的那样。
我知道这很难解释,所以这是一张图片来证明:
http://www.spaddlewit.com/QtLayoutProblem.png
(不是我用的是Qt,而是我遇到的问题的一个很好的例子)
答案 0 :(得分:1)
根据屏幕的宽度和高度缩放项目的效果非常好,除非您移动到高DPI设备。更好的方法是根据默认字体的高度缩放项目。例如,Text项的默认字体大小在Qt支持的平台上始终清晰可读,无论DPI如何。您可以使用相同的原则来缩放字体大小;将默认字体大小乘以某个数量。
下面我快速模拟了您链接到的屏幕截图:
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
id: window
contentItem.implicitWidth: 640
contentItem.implicitHeight: 480
contentItem.minimumWidth: 640
contentItem.minimumHeight: 480
contentItem.maximumWidth: 1024
contentItem.maximumHeight: 768
/*
With Qt 5.4, you can also use the new FontMetrics item,
which saves you the overhead of creating a Text item:
For example:
FontMetrics {
id: fontMetrics
}
Then:
font.pixelSize: fontMetrics.font.pixelSize * 4
anchors.margins: fontMetrics.implicitHeight * 2
*/
Text {
id: defaultText
}
Image {
source: "http://cdn2.landscapehdwalls.com/wallpapers/1/perfect-green-hills-1197-1280x800.jpg"
}
Item {
id: container
anchors.fill: parent
anchors.margins: defaultText.implicitHeight * 2
Column {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: container.anchors.margins
Text {
id: yourGameText
text: "Your Game!"
font.pixelSize: defaultText.font.pixelSize * 4
wrapMode: Text.Wrap
}
ListView {
interactive: false
anchors.right: parent.right
width: yourGameText.width
height: container.height * 0.3
model: ["Play Game!", "Options", "Exit"]
delegate: Button {
text: modelData
width: ListView.view.width
}
}
}
Row {
anchors.left: parent.left
anchors.bottom: parent.bottom
spacing: container.anchors.margins
Image {
source: "http://www.facebookbrand.com/img/assets/asset.f.logo.lg.png"
width: defaultText.implicitHeight * 3
height: width
}
Image {
source: "http://g.twimg.com/Twitter_logo_white.png"
width: defaultText.implicitHeight * 3
height: width
}
Image {
source: "http://www.youtube.com/yt/brand/media/image/YouTube-logo-full_color.png"
width: defaultText.implicitHeight * 3
height: width
}
}
}
}
我做的第一件事是设置窗口的默认,最小和最大尺寸。
接下来,我创建了一个空文本项,项目和文本大小将基于此项。它可能看起来像hackish,它有点,但它也很好用。正如评论中所提到的,在Qt 5.4中会有一个FontMetrics类型,您可以使用它而不是创建一个永远不会显示的Text项目。
另一种方法是使用Screen的pixelDensity属性。
你说你想:
将位置设置为距屏幕任意边缘的距离
我通过创建填充窗口的Item,然后将窗口边缘的边距设置为默认字体的隐式高度的某个因素来实现。这确保了项目内的内容与窗口边缘的物理距离(例如,以毫米为单位)相同,而不管您正在查看它的设备的DPI。如果您希望窗口较大时距离较大,则可以改为:
anchors.margins: window.width * 0.1
查看Text
中的Column
项。如果要确保文本在屏幕上的物理大小相同,可以将font.pixelSize
设置为默认字体的大小乘以某个数量。再说一遍,如果您更愿意将其基于屏幕大小而不是DPI,那么您可以这样做:
font.pixelSize: window.height * 0.05
Scalability文档也对此主题进行了很好的概述。
下面是正在运行的应用程序的屏幕截图:
答案 1 :(得分:0)
以下工作,但令人讨厌 - 您必须创建scaleWidth和scaleHeight函数并在其中包装任何常量坐标。 字体大小沿着屏幕的最短边缘缩放 - 此应用程序是仅限纵向的方向,因此它使用scaleWidth(pointSize)作为字体大小。
很高兴找到一个与QML设计器兼容的解决方案..有没有办法自动插入这个计算,之后可能在运行时的C ++代码中?
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
ApplicationWindow {
id:window
visible: true
width: 480
height: 640
function scaleWidth(w)
{
return w * (width / 480.0)
}
function scaleHeight(h)
{
return h * (height / 640.0)
}
Text {
id: defaultText
}
Image {
id: image1
x: 0
y: 0
width: window.width
height: window.height
fillMode: Image.Stretch
source: "http://cdn2.landscapehdwalls.com/wallpapers/1/perfect-green-hills-1197-1280x800.jpg"
Label {
id: lblTitle
x: 0
y: scaleHeight(8)
text: qsTr("Welcome to the App")
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: scaleWidth(36)
horizontalAlignment: Text.AlignHCenter
}
Label {
id: lblSubtitle
x: 0
text: qsTr("Login to Continue")
font.pointSize: scaleWidth(24)
anchors.top: lblTitle.bottom
anchors.topMargin: scaleHeight(8)
anchors.horizontalCenter: lblTitle.horizontalCenter
}
Item {
id: itemCenterAlign
x: 0
y: 0
width: 0
height: 200
anchors.horizontalCenter: parent.horizontalCenter
}
Label {
id: lblUsername
x: 0
text: qsTr("Username:")
anchors.top: lblSubtitle.bottom
anchors.topMargin: scaleHeight(64)
font.bold: true
font.pointSize: scaleWidth(24)
anchors.right: itemCenterAlign.left
anchors.rightMargin: scaleWidth(8)
}
TextField {
id: txtUsername
width: scaleWidth(224)
height: scaleHeight(43)
anchors.left: itemCenterAlign.right
anchors.leftMargin: scaleWidth(8)
anchors.top: lblSubtitle.bottom
anchors.topMargin: scaleHeight(64)
font.pointSize: scaleWidth(24)
placeholderText: qsTr("Username")
}
Label {
id: lblPIN
x: 0
y: scaleWidth(-8)
text: qsTr("PIN:")
font.bold: true
font.pointSize: scaleWidth(24)
anchors.topMargin: scaleHeight(12)
anchors.right: itemCenterAlign.left
anchors.rightMargin: scaleWidth(8)
anchors.top: lblUsername.bottom
}
TextField {
id: txtPIN
x: 0
y: 0
width: scaleWidth(224)
height: scaleHeight(43)
placeholderText: qsTr("PIN")
font.pointSize: scaleWidth(24)
anchors.topMargin: scaleHeight(8)
anchors.leftMargin: scaleWidth(8)
anchors.left: itemCenterAlign.right
anchors.top: txtUsername.bottom
}
Row {
id: row1
x: 0
y: scaleHeight(277)
width: scaleWidth(464)
height: scaleHeight(115)
spacing: scaleWidth(8)
anchors.horizontalCenter: parent.horizontalCenter
Button {
id: cmdQuit
text: qsTr("Quit")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
Button {
id: cmdGPSOnly
text: qsTr("GPS Only")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
Button {
id: cmdLogin
text: qsTr("Login")
width: row1.width / 3 - row1.spacing / 2
height: row1.height
}
}
Button {
id: cmdAbout
width: cmdQuit.width
height: scaleHeight(44)
text: qsTr("About")
anchors.top: row1.bottom
anchors.topMargin: scaleHeight(8)
anchors.left: row1.left
anchors.leftMargin: 0
}
Label {
id: lblVersion
y: 619
text: qsTr("v3.0.0.0")
font.pointSize: scaleWidth(16)
anchors.bottom: parent.bottom
anchors.bottomMargin: scaleHeight(8)
anchors.left: parent.left
anchors.leftMargin: scaleWidth(8)
}
Label {
id: lblBooks
x: 0
y: lvBooks.y
text: qsTr("Books Loaded:")
horizontalAlignment: Text.AlignRight
font.pointSize: scaleWidth(24)
anchors.right: lvBooks.left
anchors.rightMargin: scaleWidth(8)
}
Rectangle
{
x: lvBooks.x
y: lvBooks.y
width: lvBooks.width
height: lvBooks.height
color: "white"
border.color: "black"
}
ListView {
id: lvBooks
x: 0
y: 0
width: scaleWidth(224)
height: scaleHeight(160)
anchors.bottom: parent.bottom
anchors.bottomMargin: scaleHeight(8)
anchors.right: parent.right
anchors.rightMargin: scaleWidth(8)
model: ListModel {
ListElement {
name: "Book1"
}
ListElement {
name: "Book2"
}
}
delegate: Item {
x: 5
width: scaleWidth(80)
height: scaleHeight(40)
Row {
Text {
text: name
font.bold: true
font.pointSize: scaleWidth(24)
anchors.verticalCenter: parent.verticalCenter
}
spacing: 0
}
}
}
}
}