Search code examples
pythonpyqtpyqt5qwidget

How to show a widget on button click of another widget


My question is simple, I am trying to open a child window within the main window. I took help of all of the answers so this question is not a duplicate. My child window comes for some time and then disappears automatically.

import random
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import QtWidgets, uic


class SubWindow(QWidget):
    def __init__(self, parent = None):
        super(SubWindow, self).__init__(parent)
        label = QLabel("Sub Window",  self)
        label.setGeometry(0, 0, 20, 10)
        self.show()


class pro(QWidget):
    def __init__(self, parent=None):
        super(pro, self).__init__(parent)


        self.acceptDrops()

        self.x = 200
        self.y = 200
        self.width = 800
        self.length = 800

        self.setGeometry(self.x, self.y, self.width, self.length)
        self.setWindowTitle("PA")

        label = QLabel(self)
        pixmap = QPixmap('p_bg.png')
        label.setPixmap(pixmap)
        label.setGeometry(0, 0, 1100, 1000)

        self.initgui()

    def register_system(self):
        opener = SubWindow()
        opener.show()

    def initgui(self):

        self.btn_log = QPushButton(self)
        self.btn_log.setGeometry(440, 250, 150, 30)
        self.btn_log.setText("         Login         ")
        self.btn_log.adjustSize()

        self.btn_sign = QPushButton(self)
        self.btn_sign.setGeometry(440, 300, 150, 30)
        self.btn_sign.setText("       Register       ")
        self.btn_sign.adjustSize()
        self.btn_sign.clicked.connect(self.register_system)

        self.welcome = QLabel("Arial font", self)
        self.welcome.setText("Welcome")
        self.welcome.setGeometry(410, 100, 200, 30)
        self.welcome.setStyleSheet("background-color:transparent;")
        self.welcome.setFont(QFont("Arial", 30))

        self.show()

def window():

    apk = QApplication(sys.argv)
    win = pro()

    win.show()
    sys.exit(apk.exec_())
window()

I took help to make a child window from here:https://www.codersarts.com/post/multiple-windows-in-pyqt5-codersarts , I used type 2 resource in my case.


Solution

  • The reason probably is that the variable opener has scope within the register_system method only; it is getting deleted after the method exits, you can modify the code either to create the variable as an attribute to the class object using self and then show the widget like this:

        def register_system(self):
            self.opener = SubWindow()
            self.opener.show()
    

    Or, you can just create a variable opener at global scope, then use the global variable to assign and show the widget:

    # imports
    opener = None
    class SubWindow(QWidget):
        def __init__(self, parent = None):
        
        #Rest of the code
    
    class pro(QWidget):
        def __init__(self, parent=None):
        # Rest of the code
    
        def register_system(self):
            global opener
            opener = SubWindow()
            opener.show()
    
        # Rest of the code
    

    On a side note, you should always use layout for the widgets in PyQt application, you can take a look at Layout Management