QML scaling does not work with non-integer scaling factors

南楼画角 提交于 2019-12-24 08:18:00

问题


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:


As mentioned in the comment, I was not satisfied by QT_SCALE_FACTOR so I decided to make it my self, and created a ScaleableWindow like this:

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
    }
}

You can now specify the scale-factor by passing e.g. the commandline argument --scale 0.4

You can also try to use Screen.pixelDensity to calculate a scaleing factor, but that relies on the display to correctly publish its pixel density, which failed for me quite often.

You can also use this to create a window that scales the content automatically, when you resize the window.


So if the question is Is it possible with the environment variable - I don't think so. If the question is Is it possible to scale the window and its content based on some external input - here is a solution.



来源:https://stackoverflow.com/questions/43997297/qml-scaling-does-not-work-with-non-integer-scaling-factors

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