<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Python GUIs - visibility</title><link href="https://www.pythonguis.com/" rel="alternate"/><link href="https://www.pythonguis.com/feeds/visibility.tag.atom.xml" rel="self"/><id>https://www.pythonguis.com/</id><updated>2020-08-02T09:00:00+00:00</updated><subtitle>Create GUI applications with Python and Qt</subtitle><entry><title>Show and hide widgets in PyQt6 — Understanding widget visibility and how parent-child relationships affect it</title><link href="https://www.pythonguis.com/faq/show-and-hide-widget/" rel="alternate"/><published>2020-08-02T09:00:00+00:00</published><updated>2020-08-02T09:00:00+00:00</updated><author><name>Martin Fitzpatrick</name></author><id>tag:www.pythonguis.com,2020-08-02:/faq/show-and-hide-widget/</id><summary type="html">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 &lt;em&gt;all&lt;/em&gt; its child widgets are invisible, or does hiding the parent hide everything automatically?</summary><content type="html">
            &lt;blockquote&gt;
&lt;p&gt;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 &lt;em&gt;all&lt;/em&gt; its child widgets are invisible, or does hiding the parent hide everything automatically?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Great question &amp;mdash; 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.&lt;/p&gt;
&lt;h2 id="widget-visibility-basics"&gt;Widget visibility basics&lt;/h2&gt;
&lt;p&gt;Every widget in PyQt6 has a &lt;code&gt;.setVisible()&lt;/code&gt; method, along with the convenience methods &lt;code&gt;.show()&lt;/code&gt; and &lt;code&gt;.hide()&lt;/code&gt;. These control whether a widget is drawn on screen:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;widget.show()             # Make visible
widget.hide()             # Make invisible
widget.setVisible(True)   # Same as .show()
widget.setVisible(False)  # Same as .hide()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You can also check a widget's current visibility state using &lt;code&gt;.isVisible()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="parent-child-visibility"&gt;Parent-child visibility&lt;/h2&gt;
&lt;p&gt;Here's where it gets interesting. Qt widgets exist in a parent-child tree. When you place a &lt;code&gt;QLabel&lt;/code&gt; inside a &lt;code&gt;QVBoxLayout&lt;/code&gt; on a &lt;code&gt;QWidget&lt;/code&gt;, that label is a child of the widget. This parent-child relationship affects visibility in two directions.&lt;/p&gt;
&lt;h3&gt;Hiding a parent hides all its children&lt;/h3&gt;
&lt;p&gt;When you hide a parent widget, &lt;strong&gt;all of its children are hidden too&lt;/strong&gt; &amp;mdash; automatically. You don't need to manually hide each child. Calling &lt;code&gt;.hide()&lt;/code&gt; on the parent is enough to make the entire subtree disappear from the screen:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;parent_widget.hide()  # All children disappear
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This makes sense when you think about it: if the container isn't being drawn, there's nowhere to draw the children.&lt;/p&gt;
&lt;h3&gt;Showing a parent respects each child's own visibility&lt;/h3&gt;
&lt;p&gt;When you show a parent widget again, each child will reappear &lt;em&gt;only if that child's own visibility hasn't been explicitly set to &lt;code&gt;False&lt;/code&gt;&lt;/em&gt;. 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.&lt;/p&gt;
&lt;h3&gt;Children can't be visible if their parent is hidden&lt;/h3&gt;
&lt;p&gt;A child widget cannot be visible on screen if any of its ancestors are hidden. Even if you call &lt;code&gt;.show()&lt;/code&gt; on a child, it won't actually appear until its parent (and all ancestors up the tree) are also visible.&lt;/p&gt;
&lt;p&gt;This is what the Qt documentation means by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If an ancestor is not visible, the widget won't become visible until all its ancestors are shown.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="a-practical-example"&gt;A practical example&lt;/h2&gt;
&lt;p&gt;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 &amp;mdash; and you'll see that hiding the container hides everything inside it at once:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;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()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Run this and click the "Toggle Panel" button. You'll see the entire panel &amp;mdash; including all three child widgets &amp;mdash; appear and disappear together. You only need to call &lt;code&gt;.hide()&lt;/code&gt; on the parent &lt;code&gt;QWidget&lt;/code&gt;, and all its children go with it.&lt;/p&gt;
&lt;h2 id="using-setvisible-with-boolean-values"&gt;Using &lt;code&gt;.setVisible()&lt;/code&gt; with boolean values&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;.setVisible()&lt;/code&gt; method is especially handy when you want to tie visibility to a condition, since it accepts a boolean directly:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;self.panel.setVisible(not self.panel.isVisible())
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This single line replaces the &lt;code&gt;if&lt;/code&gt;/&lt;code&gt;else&lt;/code&gt; block in the toggle method above.&lt;/p&gt;
&lt;h2 id="hiding-individual-children"&gt;Hiding individual children&lt;/h2&gt;
&lt;p&gt;Sometimes you want to hide just one widget inside a container while keeping the rest visible. That works exactly as you'd expect:&lt;/p&gt;
&lt;div class="code-block"&gt;
&lt;span class="code-block-language code-block-python"&gt;python&lt;/span&gt;
&lt;pre&gt;&lt;code class="python"&gt;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()
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here we connect each checkbox's &lt;code&gt;toggled&lt;/code&gt; signal directly to the corresponding label's &lt;code&gt;.setVisible()&lt;/code&gt; method. Since &lt;code&gt;toggled&lt;/code&gt; emits a boolean and &lt;code&gt;.setVisible()&lt;/code&gt; accepts a boolean, they connect perfectly with no extra code needed.&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;Widget visibility in PyQt6 follows straightforward rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hiding a parent automatically hides all of its children&lt;/strong&gt;. You don't need to hide them individually.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Showing a parent reveals its children&lt;/strong&gt;, but only those that haven't been individually hidden.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A child can never be visible if any of its ancestors are hidden&lt;/strong&gt; &amp;mdash; calling &lt;code&gt;.show()&lt;/code&gt; on the child alone won't work until the ancestor is shown too.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;.show()&lt;/code&gt; and &lt;code&gt;.hide()&lt;/code&gt; for simple toggling, or &lt;code&gt;.setVisible(bool)&lt;/code&gt; when you want to set visibility based on a condition.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The original question asked whether a compound widget only becomes invisible when &lt;em&gt;all&lt;/em&gt; 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.&lt;/p&gt;
            &lt;p&gt;For an in-depth guide to building Python GUIs with PyQt6 see my book, &lt;a href="https://www.martinfitzpatrick.com/pyqt6-book/"&gt;Create GUI Applications with Python &amp; Qt6.&lt;/a&gt;&lt;/p&gt;
            </content><category term="pyqt6"/><category term="python"/><category term="widgets"/><category term="visibility"/><category term="qt"/><category term="qt6"/></entry></feed>