Why can't the button be set size and other styles?

Understanding widget parenting and layouts when combining custom widgets with Qt Designer
Heads up! You've already completed this tutorial.

I created a custom QPushButton subclass and set its size and stylesheet, but nothing happens — the button doesn't appear in my window. I'm using a UI built with Qt Designer. Why can't the button be set to a size and other styles?

If you've designed a window in Qt Designer and then tried to add a custom widget in your Python code, you may have run into a frustrating situation: the widget just doesn't show up, and none of your size or style settings seem to have any effect.

The reason comes down to how widgets are displayed in a Qt application. Let's walk through what's going wrong and how to fix it.

The problem: a widget without a home

Here's a simplified version of the code that causes this issue:

python
from PyQt6.QtWidgets import QApplication, QPushButton, QWidget
from PyQt6.QtCore import QSize
import sys


class MyButton(QPushButton):
    def __init__(self):
        super().__init__()
        self.setStyleSheet("background:green")
        self.setFixedSize(QSize(100, 20))


class Demo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(345, 225)
        self.btn = MyButton()
        self.btn.setFixedSize(QSize(100, 20))


if __name__ == "__main__":
    app = QApplication([])
    w = Demo()
    w.show()
    sys.exit(app.exec())

If you run this, you'll see an empty window. The MyButton exists in memory, but it has no connection to the Demo widget. In Qt, every widget needs to know where it belongs — either by being given a parent widget, or by being placed into a layout that is attached to a parent.

When you create MyButton() without passing a parent, Qt treats it as a top-level window of its own. It won't appear inside your Demo widget because Qt has no reason to put it there.

The fix: give the widget a parent or add it to a layout

There are two straightforward ways to make your custom button appear inside your window.

Pass the parent widget

You can pass self (the parent window) when creating the button:

python
self.btn = MyButton(parent=self)

You'll also need to update your MyButton.__init__ to accept and forward the parent:

python
class MyButton(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet("background:green")
        self.setFixedSize(QSize(100, 20))

This will make the button appear, but it will be positioned at the top-left corner of the window (position 0, 0) by default. You'd need to manually call self.btn.move(x, y) to position it, which is fragile and doesn't adapt well to window resizing.

Bring Your PyQt/PySide Application to Market — Specialized launch support for scientific and engineering software built using Python & Qt.

Find out More

Using Layouts

The better approach is to use a layout. Layouts automatically manage the position and size of child widgets, and they handle resizing gracefully.

python
from PyQt6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout
from PyQt6.QtCore import QSize
import sys


class MyButton(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet("background:green")
        self.setFixedSize(QSize(100, 20))


class Demo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(345, 225)

        self.btn = MyButton()

        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        self.setLayout(layout)


if __name__ == "__main__":
    app = QApplication([])
    w = Demo()
    w.show()
    sys.exit(app.exec())

When you add a widget to a layout, the layout takes care of parenting automatically. The button now appears inside the window, with its green background and fixed size intact.

What about Qt Designer code?

When you use Qt Designer and export a .ui file (or convert it to Python code), the generated setupUi method creates widgets and adds them to layouts for you. In the original question, setupUi creates a QPushButton called self.pushButton — that's the button you see in the window.

The custom MyButton created afterward in __init__ is a completely separate widget. It has no relationship to the button that Qt Designer placed, and since it was never added to the window's layout or given the window as a parent, it simply doesn't appear.

Here's the original setupUi code adapted for PyQt6, with the bug highlighted:

python
from PyQt6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout
from PyQt6.QtCore import QSize, QRect, QMetaObject
import sys


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(345, 225)
        self.pushButton = QPushButton(Form)
        self.pushButton.setGeometry(QRect(20, 30, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setText("PushButt")
        QMetaObject.connectSlotsByName(Form)


class MyButton(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setStyleSheet("background:green")
        self.setFixedSize(QSize(100, 20))


class Demo(Ui_Form, QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        # This button is created but never added to the window!
        self.btn = MyButton()
        self.btn.setFixedSize(QSize(100, 20))


if __name__ == "__main__":
    app = QApplication([])
    w = Demo()
    w.show()
    sys.exit(app.exec())

The self.pushButton created by setupUi shows up fine because it's given Form (which is self, the window) as its parent. But self.btn = MyButton() creates a floating, parentless widget.

Fixing it with Qt Designer code

To add your custom button alongside the Designer-generated UI, you need to integrate it into the window. The cleanest way is to add a layout to your Designer form and then insert the custom widget into it from your Python code.

Here's a complete working example that places both the Designer button and the custom button into a layout:

python
from PyQt6.QtWidgets import (
    QApplication, QPushButton, QWidget, QVBoxLayout
)
from PyQt6.QtCore import QSize
import sys


class MyButton(QPushButton):
    def __init__(self, text="", parent=None):
        super().__init__(text, parent)
        self.setStyleSheet("background: green; color: white;")
        self.setFixedSize(QSize(100, 30))


class Demo(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Form")
        self.resize(345, 225)

        # The original button from the Designer form
        self.push_button = QPushButton("PushButt")

        # Your custom button, now part of the same window
        self.btn = MyButton("My Button")

        # A layout to hold both buttons
        layout = QVBoxLayout()
        layout.addWidget(self.push_button)
        layout.addWidget(self.btn)
        self.setLayout(layout)


if __name__ == "__main__":
    app = QApplication([])
    w = Demo()
    w.show()
    sys.exit(app.exec())

Both buttons now appear in the window. The MyButton instance respects its fixed size and green stylesheet because it's properly part of the widget hierarchy.

Using custom widgets directly in Qt Designer

If you want your custom widget class to appear inside Qt Designer itself — so you can drag and drop it like any other widget — you can use Qt Designer's widget promotion feature. This lets you tell Designer that a particular QPushButton on your form should actually be an instance of your MyButton class at runtime.

For a full walkthrough of this approach, see the tutorial on creating your own custom widgets.

Summary

When a widget doesn't respond to size or style changes, the most common cause is that it hasn't been added to the window. Always make sure your widgets are either:

  • Given a parent widget when created, or
  • Added to a layout that belongs to the parent window

Using layouts is the recommended approach, since they handle positioning and resizing automatically. And when working with Qt Designer, remember that the generated setupUi code creates its own widgets — any additional widgets you create in Python need to be explicitly added to the window's layout to appear.

The complete guide to packaging Python GUI applications with PyInstaller.
Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

Why can't the button be set size and other styles? was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.