Search code examples
pythonpyside2

Doesn't show window correctly compared to QtDesigner's window


I'm creating a GUI application using PyQt5, I made the UI using QtDesigner and ended up with this result:

QtDesigner Preview

But this issue is that when I launch my application using Python, following the screen size I'm using, the application is not showing properly: on my laptop (from which I took the QtDesigner screenshot above), here is the result:

Python view Cropped side bar

(The white part was just to make it more visible that the rectangle is not properly displayed)

As you can see, the left side bar is not showing properly on my laptop, but on a bigger screen, it shows perfectly so I assume that the size of the screen is the error factor but I don't see how I could fix it. Is there any options I have to make sure to use in order to not have the sizes issues?

Here is the code you can use to have a minimal reproducible example:

The code generated from QtDesigner is the following:

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

################################################################################
## Form generated from reading UI file 'main_mreZokVTK.ui'
##
## Created by: Qt User Interface Compiler version 5.14.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
    QRect, QSize, QUrl, Qt)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
    QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap,
    QRadialGradient)
from PySide2.QtWidgets import *


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(1200, 800)
        MainWindow.setMinimumSize(QSize(1200, 800))
        MainWindow.setMaximumSize(QSize(1200, 800))
        font = QFont()
        font.setPointSize(8)
        MainWindow.setFont(font)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(10, 10, 10, 10)
        self.drop_shadow_frame = QFrame(self.centralwidget)
        self.drop_shadow_frame.setObjectName(u"drop_shadow_frame")
        self.drop_shadow_frame.setEnabled(True)
        font1 = QFont()
        font1.setPointSize(2)
        font1.setBold(False)
        font1.setWeight(50)
        self.drop_shadow_frame.setFont(font1)
        self.drop_shadow_frame.setStyleSheet(u"background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(13, 13, 13, 255), stop:0.972851 rgba(103, 103, 103, 255));\n"
"border-radius: 10px\n"
"")
        self.drop_shadow_frame.setFrameShape(QFrame.NoFrame)
        self.drop_shadow_frame.setFrameShadow(QFrame.Raised)
        self.lateral_bar = QFrame(self.drop_shadow_frame)
        self.lateral_bar.setObjectName(u"lateral_bar")
        self.lateral_bar.setGeometry(QRect(0, 0, 90, 781))
        self.lateral_bar.setMinimumSize(QSize(90, 781))
        self.lateral_bar.setMaximumSize(QSize(90, 781))
        self.lateral_bar.setStyleSheet(u"background-color:rgb(20, 20, 20);\n"
"background-color:#000000")
        self.lateral_bar.setFrameShape(QFrame.NoFrame)
        self.lateral_bar.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.lateral_bar)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.fonctions = QFrame(self.lateral_bar)
        self.fonctions.setObjectName(u"fonctions")
        self.fonctions.setMinimumSize(QSize(90, 691))
        self.fonctions.setMaximumSize(QSize(90, 691))
        self.fonctions.setFrameShape(QFrame.StyledPanel)
        self.fonctions.setFrameShadow(QFrame.Raised)
        self.verticalLayout_4 = QVBoxLayout(self.fonctions)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
        self.Raffles = QFrame(self.fonctions)
        self.Raffles.setObjectName(u"Raffles")
        self.Raffles.setFrameShape(QFrame.StyledPanel)
        self.Raffles.setFrameShadow(QFrame.Raised)
        self.btn_raffles = QPushButton(self.Raffles)
        self.btn_raffles.setObjectName(u"btn_raffles")
        self.btn_raffles.setGeometry(QRect(0, 0, 70, 163))
        self.btn_raffles.setMinimumSize(QSize(0, 0))
        self.btn_raffles.setMaximumSize(QSize(1000, 8000))
        font2 = QFont()
        font2.setFamily(u"MS Sans Serif")
        font2.setPointSize(1)
        self.btn_raffles.setFont(font2)
        self.btn_raffles.setLayoutDirection(Qt.LeftToRight)
        self.btn_raffles.setStyleSheet(u"QPushButton {\n"
"   border-radius:8px;\n"
"   background-color:none;\n"
"   border:2px solid rgb(45, 45, 45);\n"
"   \n"
"}\n"
"\n"
"QPushButton:hover {\n"
"   background-color:rgb(20, 20, 20);\n"
"   border:2px solid rgb(255, 255, 255)\n"
"}\n"
"")
        self.btn_raffles.setIconSize(QSize(64, 64))

        self.verticalLayout_4.addWidget(self.Raffles)


        self.verticalLayout_2.addWidget(self.fonctions)


        self.verticalLayout.addWidget(self.drop_shadow_frame)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.btn_raffles.setText("")
    # retranslateUi

And the code used to display the application is the following :

from PySide2 import QtCore
from PySide2.QtCore import (QTime, Qt)
from PySide2.QtGui import (QPixmap)
from PySide2.QtWidgets import *
from PyQt5.QtCore import QThreadPool, QRunnable, pyqtSlot, pyqtSignal, QTimer
import sys
import PyQt5
from ui_main_mre import Ui_MainWindow



class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)



app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

Solution

  • The main problem is that you're adding buttons to a widget (the QFrames) and without any layout set there. Using fixed geometries is almost never a good idea, and doing that in an UI that has other layout managers is almost always a very bad idea.
    Remember, what you see on your screen is almost never what others see in theirs; also, Designer doesn't always show in its preview what the actual result will be. In your specific case, the problem is that when your code loads the ui, the buttons are actually a bit shifted, so their contents are partially hidden because of their parent size (a child widget cannot draw outside the parent's rect).

    So, first of all, set a layout for all the QFrames that contain a button (and to any other widget that still has no layout), if your issue is ensuring that the buttons occupy the whole space available for their container, then set their horizontal and, most importantly, vertical size policy to Preferred (Qt buttons by default don't expand vertically).

    Then, there are other issues with your implementation:

    • the main widgets inside the central widget are "floating" (aka, fixed geometries), so set a layout for the central widget too;
    • remove all size constraints of buttons, as they're unnecessary;
    • avoid generic stylesheets, especially if set on parents; using selectors is always better, otherwise you might face unexpected behavior (especially from advanced/custom widgets);
    • check that minimum/maximum sizes are consistent (the button icons have minimum sizes bigger than their maximum);
    • be aware that Qt uses default layout margins and spacings depending on the current OS and style in use, so you must be careful with special widgets for which those aspects are important (the title bar, in your example); when in doubt, explicitly set those values in the layout properties (even if you're fine with the values set as default) and remember that every form in Designer can have default values for layouts from the "Form > Form settings" dialog (they are not visually applied in Designer, but they're respected when loaded from code);