Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to purge QMainWindow's geometry tag in Qt Designer UI files

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>
like image 387
Mikhail Avatar asked Aug 01 '17 16:08

Mikhail


2 Answers

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.

like image 50
ekhumoro Avatar answered Sep 22 '22 10:09

ekhumoro


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)

like image 43
Felix Avatar answered Sep 20 '22 10:09

Felix