Search code examples
pythonpyqt5pyuic

Formatting issue when converting from .ui file to .py file in windows


When converting a .ui file to .py using: pyuic5 code.ui -o code.py, Upon running the .py file in JetBrains PyCharm Community Edition, the GUI window changes from what is previewed in Qt Designer and clips out the text of the push button as seen in the attached images.

I have included: self.pushButton.adjustSize() in line 41 but it does not seem to help.

I have attached the converted code and screenshots of the issue. I am currently running Windows 10.

Does anyone know how to avoid this?

py File:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\Designer_ui_code.ui'
#
# Created by: PyQt5 UI code generator 5.9
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(263, 171)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(90, 30, 77, 44))
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.layoutWidget)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.pushButton = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 263, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.pushButton.clicked.connect(self.label.clear)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.pushButton.adjustSize()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "A Label"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

ui File:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>412</width>
    <height>213</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QWidget" name="layoutWidget">
    <property name="geometry">
     <rect>
      <x>150</x>
      <y>50</y>
      <width>77</width>
      <height>44</height>
     </rect>
    </property>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QLabel" name="label">
       <property name="text">
        <string>TextLabel</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="pushButton">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
         <horstretch>1</horstretch>
         <verstretch>1</verstretch>
        </sizepolicy>
       </property>
       <property name="text">
        <string>PushButton</string>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>412</width>
     <height>18</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>label</receiver>
   <slot>clear()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>181</x>
     <y>103</y>
    </hint>
    <hint type="destinationlabel">
     <x>181</x>
     <y>77</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

Picture of window ran as a .py file

Screenshot of window previewed in Qt Designer

Edit: Added UI File


Solution

  • While Designer tries to show you a preview of the windows you created, there's no guarantee that what you'll see is exactly what will actually appear on the final program.

    First of all, besides obvious OS differencies, each platform has different styles that can be used (you can try some of them from the menu "Form" > "Preview in"). Other than that, Designer also applies some default (content) margins and font sizes to its widget that depend on various aspects, and may not reflect the final result, especially when using screens with HiDPI (or any specific DPI setting that's not the default).

    That said, the most important aspect here is that you are using a fixed geometry for the internal layout, which constraints the available space for the widgets.
    For some reason (possibly, some default environment settings set by PyCharm), the font size or the DPI are different from what they were in Designer, and since the resulting font is bigger than the available space for the widgets, their contents are cropped.

    The simplest solution is to not use fixed geometries, but apply a layout for the whole window. If you need some margins, you could add horizontal and vertical spacings from Designer.

    Keep in mind that using fixed geometries is always discouraged. Even if you get to a point where your program seems to be shown as you wanted, there's no guarantee that it will do the same on somebody else's computer: the most common case is where people changes the system default font (family and/or size), which happens more often than you'd think.

    Finally, why adjustSize didn't work?

    1. You called while the interface was still being created; at that point, it has not been "polished" yet (meaning that things like font sizes and margins have not been checked against the size the widget would prefer to be shown). Doing that while the UI is in that point is almost useless.
    2. Even if you call it after that (usually some time after calling show()), that function only tells the widget to adjust its size to fit it contents; while it teoretically means that it will try to expand itself, its parent doesn't allow it (the fixed geometry, remember?), and you'll end up with a partially viewable widget anyway.