Qt Virtual Keyboard orientation - qt

I am trying to use the Qt Virtual keyboard in my application and one of the things that would be nice to have is to have the keyboard come from the right side of the screen and not basically align itself to use the full available width but say half the width.
Now looking at the InputPanel documentation it says:
The keyboard size is automatically calculated from the available
width; that is, the keyboard maintains the aspect ratio specified by
the current style. Therefore the application should only set the width
and y coordinates of the InputPanel, and not the height.
So, in my application I would like to set the width (say to half the screen width) but that means that the height is calculated by default and the keyboard is too small. What I would like to do is to set the width and ask the keyboard to ignore the aspect ratio settings and basically set the height to the parent height. This is, of course, at odds with the documentation quoted above and I wonder if someone knows of a workaround for this?
My InputPanel looks like:
InputPanel {
id: inputPanel
z: 89
y: active ? parent.height - height : parent.height + 100
width: 300
anchors.right: parent.right
}
With my current code (with qt numeric keypad enabled) it looks like the attached image:
What I would like is to stretch the keyboard in the vertical direction to use the height of the parent window. Currently, it calculates the height based on the current aspect ratio which makes the input panel too small for my needs.

Related

Image size vs sourceSize strange things

We had a strange problem with blurred images under Retina displays. Left part of the image - before, right one - after the fix.
Our QML code was using this code to show images:
Image {
anchors.verticalCenter: parent.verticalCenter
sourceSize.width: 25
sourceSize.height: 25
source: preview.url
}
I've tried to multiply sourceSize by Screen.devicePixelRatio - images became bigger so they did not fit their places.
Then I've replaced sourceSize.width with just width and the same for height. So:
Image {
anchors.verticalCenter: parent.verticalCenter
width: 25
height: 25
source: preview.url
}
And it works fine now.
My questions are:
Is it required to multiply sourceSize by devicePixelRatio? Or is it managed automatically? It seems that it is managed automatically for PNG and NOT managed for SVG.
If it is already managed automatically for PNG (these images preview.url are PNGs) then why was it blurred? The original PNG image is of size 64x64 pixels.
Why did images become bigger after I've multiplied sourceSize by devicePixelRatio?
Addition #1. I'm using data:// scheme in images' URLs. I.e.
QString url("data:");
url += imageMimeType;
url += ";base64,";
url += imageData.toBase64();
While referring to the other answer I gave you here, my understanding of the Qt code is that, outside from the cases described here, Qt does no scale that value. So my understanding seems to be the opposite of what you state in 1. What evidences led you to that statement?
Assuming this concept is correct (I may be incorrect), the reason for point 2, would be that Qt is loading a size that would be appropriate for 1x scaling. But for higher factors, there is a quality loss. If you are on retina, then you should adjust that value, or provide the #2x version.
As for point 3, the reason is probably in the docs: "if the width and height properties are not specified, the Image automatically uses the size of the loaded image". So if you double the size of the loaded image, you double the size of the element, as you are not setting width and height explicitly.
Setting width and height solves the problem because the image is loaded in full size, so it can draw with proper quality after the scaling.
Hope someone else can correct me if my understanding of Qt code is wrong.

QML/Qt: Make displayed text as large as possible depending on the parent containing it

