Search code examples
user-interfacelayoutpyqtpyqt4qwidget

Works with QGridLayout not with QVBoxLayout


from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os, time

class SetName(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.show()
        toplayout = QVBoxLayout()
        self.setWindowTitle('Personal Info')
        self.form_layout = QFormLayout()
        self.setLayout(self.form_layout)
        self.line_edit_param = QLineEdit(self)

        self.line_edit_param.setPlaceholderText("Write Here")
        self.form_layout.addRow('Write Name', self.line_edit_param)      
        toplayout.addLayout(self.form_layout)
        self.setFocus()

class LearnApp(QDialog):
    def __init__(self):
        super(QDialog, self).__init__()
        self.setWindowTitle("LearnApp")

        self.active = False

        close_button = QPushButton("Close")
        close_button.clicked.connect(self.close)

        self.check_button = QPushButton("Check")
        self.check_button.clicked.connect(self.set_data)        
        self.tr = QTextEdit()
        self.tr.setReadOnly(True)
        # layout
        layout = QHBoxLayout()        
        #layout.addWidget(self.button3)
        sub_layout = QVBoxLayout()
        sub_layout.addWidget(self.check_button)
        sub_layout.addWidget(close_button)
        layout.addLayout(sub_layout)
        layout.addWidget(self.tr)
        self.setLayout(layout)
        self.setFocus()

    def set_data(self):
        print "in set_data"
        SetName()

app = QApplication(sys.argv)
dialog = LearnApp()
dialog.show()
app.exec_()

This is the code I'm trying. If edit it with toplayout = QGridLayout(), program works fine but with toplayout = QVBoxLayout(), it gives message QLayout::addChildLayout: layout "" already has a parentand just flashes the new window. What could be the problem? How should I tackle this? I wanna use QVBoxLayout instead of QGridLayout


Solution

  • Firstly, the new window disappears straight away because you don't store a reference to it. You need to store a reference to the instance in your LearnApp class, or parent it to another Qt object outside of set_data() if you want it to stick around.

    The error message regarding the layouts is not occurring because of your choice of layouts, but because you are calling

    self.setLayout(self.form_layout)
    

    and then

    toplayout.addLayout(self.form_layout)
    

    The first call assigns the layout to the instance of SetName, but in doing so also makes the instance the parent of self.form_layout. The second call is trying to add the same layout to toplayout and set it as the parent, but Qt sees that self.form_layout already has a parent (i.e. is being used elsewhere). This is what the error message is trying to tell you.

    I suspect that instead of self.setLayout(self.form_layout), you intended to write something like

    self.setLayout(toplayout)