Qt Designer adds excess 1 pixel spacing
I'm working on application for embedded and we have 256x64 grayscale screen. Qt 5.3 perfectly renders on that screen with -platform linuxfb option. Obviously, we save every pixel of space, so I faced with trouble: Qt Designer adds excess 1 pixel spacing for every layout element deeper in hierarchy. So they accumulate for the most deep widgets. More precisely, for some reason child element of layout components gets coordinates (1,1) relative to parent. So, it's true for every widget except for root widget. Picture below demonstrates accumulated spacings (thin and thick red lines), and (1,1) coordinates of the very first child widget.
I believe it's Qt behavior itself, not just Qt Designer issue (not tested yet). But I can't work further even if it's shown in Designer only: I need to have pixel-exact view while designing.
Of course, every spacing and margin of every component in form set to 0.
Manual coordinates assigning (from code) eliminates the problem of course, but I need to generate code by uic.
So, my question is: how to avoid such spacings? Fixing Qt core sources can be (hard) option too, since anyway we recompile Qt for the project.
Hi and welcome
Just tried here on win 7, qt 5,5
and it get 0,0 for a label inside a layout,
So I wonder if it needs to be nested even more deeply?
Do you have a sample that has this issue, i could try?
Hmm, I see this 1 pixel addition behaviour, too.
I think I disagree, with ekhumoro's reply as follows, that the behaviour is cosmetic only:
For us, it pushes our design beyond the target 960 x 640 resolution, by a few pixels in each direction.
And, means the user can resize window in the vertical direction, which I don't want them to be able to do.
Seems, the Designer, and the runtime behaviour, each get a bit confused, as to whether the y is 640, or a few pixels more, for example.
The issue seemingly started, when I started using 'Widget', in the Containers list, as a container for other widget that I wish to overlap.
I tried 'Frame' also, from the Containers list, but that didn't work, for overlapping.
I guess I'm happy to do some judicious -1's, if I knew quite where to add them.
Either constant -1's. Or subtracting -1 from some values.
I see that the post and link reply, are just over 2 years old.
So I wondered, any update information, on this ?
I'm using latest and greatest Qt, 5.10
Just to add, the issue is, that the designer won't actually let me set the overall app container QWidget maximumSize.Height, to 640.
It makes me keep it to 652.
Which means, when I start the app, it is 652 high.
I measured this with a screen cap util.
Then, I tried resizing the window vertically, and Windows allowed me, to anything between 640 and 652.
In other words, Windows let me drop the window height, from 652, to the 640 that the content of our app would suggest is possible.
Previously, before I started nesting as described, the window was always 640 deep, depth couldn't be resized in Windows, rock solid 640..
Set the spacing/margins to
0for the widget's layout?
Thanks - I'm afraid I already have all at 0
Could you upload a screen shot and any relevant code? In principle it should be enough to set the min size and max size to the same values, and set the size policy to
Fixedfor the top level widget to get a fixed-size window.
Hi kshegunov and all,
OK, I think I can see why.
I found out, by starting with a new .ui file, and creating the simplest possible layout:
Just the application-level widget, with all properties at defaults. Except, Width and Height both set to 200, in the geometry, minimumSize and maximumSize sections. And in the Layout section, the four margins changed from 9 to 0, and the spacing changed from 6 to 0. Just so I could understand more clearly, what's occurring.
Then, I dropped in two labels. Qt arranges them one above the other, not side by side. I guess Qt hardcodes that, for the application-level widget. I think I might have read that somewhere, in the Qt documentation online.
For each label, in the geometry section, Qt gives the label a Width of 200, and Height of 100, as you might expect. Qt greys the geometry section, indicating Qt is in control. Indeed as you would expect, as the labels are under layout control, of the application-level QWidget.
Next, I deleted the two labels, and instead dropped into the application-level widget, a Vertical Layout, with all properties at defaults, except, the spacing changed from 6 to 0.
Into the Vertical Layout, I dropped two labels, leaving each at defaults. Interestingly, for the first label, in the geometry section, greyed, Qt gives the label a Width of 198, and a Height of 99. And with an X,Y offset, from the top-left corner, of 1,1. Likewise the second label, but with an X,Y offset of 1,100 from the top-level corner.
So it looks like, a Qt Vertical Layout includes a 1 pixel inner box, within which, it lays out the content. In this case, two labels.
Is this 1 pixel inner box, documented, somewhere? Can it be changed to 0 pixels, aka disabled?
The problem comes, if the user presumed, as I had, that there is no such 1 pixel inner box. And that the labels can each have a width of 200, and height of 100. And for this first foray into Qt, want to set the labels to that size, and worry about creating a fully dynamically resizing UI, later !
And so, for each label, I set Width to 200 and Height to 100, in the minimumSize and maximumSize sections. In the geometry section, greyed, Qt accordingly changes the Width from 198 to 200, and Height from 99 to 100. Though leaves the X,Y values unchanged, indicating I think, that Qt has not fully 'acceded' to my user request.
Up in the application-level widget, in the maximumSize section, Qt I see, has changed Width and Height, from 200 to 202. In the minimumSize section, Width and Height remain at 200. And in Qt Creator, and at runtime, I can drag resize the application window, between 200 and 202.
In the application-level widget, in the sizePolicy section, changing Horizontal Policy and Vertical Policy, from Preferred, to Fixed, has no effect on this.
I would attach OnePixel.ui/js, exhibiting. But the forum errored saying I lack the privileges, as yet.
Instead, I'll copy-paste the .ui and .js file content, in a follow-on post. They are not too long.
You'll need our vendor tool to open the .js, which launches the .ui, via vendor specific command. The demo version of our tool can be freely downloaded from https://www.emtas.de/en/download/canopen-deviceexplorer-demo/. It times out and exits after 1 hour of use, can be restarted.
This then, fully replicates the behaviour that I see in my actual application, but in a simple example. Here's a design-time and run-time screenshot, although you can't really see much, from them.
The Qt Horizontal Layout likewise has 1 pixel inner box. And perhaps the Qt Grid Layout, and Qt Form Layout, do too, although I haven't checked.
So per my first post in this thread, it seems this 1 pixel inner box, is not just a design-time visual, in providing a red box at the perimeter of a Vertical Layout. But actually reduces the space allowed, for the layout content. Perhaps it would be better if the red box were drawn on top of the content rather than around..
Why this chasing of pixels? Because for this first foray into Qt, I sketched out my UI on squared graph paper, with each square 16 by 16 pixels. So all my UI elements, and spacing between, are multiples of 16, for a neat lined-up layout. I have a complex n-layer nesting, of vertical, horizontal and grid layouts, as necessary. Perhaps quite typical, of Qt applications. And it would be a real pain, to have to variously subtract 1 2 3 pixels etc, from the width and height of my UI elements, to reflect the layout nesting which they just so happened to lie within. A nesting that often changes, to accomodate some changing visual need.
OnePixel.ui ----------- <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>OnePixel</class> <widget class="QWidget" name="OnePixel"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>200</width> <height>200</height> </rect> </property> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>200</width> <height>200</height> </size> </property> <property name="maximumSize"> <size> <width>202</width> <height>202</height> </size> </property> <property name="windowTitle"> <string>OnePixel</string> </property> <property name="styleSheet"> <string notr="true"/> </property> <property name="sizeGripEnabled" stdset="0"> <bool>false</bool> </property> <layout class="QVBoxLayout"> <property name="spacing"> <number>0</number> </property> <property name="leftMargin"> <number>0</number> </property> <property name="topMargin"> <number>0</number> </property> <property name="rightMargin"> <number>0</number> </property> <property name="bottomMargin"> <number>0</number> </property> <item> <layout class="QVBoxLayout" name="verticalLayout"> <property name="spacing"> <number>0</number> </property> <item> <widget class="QLabel" name="label"> <property name="minimumSize"> <size> <width>200</width> <height>100</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>100</height> </size> </property> <property name="text"> <string>TextLabel</string> </property> </widget> </item> <item> <widget class="QLabel" name="label_2"> <property name="minimumSize"> <size> <width>200</width> <height>100</height> </size> </property> <property name="maximumSize"> <size> <width>200</width> <height>100</height> </size> </property> <property name="text"> <string>TextLabel</string> </property> </widget> </item> </layout> </item> </layout> </widget> <resources/> <connections/> </ui> OnePixel.js ----------- util.loadUIFile( "OnePixel.ui", "OnePixel" );
Ah, and within the vendor tool, to launch the .js, select PlugIns > CAN/CANopen Scripting, then Load, and nav to the .js
What is "application-level widget" ?
the centralWidget in mainwindow ?
I am probably using the wrong terminology completely - do correct me !
But by 'application-level widget', I mean the QWidget at the root of the hierarchy, within which all other widgets reside.
Namely, as defined starting on line 4, within the OnePixel.ui source, within my previous post.
We're not using C++, just Qt Script, with just a .js file, and a .ui file, source per previous post. Our vendor tool, which is a Windows .exe, has a dialogue as mentioned, for opening the .js file.
The vendor provides a number of custom script functions, one of which is called util.loadUIFile( ), for loading the .ui file. That function call be seen in OnePixel.js, in my previous post.
I guess behind the scenes, within the vendor Windows .exe source code, concepts of centralWidget and mainwindow, could well exist. But those are hidden from view for us, within their undisclosed source.
Are centralWidget and mainwindow, standard names and concepts, with regular full C++ Qt development ?
I really need to set aside some time, to study Qt properly. But rushing against a looming project deadline, too much still to do, not enough time, usual story ..
Oh, btw, if you were to download the demo version of the vendor tool, from the mentioned weblink, as below, then after installing, the PDF manual for the vendor-special functions, can be found in
C:\Program Files\emtas\CANopenDeviceExplorer\doc, filename cde_script_api.pdf.
Makes perfect sense now :)
-Are centralWidget and mainwindow, standard names and concepts, with regular full C++ Qt -
Well yes as a Default project has a default QWindow type that is a widget with docking
abilities. Supporting that it comes with a inner plain widget called centralWidget that is
the main client area of it and its often a gotch when starting up. ( you think u insert directly to the window)
Other than that, its just as normal to use any widget as window as its just a flag.
I read you post a few times and still not 100% sure what the issue is. :)
I read it like
I put in some layouts. I set min/max and when i run it i can make it 2 pixels more that
it should be allowed to ?
(even with fixed Policy)
Something like that ?
Things are actually a little bit weirder than I thought: Rather than Vertical Layout having a 1 pixel inner box, it's actually a more like a closing square bracket ] surrounding the content, 1 pixel top and bottom, 2 pixels on the right, and no pixels on the left.
I found that, by placing in the styleSheet property for the first label, background-color:blue;
And in the styleSheet property for the second label, background-color:green;
Everything else, left exactly per the OnePixel.ui source in my post.
Checkout the following runtime screengrabs. First is as-is. Second is with window dragged out, from 200 by 200, to 202 by 202. You can see the little white sliver of the ] enclosing the blue and green.
In both labels, in the QFrame section, I then tried changing lineWidth, from the default 1, to 0. No change to behaviour.
And then for both labels, in QLabel section, under alignment, I tried changing Horizontal from the default AlignLeft, to AlignHCenter. No change to behaviour, except for centering the TextLabel text, within the blue and green panel.
Lastly, for each label, in the QWidget section, I tried changing layoutDirection, from the default LeftToRight, to instead, RightToLeft. I've never had need to look at that property before. Lo-and-behold, the ] changes to a [, if you're with me.
So as follows, when dragged out from 200 by 200, to 202 by 202:
LayoutDirectionAuto is the same as LeftToRight.
Ah, my recent posts, crossed with your reply
Yes, your summary pretty much sums it up
Although in our actual application, it's 12 pixels more height than it should be, not 2 as in the example
And that's because of
Btw mrjj, does that Champion flash mean you're a Qt staffer ? Can we tell on this forum if someone is an Qt support person, who might have the ear of the Qt devs ?
Ok its actually 12 pixels that is a lot.
Nope, im just a private person. This is a user forum and paid support is
available via other channels. (as in , not so much staff here but they host/pay the server)
However, its possible to speak to the devs at
It's QFrame adding this extra pixel.
set frameShape to NoFrame