End to End GUI Development with Qt5
上QQ阅读APP看书,第一时间看更新

UI scaling

We’ve focused a lot on responsive UI in this book, using anchors and relative positioning where possible so that when the user resizes the window, the contents scale and adjust themselves appropriately. We’ve also pulled all the “hard-coded” properties like sizes and colors into a centralized Style object.

If we pick a property concerned with sizing, for example, sizeScreenMargin, it currently has a fixed value of 20. If we decide to increase the starting size of our Window element in MasterView, this screen margin size will remain the same. Now, it’s really easy to increase the screen margin too, thanks to the Style object, but it would be nice if all the hard-coded properties could scale up and down dynamically along with our Window element. That way, we can try out different window sizes without having to update Style each time.

As we’ve already seen, the flexibility of QML is extended even further with the built-in JavaScript support, and we can do just that.

First, let’s create new width and height properties for the window in Style:

readonly property real widthWindow: 1920
readonly property real heightWindow: 1080

Use these new properties in MasterView:

Window {
    width: Style.widthWindow
    height: Style.heightWindow
    ….
}

All the size properties in Style that we’ve created so far are relevant to this window size of 1920 x 1080, so let’s record that as new properties in Style:

readonly property real widthWindowReference: 1920
readonly property real heightWindowReference: 1080

We can then use the reference sizes and the actual sizes to calculate scaling factors in the horizontal and vertical axes. So in simple terms, if we design everything with a window width of 1,000 in mind and then we set the window to be 2,000 wide, we want everything to scale horizontally by a factor of 2. Add the following functions to Style:

function hscale(size) {
    return Math.round(size * (widthWindow / widthWindowReference))
}
function vscale(size) {
    return Math.round(size * (heightWindow / heightWindowReference))
}
function tscale(size) {
    return Math.round((hscale(size) + vscale(size)) / 2)
}

The hscale and vscale functions calculate the horizontal and vertical scaling factors respectively. For certain size properties like pixel size for fonts, there is no independent width and height, so we can calculate an average of the horizontal and vertical scales using the tscale function.

We can then wrap any properties we want to scale in the appropriate function. For example, our screen margin can use the tscale function:

readonly property real sizeScreenMargin: tscale(20)

Now, not only can you increase the initial size of the window in Style, but your selected properties will automatically scale to the new size.

A really useful module you can add to help with sizing is QtQuick.Window. We already added this to MasterView in order to access the Window element. There is another object in that module, Screen, which makes available information regarding the user’s display. It contains properties for things like the width and height of the screen, and orientation and pixel density, which can be useful if you’re working with high DPI displays such as the Microsoft Surface or Macbook. You can use these values in conjunction with your Style properties to do things such as making your window fullscreen, or make it 50% of the screen size and positioning it in the center of the display.