Show and hide widgets in PyQt6

Understanding widget visibility and how parent-child relationships affect it
Heads up! You've already completed this tutorial.

How does widget visibility work in PyQt6? When I hide a parent widget, all the child widgets also get hidden. Does a compound widget only become invisible when all its child widgets are invisible, or does hiding the parent hide everything automatically?

Great question — widget visibility in Qt can seem a little confusing at first, because it works differently depending on whether you're hiding a parent or hiding individual children. Let's walk through how it actually works.

Widget visibility basics

Every widget in PyQt6 has a .setVisible() method, along with the convenience methods .show() and .hide(). These control whether a widget is drawn on screen:

python
widget.show()             # Make visible
widget.hide()             # Make invisible
widget.setVisible(True)   # Same as .show()
widget.setVisible(False)  # Same as .hide()

You can also check a widget's current visibility state using .isVisible().

Parent-child visibility

Here's where it gets interesting. Qt widgets exist in a parent-child tree. When you place a QLabel inside a QVBoxLayout on a QWidget, that label is a child of the widget. This parent-child relationship affects visibility in two directions.

Hiding a parent hides all its children

When you hide a parent widget, all of its children are hidden too — automatically. You don't need to manually hide each child. Calling .hide() on the parent is enough to make the entire subtree disappear from the screen:

python
parent_widget.hide()  # All children disappear

This makes sense when you think about it: if the container isn't being drawn, there's nowhere to draw the children.

Showing a parent respects each child's own visibility

When you show a parent widget again, each child will reappear only if that child's own visibility hasn't been explicitly set to False. In other words, Qt remembers whether you individually hid a child. If you hid a specific child before hiding the parent, that child will stay hidden when the parent comes back.

Children can't be visible if their parent is hidden

A child widget cannot be visible on screen if any of its ancestors are hidden. Even if you call .show() on a child, it won't actually appear until its parent (and all ancestors up the tree) are also visible.

PyQt/PySide Office Hours 1:1 with Martin Fitzpatrick — Save yourself time and frustration. Get one on one help with your projects. Bring issues, bugs and questions about usability to architecture and maintainability, and leave with solutions.

60 mins ($195)

This is what the Qt documentation means by:

If an ancestor is not visible, the widget won't become visible until all its ancestors are shown.

A practical example

Let's put this together with a working example. We'll create a window with a button that toggles the visibility of a container widget. That container holds several child widgets — and you'll see that hiding the container hides everything inside it at once:

python
import sys

from PyQt6.QtWidgets import (
    QApplication,
    QLabel,
    QMainWindow,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Show and Hide Widgets")

        # Main layout
        main_layout = QVBoxLayout()

        # Toggle button
        self.toggle_button = QPushButton("Toggle Panel")
        self.toggle_button.clicked.connect(self.toggle_panel)
        main_layout.addWidget(self.toggle_button)

        # A container widget with children
        self.panel = QWidget()
        panel_layout = QVBoxLayout()
        panel_layout.addWidget(QLabel("Child Label 1"))
        panel_layout.addWidget(QLabel("Child Label 2"))
        panel_layout.addWidget(QPushButton("Child Button"))
        self.panel.setLayout(panel_layout)

        main_layout.addWidget(self.panel)

        # Central widget
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)

    def toggle_panel(self):
        if self.panel.isVisible():
            self.panel.hide()
        else:
            self.panel.show()

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Run this and click the "Toggle Panel" button. You'll see the entire panel — including all three child widgets — appear and disappear together. You only need to call .hide() on the parent QWidget, and all its children go with it.

Using .setVisible() with boolean values

The .setVisible() method is especially handy when you want to tie visibility to a condition, since it accepts a boolean directly:

python
self.panel.setVisible(not self.panel.isVisible())

This single line replaces the if/else block in the toggle method above.

Hiding individual children

Sometimes you want to hide just one widget inside a container while keeping the rest visible. That works exactly as you'd expect:

python
import sys

from PyQt6.QtWidgets import (
    QApplication,
    QCheckBox,
    QLabel,
    QMainWindow,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Hide Individual Children")

        layout = QVBoxLayout()

        self.label_a = QLabel("Label A")
        self.label_b = QLabel("Label B")
        self.label_c = QLabel("Label C")

        layout.addWidget(self.label_a)
        layout.addWidget(self.label_b)
        layout.addWidget(self.label_c)

        # Checkboxes to toggle each label
        self.check_a = QCheckBox("Show Label A")
        self.check_a.setChecked(True)
        self.check_a.toggled.connect(self.label_a.setVisible)

        self.check_b = QCheckBox("Show Label B")
        self.check_b.setChecked(True)
        self.check_b.toggled.connect(self.label_b.setVisible)

        self.check_c = QCheckBox("Show Label C")
        self.check_c.setChecked(True)
        self.check_c.toggled.connect(self.label_c.setVisible)

        layout.addWidget(self.check_a)
        layout.addWidget(self.check_b)
        layout.addWidget(self.check_c)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Here we connect each checkbox's toggled signal directly to the corresponding label's .setVisible() method. Since toggled emits a boolean and .setVisible() accepts a boolean, they connect perfectly with no extra code needed.

Summary

Widget visibility in PyQt6 follows straightforward rules:

  • Hiding a parent automatically hides all of its children. You don't need to hide them individually.
  • Showing a parent reveals its children, but only those that haven't been individually hidden.
  • A child can never be visible if any of its ancestors are hidden — calling .show() on the child alone won't work until the ancestor is shown too.
  • Use .show() and .hide() for simple toggling, or .setVisible(bool) when you want to set visibility based on a condition.

The original question asked whether a compound widget only becomes invisible when all its children are invisible. It's actually the other way around: hiding the parent makes the entire group invisible in one step, regardless of the children's individual states. The children's own visibility settings are remembered and restored when the parent becomes visible again.

PyQt/PySide Development Services — Stuck in development hell? I'll help you get your project focused, finished and released. Benefit from years of practical experience releasing software with Python.

Find out More

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

Show and hide widgets in PyQt6 was written by Martin Fitzpatrick with contributions from Leo Well.

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.