QML scaling does not work with non-integer scaling factors

时间:2017-05-16 09:19:49

标签: windows qt user-interface qml

I'm writing an application using QML. I'm having trouble when I scale my GUI by non-integer factors. According to the docs, Qt::AA_EnableHighDpiScaling should enable device-independent pixels, therefore automatically taking care of most of the scaling:

The application attribute Qt::AA_EnableHighDpiScaling, introduced in Qt 5.6, enables automatic scaling based on the pixel density of the monitor.

In a blog post about 5.6, they admit that there can be problems:

Q: Are non-integer scale factors supported?

A: Qt uses qreal in the API, and will allow setting non-integer scale factors via QT_SCALE_FACTOR. However, Qt does not guarantee that graphics and styles will be glitch-free in that case. Styles may break first: the fusion style is generally most scalable. The Qt platform plugins round the reported scale factors to the nearest integer.

and in a comment:

Q: Does that mean it’s still effectively integer-only? What happens to Windows with 150% DPI scale?

A: Yes, unless you set/correct it manually with QT_SCALE_FACTOR. 150% should then go to 2x.

So for me this leads to a comically large GUI when scaling to 150%. However, the text scales correctly which leads to weird artifacts such as large button with small text.

Am I misunderstanding how this works or is it just not really possible yet?

1 个答案:

答案 0 :(得分:2)

正如评论中提到的那样,我对QT_SCALE_FACTOR感到不满意,所以我决定让自己成为自己,并创建了ScaleableWindow这样的:{/ p>

import QtQuick 2.0
import QtQuick.Controls 2.0

ApplicationWindow {
    id: root
    property real scale: 1
    property real unscaledWidth: 100
    property real unscaledHeight: 100

    Component.onCompleted: {
        var i = Qt.application.arguments.indexOf('--scale')
        if (i > -1 && Qt.application.arguments[i+1]) scale = parseFloat(Qt.application.arguments[i+1])
    }

    width: unscaledWidth * scale
    height: unscaledHeight * scale

    property alias scaledContentItem: scaledContent
    default property alias scaledContent: scaledContent.data

    Item {
        id: scaledContent
        width: root.unscaledWidth
        height: root.unscaledHeight
        scale: root.scale
        anchors.centerIn: parent
    }
}

您现在可以通过传递例如指定比例因子命令行参数--scale 0.4

您也可以尝试使用Screen.pixelDensity来计算缩放系数,但这取决于显示器正确发布其像素密度,这对我来说经常失败。

您还可以使用它来创建一个窗口,在您调整窗口大小时自动缩放内容。

因此,如果问题是是否可以使用环境变量 - 我不这么认为。如果问题是是否可以根据某些外部输入扩展窗口及其内容 - 这是一个解决方案。