Search code examples
layoutpyqtpyqt4qt-designerpyuic

pyuic4 generates wrong layout?


pyuic4 seems to generate a wrong layout based on a .ui file from Qt Designer. The UI file is here:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>348</width>
    <height>267</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_2">
   <item>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item alignment="Qt::AlignTop">
      <widget class="QLabel" name="label">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="maximumSize">
        <size>
         <width>16777215</width>
         <height>25</height>
        </size>
       </property>
       <property name="text">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt;&quot;&gt;Some Text&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
      </widget>
     </item>
     <item alignment="Qt::AlignTop">
      <widget class="Line" name="line_2">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
     </item>
     <item alignment="Qt::AlignBottom">
      <widget class="Line" name="line">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item alignment="Qt::AlignBottom">
        <widget class="QPushButton" name="btn_customize">
         <property name="text">
          <string>Customize</string>
         </property>
        </widget>
       </item>
       <item alignment="Qt::AlignBottom">
        <widget class="QPushButton" name="btn_done">
         <property name="text">
          <string>OK</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

In this layout, I'm trying to align a pair of buttons with the bottom of the dialog window and some text with the top. Running pyuic4 test.ui --preview shows all objects aligned to the center horizontally, instead of to the top and bottom (and displaying this dialog from the actual python program shows the same results). By comparison, pyuic5 test.ui --preview seems to be more along the lines of what I wanted to get.

If it helps, my version of pyuic4 is 4.11.4 and I'm on Ubuntu 16.04.

Any ideas? Am I doing something wrong? Or is there perhaps a newer pyuic4 out there?


Solution

  • There was bug in pyuic that affected the handling of alignment in layouts. This was fixed in PyQt-5.5, which was released on the 17th July 2015. However, PyQt-4.11.4 (which is the current version) was released on the 11th June 2015 - so the fix has not been included, yet. The current development snapshot for PyQt-4.12 does includes the fix, though.

    But I don't think this will really fix the issue you have. What you need to do instead is use expanding spacers. Here's how to do this using your example ui file:

    1. Click on the horizontal button layout, and then click Break Layout (this will remove all the current layouts).
    2. Ctrl+click the two buttons, and then click Layout Horizontally.
    3. Click on the Dialog, and then click Layout Vertically.
    4. Drag and drop a Vertical Spacer between the two Line widgets

    Giving you this:

    screenshot

    If you want to have some other widgets in the central area, you may need to add expanding vertical spacers above and/or below them to get the same results. Then again, if you put something like a text-box or list-widget in there, it should automatically expand to fill the available space - in which case, there wouldn't be any need for any spacers (or layout alignments).