I am trying to make a very simple KDE-Plasma Widget where only a certain number is displayed. I want to make this displayed number have a font size as large as possible depending on the parent containing it.
Here is what it looks right now:
As you can see, the text inside has a lot of space around it. What I actually want it to be is something like the "Date And Time" Widget found in KDE Plasma (my widget is right next to it for comparison):
Here, the time displayed has much lesser space around it while also auto-resizing whenever the panel height is changed.
Here is what the current code looks like:
import QtQuick 2.6
import QtQuick.Layouts 1.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
Item {
id: main
anchors.fill: parent
Layout.minimumWidth: units.iconSizes.large
Layout.minimumHeight: units.iconSizes.large
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
PlasmaComponents.Label {
id: display
anchors {
fill: parent
margins: Math.round(parent.width * 0.1)
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: foobar
font.pixelSize: 1000;
minimumPointSize: theme.smallestFont.pointSize
fontSizeMode: Text.Fit
font.bold: true
}
Timer {
some stuff
}
}
I tried looking into the code of the above Date and Time widget and wrote down the exact same layouts/controls (which is what you are seeing in the above code) with the same positioning/styling properties and yet I get a lot of space around my text/or the font size continues to remain small.
I tried your code and it resized the font correctly. For the spacing around the text, there are two points:
The spacing on the left and right is easily controlled by adjusting the margins value that you are using. For less space, try Math.round(parent.width * 0.05).
The spacing on the top and bottom is larger because the shape of your parent object is square, while the shape of the text is rectangular. In order to make the text fit the height of the square without exceeding the width of the square, the text would not just need to resize, it would need to be stretched vertically. But QML does not have an easy way to do that, and I doubt that's really what you want anyway.
EDIT:
And if you do want font stretching, I'll point you to this answer.
Thanks to #JarMan's input I was able to realize that my text was being rendered in small font because of lack of space due to the root (item) element being square in shape.
I have now figured that to change the layout sizes of the root element inside the KDE-Plasma panel, one needs to mess with Layout.preferredWidth and Layout.preferredHeight.
Here is what I did:
item {
.
.
Layout.preferredWidth: 150 * units.devicePixelRatio
Layout.preferredHeight: 50 * units.devicePixelRatio
.
.
}
Note: the 150 and 50 values aren't final. It basically gives an idea about the ratio at which the root element's width and height should be in (and I wanted a rectangle). It automatically resizes the inner content too as the Plasma Panel is resized.

How to scroll with arrow keys in a Kirigami ScrollablePage?

The Qt QML based mobile/desktop convergent UI framework Kirigami provides a QML type ScrollablePage to support scrolling through content. Placing any visual QML item into it automatically makes it scrollable if it's larger than the ScrollablePage itself:
ScrollablePage is a Page that holds scrollable content, such as ListViews.
Scrolling and scrolling indicators will be automatically managed.
Kirigami.ScrollablePage {
id: root
//The rectangle will automatically be scrollable
Rectangle {
width: root.width
height: 99999
}
}
(source)
This provides scrollbars and allows scrolling with the mouse wheel, two-finger-scrolling with the touchpad and flicking ("click and throw") scrolling as we're used to from touchscreen devices.
However, it does not allow scrolling with any keyboard keys (Arrow Up / Down, Page Up / Down). How can I make that possible? The usual approach of doing Keys.onUpPressed: scrollBar.decrease() does not work because the ScrollablePage's scrollbar is not accessible as part of its public API.
Instructions
Use a Flickable to wrap the content items you put into your ScrollablePage. Then evaluate key press events in the Flickable and in response execute flick() to scroll the view. Example (combining examples from the Kirigami manual and from the Qt manual):
Kirigami.ScrollablePage {
id: root
Flickable {
focus: true
topMargin: 20; leftMargin: 20; bottomMargin: 20; rightMargin: 20
Keys.onUpPressed: flick(0, 800)
Keys.onDownPressed: flick(0, -800)
Rectangle {
width: root.width
height: 5000
}
}
}
Details and Explanation
While you can't access the scrollbar, you can access what the scrollbar uses to move the view: a Flickable instance. You just have to wrap it around the page's content. If you don't, ScrollablePage internally uses ScrollView to wrap your page's content in a Flickable anyway, but then you don't have a reference on it to execute flick().
Executing flick() does the same as when the user flicks the element, so the scrollbar position etc. will be updated alright.
If it still does not work, then (1) maybe you give too small pixel/second values to Flickable::flick() for scrolling to be visible or (2) maybe the initial Flickable::flickDeceleration values on your platform are messed up. These values are platform specific, so it can require some experimentation. On some platforms, setting them to zero during a flick() will help, while under Linux this is exactly the value preventing any scroll movement.
It is not necessary to enable ScrollablePage::keyboardNavigationEnabled for the above solution to work, since that is only for moving the currentItem of suitable content with the arrow keys (see below), and not for scrolling in general. It will even prevent ordinary scrolling in case your page content is an item view (ListView, GridView etc.).
Alternative solution for item views
If the content of your ScrollablePage is an item view (any QML object that has a currentItem property, such as ListView or GridView), then instead of wrapping that content in a Flickable just enable ScrollablePage::keyboardNavigationEnabled. It will allow you to move the currentItem with the Arrow Up and Arrow Down keys. That's what one usually wants for these views, even though it's not scrolling but rather keyboard navigation.

How to disable rendering in QML WebView?

I am currently building an application that makes use of QML WebView (import QtWebKit 3.0). The users need to resize the WebView very often (I am using a QML SplitView), however this leads to the UI to lag extremely whenever the app window is resized. Is there any way to prevent this?
Instead of changing the width and height properties change scale property of the WebView.
At beginning of the resize save initial values of width and height.
On resize don't change width and height. Instead set scale to newWidth divided by width at beginning of the resize.
When resize ends set new values of width and height to these properties and set scale to 1.
EDIT:
Since you don't have control of width and height properties you can replace WebView with Rectangle with color set to "transparent". Then you can place WebView on Rectangle and watch how width and height of Rectangle are changing.
Now two things.
If you don't know when resize starts and when ends use Timer with interval for example 100ms. Restart Timer and update scale every time width and height of Rectangle changes. When Timer is triggered set real width and height.
If ratio of width and height of Rectangle is not constant use QML object Scale. With it you can change xScale and yScale independently.

Resize mobile QML app

I'm working on a program to run Harmattan (N9) apps on Fremantle (N900). One of the problems is the resolution difference.
N900 has 800x480 screen and N9 854x480. Because of this part of the screen is cut off.
Can I fool (something) so that it thinks that the 800px screen contains 854px and paints all the elements (all the elements are painted as if 854px were availabe). I know that the shapes will be unnatural due to resizing one dimension, but it's better than a cut-off layout.
This has to be done without recompilation, as I can't access source code of every application for N9. I can't edit the qml files as they're built-in into qrc
Thanks in advance
marmistrz
If you code for different sizes of screens, you had better not use the raw values of screen dimensions. What you can do is saying that "this item with fill pw% of the width and ph% of the height". It will be automatically resized with the property binding. In your QML code, you can write something like this :
MyItem {
id: my_item
width: (pw / 100) * screen_width
height: (ph / 100) * screen_height
// ...
}

Resources