PyQt: Parenting a Widget

Veek M vek.m1234 at gmail.com
Tue Sep 26 01:48:31 EDT 2017


Summary: Could someone explain widget and dialog parenting - the text book is not making sense.
######################
I'm trying to understand widget parenting, from the book: Rapid GUI Programming, pg 118, and thereabouts - he says:

A. All PyQt classes that derive from QObjectand this includes all the widgets,
since QWidget is a QObject subclasscan have a “parent”.

B. PyQt automatically repar-
ents the widgets that are laid out. So although we did not give our widgets a
parent of self (the Form instance),when we call setLayout() the layout manager
gives ownership of the widgets and of itself to the form,and takes ownership of
any nested layouts itself. This means that none of the widgets that are laid out
is a top-level window, and all of them have parents, which is what we want. So
when the form is deleted, all its child widgets and layouts will be deleted with
-----------------------------
1. In A, does he mean, you are ALLOWED to set a parent on a widget ONLY because its Base Class is QObject? 

With DockWidgets, you have to explicitly parent them - why?

2. If I create two widgets and wdget.show() them, and app.exec_() - which one becomes the main-window and which one is the memory leak? I have not used a layout manager so, one widget with no parent auto-becomes the main-window (as per B), which would result in a leak with the other?

#!/usr/bin/python

import sys, os, re


from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = QApplication(sys.argv)

lbl = QLabel('<font size=11 color=red><b>Hello World</b></font>')
lbl.setWindowFlags(Qt.SplashScreen)
lbl.show()
txtBrw = QTextBrowser()
txtBrw.show()

QTimer.singleShot(3000, app.quit)
app.exec_()

3. QObject --> QWidget --> QDialog --> Form --> Form_Layout_Manager --> Nested_Layout_Manager

B, says that the layout manager parents the widgets under it and makes 'Form' the parent. If the Form Layout Manager is taking charge of the Nested Layout Manager, who is the parent of the widgets under the Nested Layout Mangaer? 

4. In the Chapter on 'Dialogs', I am trying to create a QMainWindow Style application with one label as the central widget and one button to invoke a dialog. It doesn't work and I get:

QWidget::setLayout: Attempting to set QLayout "" on Parent "", which already has a layout

I tried this link and it made no sense:
https://stackoverflow.com/questions/25450598/qlayout-attempting-to-add-qlayout-to-qwidget-which-already-has-a-layout

How does parenting work in PyQt? What is autoparented, what needs to be explicitly parented and who is scrwing whom? Additionally, why is my button, hiding?


#!/usr/bin/python

import sys, os, re


from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = QApplication(sys.argv)

class Dialog(QDialog):
    def __init__(self, parent = None):
        super(Dialog, self).__init__(parent)
        
        self.lbl = QLabel('Width: ')
        self.spn = QSpinBox()
        self.spn.setRange(0, 100)
        self.lbl.setBuddy(self.spn)
        
        self.chk = QCheckBox('&Beveled Edges')

        self.lbl_styl = QLabel('Style')
        self.lst = QComboBox()
        self.lst.addItems(['dashed', 'dotted', 'star'])
        self.lbl_styl.setBuddy(self.lst)
        
        self.ok_btn = QPushButton('&Ok')
        self.cncl_btn = QPushButton('&Cancel')

        self.layout([(self.lbl, 0, 0), (self.spn, 0, 1), (self.chk, 0, 2), 
                     (self.lbl_styl, 1, 0), (self.lst, 1, 1), 
                     (self.ok_btn, 2, 0), (self.cncl_btn, 2, 1)])

    def layout(self, wgts = []):
        self.lyt = QGridLayout()
        for wgt, row, col in wgts:
            self.lyt.addWidget(wgt, row, col)
            
        self.setLayout(self.lyt)
        

class Parent(QMainWindow):
    def __init__(self, parent = None):
        super(Parent, self).__init__(parent)
        
        lbl = QLabel('HELLO WORLD')
        btn = QPushButton('&Start Dialog')
        lbl.setBuddy(btn)
        
        lyt = QHBoxLayout()
        lyt.addWidget(lbl)
        lyt.addWidget(btn)
        
        self.setLayout(lyt)
        self.connect(btn, SIGNAL('clicked()'), self.popup_dialog)

    def popup_dialog(self):
        x = Dialog(self)
        if x.exec_():
            print(x.spn.value())

p = Parent()    
p.show()

app.exec_()

    



More information about the Python-list mailing list