On Tuesday, September 26, 2017 at 2:23:22 PM UTC+5:30, Thomas Jollans wrote:
> On 2017-09-26 08:16, Veek M wrote:
> > On Tuesday, September 26, 2017 at 11:18:54 AM UTC+5:30, Veek M wrote:
> >> 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_()
> > 
> > I fixed some of it by deleting the:
> > Parent
> >  self.setLayout(lyt) 
> > 
> > I don't understand why that works - aren't we supposed to attach a layout 
> > to the Parent/MainWindow object? Why not?
> > 
> > Also, I made the: 
> > Parent
> >  self.setCentralWidget(btn)
> 
> IIRC, QMainWindow is a bit weird, since it provides things like menu and
> status bars. Everything normally goes into a "central widget".
> 
> The (or: a) thing to do is (I suspect):
> 
> class Parent(QMainWindow):
>     def __init__(self, parent=None):
>       # This is the future. super() is smart now.
>         super().__init__(parent)
> 
>         lbl = QLabel('HELLO WORLD')
>         btn = QPushButton('&Start Dialog')
>         lbl.setBuddy(btn)
> 
>         lyt = QHBoxLayout()
>         lyt.addWidget(lbl)
>         lyt.addWidget(btn)
> 
>       central_widget = QWidget()
>         central_widget.setLayout(lyt)
>         self.setCentralWidget(central_widget)
>       
>       # Use new-style signals and slots! They're nicer!
>       btn.clicked.connect(self.popup_dialog)
> 
>     def popup_dialog(self):
>         x = Dialog(self)
>         if x.exec_():
>             print(x.spn.value())
> 
> I normally like to explicitly parent my widgets on construction, but
> that's not necessary and I'm probably doing it wrong anyway.
> 
> Aside: I notice you're using PyQt4. That's great, I do too (for now),
> but I suggest you consider moving to PyQt5. PyQt4 is slowly
> disappearing. Anaconda (on Windows at least) has annoying dependency
> structures that force you to use old versions of the scientific python
> stack if you want to use qt4. I'm going to have to upgrade soon.
> 
> The differences between PyQt4 and PyQt5 aren't massive, but they've
> moved around some classes (QtGui has been split into two packages, which
> is going to be annoying to migrate) and support for old-style signal and
> slot syntax has been dropped (good riddance).
> 
> Also, if you're using Python 2: don't. Just don't. It's not 2012 any
> more. (I don't know what you're using, but /usr/bin/python is normally
> Python 2)
> 
> > 
> > so the button is the central widget. To use the Label, I think I would have 
> > to create a composite widget which is too complicated for me, currently.
> > 
> > Now. it works so I tested some more and added:
> >     def popup_dialog(self):
> >         x = Dialog(self)
> >         y = Dialog(self)
> >         y.show()
> >         if x.exec_():
> >             print(x.spn.value())
> > AND
> > 
> > class Dialog(QDialog):
> >     self.connect(self.cncl_btn, SIGNAL('clicked()'), self.close)
> > 
> > So my dialog pops up and because exec_ is being called on 'x', I have to 
> > first close that widget before I can interact with my button and 'y'. 
> > However, let's say I close the 'x' dialog - then I can click on 'Button' 
> > and I get two more dialogs which don't lock anything - why??
> > 
> 
> 
> -- 
> Thomas Jollans

Thanks - i'm on debian stretch so python 2.7 is what I use. Right now, my book 
deals with PyQt4 so I thought I'd stick with that, till I get a hang of things.
The book I'm using is good but not great - he's over complicated things with 
really verbose examples of simple stuff, instead of conveying a central idea 
eg: dump, smart and standard dialogs are mostly the same thing and the central 
idea could be conveyed in a few lines but he's got some huge examples spread 
over pages, that's mostly unnecessary. I found the PyQt docs to be very clear 
but right now, I dare not stray.


There's a russian book on PyQt5 that looks nice but there's no way to translate 
it: Python 3 and pyqt 5 application development - prokhorenok n.a
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to