Resize mobile QML app - qt

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

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.

Qt widget app - different layouts based on orientation

I have a qt widgets app that needs to rearrange itself if the screen orientation is portrait vs landscape or if the window is resized to be taller than it is wide. The app has all the same widgets and functionality in both modes, just laid out differently.
I realize you can move widgets around in layouts at runtime based on resize events, but this alone is not ideal because you can't see what it will look like beforehand in the designer. I also found this example in the archives: https://doc.qt.io/archives/qt-4.8/qt-widgets-orientation-example.html where they have two separate UIs can choose which to show when the screen resizes, but in this case every single UI change, slot connection, etc. must be done to both UIs which is also extremely cumbersome, not scalable, and error prone.
Is there a clean way to handle this situation? Or at least visualize both modes without running the app? Qt version is 5.12+
You could - theoretically - create 2 files or objects. One would be myLandscapeWidget and other myPortraitWidget. Surround them with a Loader and could do a
Loader {
id: myLoader
anchors.fill: parent
sourceComponent: Screen.orientation === Qt.LandscapeOrientation ? land : port
Component {
id: land
myLandscapeWidget {
width: 500
height: 100
}
}
Component {
id: port
myPortraitWidget {
width: 100
height: 500
visible: Screen.orientation !== Qt.LandscapeOrientation
}
}
}
Well, atleast thats the gist of it...
Some links:
Loader , Screen

Why is responsive images so off (my) reality?

There is one simple task I want to achieve.
I have an image in a variable width container.
The container can have a width of 300, 400, 700, or 900 pixels. This is done by the means of media-queries
The image should take up all the width of that container. So it will be also 300, 400, 700, or 900 pixels wide.
The image should have different sources for all that width values. So I can serve smaller images on mobile phones.
I thought that this could be done with the srcset attribute of the img element, maybe under help of the sizes attribute. width something like this
<img src="http://dummyimage.com/300x200/abc/000"
alt="dummy"
srcset="
http://dummyimage.com/900x200/abc/000 900w,
http://dummyimage.com/700x200/abc/000 700w,
http://dummyimage.com/400x200/abc/000 400w,
http://dummyimage.com/300x200/abc/000 300w
"
/>
But it's not working in that way, because the browser chooses the image in proportion to the width of the display port and not to that of the image itself.
Example with use of picturefill polyfill from http://scottjehl.github.io/picturefill/: http://codepen.io/HerrSerker/pen/itBJy . This does not work, because it will take the one image that is the next size.
I could of course take that into account and change my srcset to this
srcset="
http://dummyimage.com/900x200/abc/000 999999w,
http://dummyimage.com/700x200/abc/000 900w,
http://dummyimage.com/400x200/abc/000 700w,
http://dummyimage.com/300x200/abc/000 400w
"
This will work on the desktop, but fails on retina displays, because the device pixel ratio is taken into account here, but in a different way than with the media queries. And it is not useful, because the image should know about the width of the viewport and of the same width and that at compile time? No way. Image I use the image in a grid system. The image has different widthes if I'm in a 3 column grid on desktop devices and a 1 column grid on smart phones. That should not be in the responsibility of the image to calulate the ratio of width and viewport-width.
I did not have any luck with the sizes attribute as well (no example here). The reason is tha same as above. In the sizes attibute I say which amount of the viewport width should my image be wide according to media queries. This is so off. How should the image know?
So I came around with this solution. I setup a data-srcset attribute with the same syntax as the srcset attribute itself, but with a custom JavaScript programming. Example here: http://codepen.io/HerrSerker/pen/tCqJI
jQuery(function($){
var reg = /[\s\r\n]*(.*?)[\s\r\n]+([^\s\r\n]+w)[\s\r\n]*(,|$)/g;
var regw = /(.*)w/;
var sets, $set, set, myMatch, i, w, that, last;
var checkData = function() {
$('img[data-srcset]').each(function() {
that = $(this);
$set = that.data('srcset');
sets = [];
while(myMatch = reg.exec($set)) {
set = {};
set.src = myMatch[1];
set.w = (myMatch[2].match(regw))[1];
sets[set.w] = set;
}
w = that.width();
last = 0;
for (i in sets) {
last = i;
if (w <= i) {
that.attr('src', sets[i].src);
return;
}
}
that.attr('src', sets[last].src);
});
};
checkData();
$(window).on('resize', checkData);
});
This works, but it feels wrong. But maybe not, as the specifications says for responsive images to behave just in the way that it does. But I feel that it's the wrong way. 90 % of use cases for responsive images won't work with the spec.
So am I wrong? Didn't I use the srcset in the defined way? Did I understand the spec incorrectly? And do the W3C and Responsive Images Community Group think in such a way apart from reality?
Are the smaller images scaled down versions of the bigger image? Or are they cropped (art direction)? If the latter, you should use picture and source media.
The reason the browser only uses the viewport for deciding which image to download is that it's the only thing that is available when the browser wants to download an image. The CSS (probably) isn't downloaded yet. So if you use srcset+sizes, you have to repeat the breakpoints and image widths in sizes.
This question seems like a duplicate of Responsive full width image banner with fixed height using srcset
Like zcorpan said, what you are trying to do falls under the "art-direction" use-case (since the different images have different proportions), so you should use the <picture> element, rather than srcset. See the other question's answers for a syntax example.

How to set the desired size of a QMainWindow with QScrollArea?

I am working on a project where I have to display a pretty large (vertically) main Widget.
In the initial Version of my GUI it was just added as the central Widget of a QMainWindow, which caused the Problem that on small screen resolutions the controls on the Bottom of the Widget are unreachable.
To solve this i wrapped a QScrollArea around the main Widget, but now the main window is always relatively small even if it doesn't have to.
What do i need to change so the Main Windows (vertical) size is large enough to show all the contents unless it would be too large for the screen resolution? Also I don't want it to be stretched, so simply always using the whole vertical screen resolution is not an option. Ideally the size should be fixed to the size needed by the contents (w/o the scroll area) and only smaller where needed.
Overriding the sizeHint method did only resulted in a small enlargement of the Window and setting the minimal height brings me back to the beginning where some of the controls are not assessable on small resolutions.
Since i am new to QT I am actually out of ideas how to google the solution because most Solutions I can find are about sizing components inside a Window and not the Window itself.
By default a QScrollArea will not attempt to expand to fit its contents. In order to do this you will need to re-implement QScrollArea's sizeHint() to return the size of QScrollArea's child widgets.
In your question it sounds like you were trying to re-implement MainWindow's sizeHint? re-implementing sizeHint on the top-level window will have no effect as sizeHint designed for use with widgets inside layouts.

Check if control is on screen

How do I check if a control/DisplayObject is on screen? This means it is displayed on screen so no scrolling needs to be done.
Example: I have several controls on a form. The size of the form exceeds the screen length/width. As a result I need scrollbars. How do I check if a control is on screen?
This is a less elegant solution, but if no one else answers, you can try to do this:
Check X and Y (or just Y if you are interested in height) of the component you want to verify is on-screen or off-screen.
Then compare that to the total height of the application or container of the component.

Resources