6

Qt Designer adds a geometry tag that contains the widget's default size in absolute units (pixels).

This is really annoying because if you edit a ui file on a 4k monitor all of your uis will (by default) display with massive white space on a lower DPI system.

If I manually delete this tag, my windows have the expected size on first-show, but manually editing every ui file each time I open them in Qt Designer feels wrong.

I'm using Qt 5.9.

What's the paradigmatic way to prevent Qt Designer from adding this XML tag?

In example.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Example</class>
 <widget class="QMainWindow" name="Example">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>970</width>
    <height>1371</height>
   </rect>
  </property>
cbuchart
  • 10,847
  • 9
  • 53
  • 93
Mikhail
  • 7,749
  • 11
  • 62
  • 136
  • To "normalize" your UI on 4K monitor you can do: Simply put this before QApplication app object initialized: `QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication app(argc, argv);` I could have put that in form of the answer but the question is more about Designer? – Alexander V Aug 01 '17 at 17:44
  • Also: https://stackoverflow.com/questions/39823918/how-to-approach-development-of-new-qt-5-7-high-dpi-per-monitor-dpi-aware-applic/39824445#39824445 – Alexander V Aug 01 '17 at 17:49
  • @AlexanderVX Yeah, that's different. The problem is that Qt Designer sets size hints that are specific to the DPI/resolution of the developer's machine. – Mikhail Aug 01 '17 at 20:01
  • Why not to try smth like `mainwindow.setGeometry(screen.width() / 4, screen.height() / 4, screen.width() / 2, screen.height() / 2);` // so you will ensure it is proportional to the screen. And you can detect what screen it is on. – Alexander V Aug 01 '17 at 20:20
  • @AlexanderVX On one hand that is not a bad idea, on the other hand the layout is "perfect' when I manually delete the line from the `ui` file. – Mikhail Aug 01 '17 at 20:22
  • I guess nested layouts may help so that you avoid fixed things. – Alexander V Aug 01 '17 at 20:27
  • You simply need to use layouts. – vahancho Aug 02 '17 at 07:30

3 Answers3

6

I am able to remove the geometry tags in Qt Designer like this:

  1. Open a new Main Window form
  2. Select geometry in the Property Editor
  3. Click the red arrow on the right

This will automatically resize the form - but manually resizing it won't reinstate the geometry tag. However, if the form has a menu-bar, it will also add a geometry tag for that. So select menubar in the Object Inspector and then repeat steps 2 and 3 above. After doing that, I get this output:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget"/>
  <widget class="QMenuBar" name="menubar"/>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

And after adding other widgets/menus/layouts and resizing the form, the geometry tags never reappear. This was all tested using Qt Designer 5.10.1 on Linux.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Yeah. This looks like the most reliable way. Seems that all children need to be "reset" to effectively loose those tags. – Mikhail May 17 '18 at 00:24
1

Assuming you are using qmake for your project:

One possible solution would be to create an intermediate "compiler" that first transforms the ui file to remove the geometry tag and that passes it to uic - this way you can at least automate the process of removing the geometry tags.

The code for the PRO-file would add a new compiler like this:

uiungeom_c.name = fix ui of ${QMAKE_FILE_IN}
uiungeom_c.input = RAW_FORMS
uiungeom_c.variable_out = FORMS
uiungeom_c.commands = /path/to/<some_command> ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
uiungeom_c.output = ./.uifix/${QMAKE_FILE_BASE}.ui
uiungeom_c.CONFIG += target_predeps
QMAKE_EXTRA_COMPILERS += uiungeom_c

And change the FORMS in your pro file to RAW_FORMS, i.e.

RAW_FORMS += mainwindow.ui #...

This will run the <some_command> on all your ui-files and generate a copy of them without the geometry in your build folder in a subfolder. Those generated ui files are automatically passed to the FORMS variable and thus are now passed on to uic to create the header.


The tricky part here is the <some_command> - You would have to create some kind of script (bash, batch, python, XSLT-Transformation, ... - whatever you prefer) that takes the original xml file as input and removes the tag. XSLT-Transformations are propably the most elegant and reliable way, but also the most complicated - you can learn more about them at W3schools, but I would propably just use python, as it propably leads the the smallest and easiest to understand script.

(If you would like to see a basic sample in python that could do the job, I can fiddle one out later the day - just ask for it as a comment)

Felix
  • 6,885
  • 1
  • 29
  • 54
1

I don't have a solution to prevent Designer from writing this, I often find it simpler to just revert by code what has been done.

In this case I would suggest adding a call to setSize(sizeHint()) at the end of the constructor of your main window.

Aurélien Gâteau
  • 4,010
  • 3
  • 25
  • 30