parent-childpyqt5non-modal

Custom modeless dialog class not visible


I want to make a custom non-modal dialog class with a label and a QDialogButtonBox. I have looked at a number of postings, but none seems really on point. My code is below. Two questions: 1. Why isn't the dialog class displaying anything? 2. Do the connections look correct for the QDialogButtonBox?

Any help would be appreciated. Thanks!

from PyQt5.QtWidgets import *

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        cb = QCheckBox('Check me anytime', self)
        cb.move(20, 20)

        button = QPushButton('Open Dialog', self)
        button.move(20,50)
        self.resize(120, 90)

        button.clicked.connect(self.showDialog)

    def showDialog(self):
        self.dialog = ModelessDialog(self)
        self.dialog.show()

class ModelessDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout()
        lbl = QLabel("please show something ...")
        buttonBox = QDialogButtonBox(
            QDialogButtonBox.Cancel|QDialogButtonBox.Apply)
        layout.addWidget(lbl)
        layout.addWidget(buttonBox)
        self.resize(300, 200)        

        applyBtn = buttonBox.button(QDialogButtonBox.Apply)
        applyBtn.clicked.connect(self.apply)

        cancelBtn = buttonBox.button(QDialogButtonBox.Cancel)
        cancelBtn.clicked.connect(ModelessDialog.reject)

        self.setWindowTitle("Modeless")

    def apply(self):
        print("ModelessDialog: in apply")

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())

Solution

  • Sets the layout manager for this widget to layout .

    self.setLayout(layout) 
    

    Try it:

    from PyQt5.QtWidgets import *
    
    class Window(QWidget):
        def __init__(self):
            QWidget.__init__(self)
    
            cb = QCheckBox('Check me anytime', self)
            cb.move(20, 20)
    
            button = QPushButton('Open Dialog', self)
            button.move(20,50)
            self.resize(150, 90)
    
            button.clicked.connect(self.showDialog)
    
        def showDialog(self):
            self.dialog = ModelessDialog(self)
            self.dialog.show()
    
    class ModelessDialog(QDialog):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            layout = QVBoxLayout()
            lbl    = QLabel("please show something ...")
            buttonBox = QDialogButtonBox(
                QDialogButtonBox.Cancel|QDialogButtonBox.Apply)
            layout.addWidget(lbl)
            layout.addWidget(buttonBox)
            self.resize(300, 200)  
            # Sets the layout manager for this widget to layout .
            self.setLayout(layout)                              # +++    
    
            applyBtn = buttonBox.button(QDialogButtonBox.Apply)
            applyBtn.clicked.connect(self.apply)
    
            cancelBtn = buttonBox.button(QDialogButtonBox.Cancel)
            #cancelBtn.clicked.connect(ModelessDialog.reject)   # ---
            # first argument of unbound method must have type 'QDialog'
            cancelBtn.clicked.connect(self.reject)              # +++
    
            self.setWindowTitle("Modeless")
    
        def apply(self):
            print("ModelessDialog: in apply")
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        win = Window()
        win.show()
        sys.exit(app.exec_())
    

    enter image description here