Python Forum

Full Version: App crashes when reopening a subwindow
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hi, guys! I have a MainWindow with a subwindow inside an mdiArea. The subwindow opens, but if I close it and try to reopen it, my app crashes. What am I doing wrong? Here's my code:

from PyQt5 import QtCore, QtGui, QtWidgets
  
  
class Ui_MainWindow(object):
  
    def setupUi(self, MainWindow):
  
        MainWindow.setObjectName("MainWindow")
        MainWindow.setWindowModality(QtCore.Qt.WindowModal)
        MainWindow.resize(781, 478)
         
        self.mdiArea = QtWidgets.QMdiArea()
        self.mdiArea.setGeometry(0, 0, 600, 400)
        self.mdiArea.setAutoFillBackground(True)
        self.mdiArea.setObjectName("mdiArea")
  
        self.subWindowUsers = QtWidgets.QWidget()
        self.subWindowUsers.setMinimumSize(QtCore.QSize(466, 267))
        self.subWindowUsers.setObjectName("subWindowUsers")
  
        self.pushButton_save_2 = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_save_2.setGeometry(QtCore.QRect(330, 220, 75, 23))
        self.pushButton_save_2.setObjectName("pushButton_save_2")
  
        self.pushButton_previous = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_previous.setGeometry(QtCore.QRect(150, 190, 75, 23))
        self.pushButton_previous.setObjectName("pushButton_previous")
  
        self.lineEdit_date = QtWidgets.QLineEdit(self.subWindowUsers)
        self.lineEdit_date.setGeometry(QtCore.QRect(110, 50, 91, 20))
        self.lineEdit_date.setObjectName("lineEdit_date")
  
        self.pushButton_edit = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_edit.setGeometry(QtCore.QRect(150, 220, 75, 23))
        self.pushButton_edit.setObjectName("pushButton_edit")
  
        self.pushButton_update = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_update.setGeometry(QtCore.QRect(240, 220, 75, 23))
        self.pushButton_update.setObjectName("pushButton_update")
  
        self.pushButton_next = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_next.setGeometry(QtCore.QRect(240, 190, 75, 23))
        self.pushButton_next.setObjectName("pushButton_next")
  
        self.pushButton_first = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_first.setGeometry(QtCore.QRect(60, 190, 75, 23))
        self.pushButton_first.setObjectName("pushButton_first")
  
        self.pushButton_last = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_last.setGeometry(QtCore.QRect(330, 190, 75, 23))
        self.pushButton_last.setObjectName("pushButton_last")
  
        self.pushButton_add = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_add.setGeometry(QtCore.QRect(60, 220, 75, 23))
        self.pushButton_add.setObjectName("pushButton_add")
  
        self.pushButton_cancel = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_cancel.setGeometry(QtCore.QRect(240, 220, 75, 23))
        self.pushButton_cancel.setObjectName("pushButton_cancel")
  
        self.lineEdit_login = QtWidgets.QLineEdit(self.subWindowUsers)
        self.lineEdit_login.setGeometry(QtCore.QRect(110, 110, 171, 20))
        self.lineEdit_login.setObjectName("lineEdit_login")
  
        self.lineEdit_name = QtWidgets.QLineEdit(self.subWindowUsers)
        self.lineEdit_name.setGeometry(QtCore.QRect(110, 80, 271, 20))
        self.lineEdit_name.setObjectName("lineEdit_name")
  
        self.pushButton_save = QtWidgets.QPushButton(self.subWindowUsers)
        self.pushButton_save.setGeometry(QtCore.QRect(330, 220, 75, 23))
        self.pushButton_save.setObjectName("pushButton_save")
  
        self.lineEdit_number = QtWidgets.QLineEdit(self.subWindowUsers)
        self.lineEdit_number.setGeometry(QtCore.QRect(110, 20, 61, 20))
        self.lineEdit_number.setObjectName("lineEdit_number")
  
        self.lineEdit_pwd = QtWidgets.QLineEdit(self.subWindowUsers)
        self.lineEdit_pwd.setGeometry(QtCore.QRect(110, 140, 113, 20))
        self.lineEdit_pwd.setObjectName("lineEdit_pwd")
  
        MainWindow.setCentralWidget(self.mdiArea)
  
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 781, 21))
        self.menubar.setObjectName("menubar")
  
        self.menuUsers = QtWidgets.QMenu(self.menubar)
        self.menuUsers.setObjectName("menuUsers")
        MainWindow.setMenuBar(self.menubar)
  
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
  
        self.actionFile_users = QtWidgets.QAction(MainWindow)
        self.actionFile_users.setObjectName("actionFile_users")
  
        self.menuUsers.addAction(self.actionFile_users)
        self.menubar.addAction(self.menuUsers.menuAction())
  
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
  
        self.actionFile_users.triggered.connect(lambda: self.OpenUserForm("Users"))
  
        self.pushButton_cancel.hide()
        self.pushButton_save.hide()
  
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "My App"))
        self.subWindowUsers.setWindowTitle(_translate("MainWindow", "Subwindow"))
        self.pushButton_save_2.setText(_translate("MainWindow", "Delete"))
        self.pushButton_previous.setText(_translate("MainWindow", "< Previous"))
        self.pushButton_edit.setText(_translate("MainWindow", "Edit"))
        self.pushButton_update.setText(_translate("MainWindow", "Update"))
        self.pushButton_next.setText(_translate("MainWindow", "Next >"))
        self.pushButton_first.setText(_translate("MainWindow", "<< First"))
        self.pushButton_last.setText(_translate("MainWindow", "Last >>"))
        self.pushButton_add.setText(_translate("MainWindow", "New user"))
        self.pushButton_cancel.setText(_translate("MainWindow", "Cancel"))
        self.pushButton_save.setText(_translate("MainWindow", "Save"))
        self.menuUsers.setTitle(_translate("MainWindow", "Files"))
        self.actionFile_users.setText(_translate("MainWindow", "Users"))
  
    def OpenUserForm(self, text):
        self.mdiArea.addSubWindow(ui.subWindowUsers)
        ui.subWindowUsers.setWindowTitle(text)
        ui.subWindowUsers.show()
  
  
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
Thanks a lot for your time and help. I appreciate it! Best regards,
(Aug-03-2021, 01:58 AM)JayCee Wrote: [ -> ]
        self.mdiArea = QtWidgets.QMdiArea()
        self.mdiArea.setGeometry(0, 0, 600, 400)
        self.mdiArea.setAutoFillBackground(True)
        self.mdiArea.setObjectName("mdiArea")
  
        self.subWindowUsers = QtWidgets.QWidget()
        self.subWindowUsers.setMinimumSize(QtCore.QSize(466, 267))
        self.subWindowUsers.setObjectName("subWindowUsers")

    def OpenUserForm(self, text):
        self.mdiArea.addSubWindow(ui.subWindowUsers)
        ui.subWindowUsers.setWindowTitle(text)
        ui.subWindowUsers.show()

What does it give as an error?

where is the " self "... I guess it might be because you didn't specify this on the bottom line on the side I cut out... I didn't have a chance to test your code, I'm just making a guess.
(Aug-03-2021, 02:47 AM)JokerSob Wrote: [ -> ]
(Aug-03-2021, 01:58 AM)JayCee Wrote: [ -> ]
        self.mdiArea = QtWidgets.QMdiArea()
        self.mdiArea.setGeometry(0, 0, 600, 400)
        self.mdiArea.setAutoFillBackground(True)
        self.mdiArea.setObjectName("mdiArea")
  
        self.subWindowUsers = QtWidgets.QWidget()
        self.subWindowUsers.setMinimumSize(QtCore.QSize(466, 267))
        self.subWindowUsers.setObjectName("subWindowUsers")

    def OpenUserForm(self, text):
        self.mdiArea.addSubWindow(ui.subWindowUsers)
        ui.subWindowUsers.setWindowTitle(text)
        ui.subWindowUsers.show()

What does it give as an error?

where is the " self "... I guess it might be because you didn't specify this on the bottom line on the side I cut out... I didn't have a chance to test your code, I'm just making a guess.

It prints out a memory address error in the Pycharm console window, but that's it.
line 140, in <module>
ui.setupUi(MainWindow)
line 15, in setupUi
self.ui.mdiArea = QtWidgets.QMdiArea()
AttributeError: 'Ui_MainWindow' object has no attribute 'ui'


also ui = Ui_MainWindow() - ui.setupUi(MainWindow) When you remove these two, the window opens. I would like to solve your mistake but now I will go to sleep
This an example using Layouts, (removed all setGeometry)

password should use echoMode 2.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
   
 
class SubWindowUsers(QtWidgets.QWidget):
    def __init__(self):
        super(SubWindowUsers, self).__init__()  
        
        self.setMinimumSize(QtCore.QSize(400, 300))
        self.setObjectName("subWindowUsers")
        self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        layout = QtWidgets.QVBoxLayout()
        fields_box = QtWidgets.QVBoxLayout()
        btn_box_1 = QtWidgets.QHBoxLayout()
        btn_box_2 = QtWidgets.QHBoxLayout()
        btn_box_3 = QtWidgets.QHBoxLayout()
   
        self.pushButton_save_2 = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_DialogSaveButton), "Save", self)
        self.pushButton_save_2.setObjectName("pushButton_save_2")
   
        self.pushButton_previous = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowBack), "Previous", self)
        self.pushButton_previous.setObjectName("pushButton_previous")
   
        self.lineEdit_date = QtWidgets.QLineEdit(self, placeholderText = "Date")
        self.lineEdit_date.setObjectName("lineEdit_date")
   
        self.pushButton_edit = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_FileDialogListView), "Edit", self)
        self.pushButton_edit.setObjectName("pushButton_edit")
   
        self.pushButton_update = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton), "Update", self)
        self.pushButton_update.setObjectName("pushButton_update")
   
        self.pushButton_next = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowForward), "Next", self)
        self.pushButton_next.setObjectName("pushButton_next")
   
        self.pushButton_first = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowUp), "First", self)
        self.pushButton_first.setObjectName("pushButton_first")
   
        self.pushButton_last = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowDown), "Last", self)
        self.pushButton_last.setObjectName("pushButton_last")
   
        self.pushButton_add = QtWidgets.QPushButton("+  Add", self)
        self.pushButton_add.setObjectName("pushButton_add")
   
        self.pushButton_cancel = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton), "Cancel", self)
        self.pushButton_cancel.setObjectName("pushButton_cancel")
   
        self.lineEdit_login = QtWidgets.QLineEdit(self, placeholderText = "Login")
        self.lineEdit_login.setObjectName("lineEdit_login")
   
        self.lineEdit_name = QtWidgets.QLineEdit(self, placeholderText = "Name")
        self.lineEdit_name.setObjectName("lineEdit_name")
   
        self.pushButton_save = QtWidgets.QPushButton(self.style().standardIcon(QtWidgets.QStyle.SP_DialogSaveButton), "Save", self)
        self.pushButton_save.setObjectName("pushButton_save")
   
        self.lineEdit_number = QtWidgets.QLineEdit(self, placeholderText = "Number")
        self.lineEdit_number.setObjectName("lineEdit_number")
   
        self.lineEdit_pwd = QtWidgets.QLineEdit(self, placeholderText = "Password", echoMode = 2)
        self.lineEdit_pwd.setObjectName("lineEdit_pwd")
        
        fields_box.addWidget(self.lineEdit_number)
        fields_box.addWidget(self.lineEdit_date)
        fields_box.addWidget(self.lineEdit_name)
        fields_box.addWidget(self.lineEdit_login)
        fields_box.addWidget(self.lineEdit_pwd)
        
        btn_box_1.addWidget(self.pushButton_first, 1, QtCore.Qt.AlignLeft)
        btn_box_1.addWidget(self.pushButton_previous, 1, QtCore.Qt.AlignLeft)
        btn_box_1.addWidget(self.pushButton_next, 1, QtCore.Qt.AlignLeft)
        btn_box_1.addWidget(self.pushButton_last, 1, QtCore.Qt.AlignLeft)
        
        btn_box_2.addWidget(self.pushButton_add, 1, QtCore.Qt.AlignLeft)
        btn_box_2.addWidget(self.pushButton_update, 1, QtCore.Qt.AlignLeft)
        btn_box_2.addWidget(self.pushButton_edit, 1, QtCore.Qt.AlignLeft)
        btn_box_2.addWidget(self.pushButton_save_2, 1, QtCore.Qt.AlignLeft)

        btn_box_3.addWidget(self.pushButton_cancel, 1, QtCore.Qt.AlignLeft)
        btn_box_3.addWidget(self.pushButton_save, 1, QtCore.Qt.AlignLeft)
        
        layout.addLayout(fields_box)
        layout.addLayout(btn_box_1)
        layout.addLayout(btn_box_2)
        layout.addLayout(btn_box_3)
        self.setLayout(layout)
        
        #self.pushButton_cancel.hide()
        #self.pushButton_save.hide()
 
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__()
   
        self.setObjectName("MainWindow")
        self.setWindowModality(QtCore.Qt.WindowModal)
        self.setGeometry(50, 50, 700, 500)
          
        self.mdiArea = QtWidgets.QMdiArea()
        self.mdiArea.setAutoFillBackground(True)
        self.mdiArea.setObjectName("mdiArea")
 
        self.setCentralWidget(self.mdiArea)
   
        bar = self.menuBar()
        self.menubar = bar.addMenu("Files")
        self.menubar.setObjectName("menubar")
   
        self.statusbar = self.statusBar()
        self.statusbar.setObjectName("statusbar")
        self.statusbar.showMessage("Ready", 0)
   
        self.actionFile_users = QtWidgets.QAction("Users")
        self.menubar.addAction(self.actionFile_users)
   
        QtCore.QMetaObject.connectSlotsByName(self)
   
        self.actionFile_users.triggered.connect(self.OpenUserForm)
   

    def OpenUserForm(self):
        self.swu = SubWindowUsers()
        self.mdiArea.addSubWindow(self.swu)
        self.swu.setWindowTitle("Users")
        self.swu.show()
        self.statusbar.showMessage("Users Window opened", 0)
   
   
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainwin = MainWindow()
    mainwin.show()
    sys.exit(app.exec_())
(Aug-03-2021, 01:34 PM)Axel_Erfurt Wrote: [ -> ]This an example using Layouts, (removed all setGeometry)

password should use echoMode 2.

Hi Axel. Your code worked perfectly, again. I'm going to study it line by line to understand what you did. You even made the buttons beautiful. Thanks a lot for all your time and help!!
Zeal is a fine app (Win / Mac / Linux) for offline docs (200 programming languages ​​available)
A layout is, so to speak, a box in which widgets are placed.

QVBoxLayout -> vertical
QHBoxLayout -> horizontal

layout = QtWidgets.QVBoxLayout()

is the (vertical) Layout for the whole window.

fields_box = QtWidgets.QVBoxLayout()

all QLineEdit are placed in this (vertical) Layout

btn_box_1 = QtWidgets.QHBoxLayout()
btn_box_2 = QtWidgets.QHBoxLayout()
btn_box_3 = QtWidgets.QHBoxLayout()

In this horizontal layouts, the buttons are placed next to each other.

layout.addLayout(fields_box)
layout.addLayout(btn_box_1)
layout.addLayout(btn_box_2)
layout.addLayout(btn_box_3)

all layouts are added to the main layout.
(Aug-03-2021, 04:32 PM)Axel_Erfurt Wrote: [ -> ]Zeal is a fine app (Win / Mac / Linux) for offline docs (200 programming languages ​​available)

Great tip! Just downloaded and installed it. Amazing tool... By the way, I learned my lesson NOT to use Qt Designer.
(Aug-03-2021, 04:44 PM)Axel_Erfurt Wrote: [ -> ]A layout is, so to speak, a box in which widgets are placed.

QVBoxLayout -> vertical
QHBoxLayout -> horizontal

layout = QtWidgets.QVBoxLayout()

is the (vertical) Layout for the whole window.

fields_box = QtWidgets.QVBoxLayout()

all QLineEdit are placed in this (vertical) Layout

btn_box_1 = QtWidgets.QHBoxLayout()
btn_box_2 = QtWidgets.QHBoxLayout()
btn_box_3 = QtWidgets.QHBoxLayout()

In this horizontal layouts, the buttons are placed next to each other.

layout.addLayout(fields_box)
layout.addLayout(btn_box_1)
layout.addLayout(btn_box_2)
layout.addLayout(btn_box_3)

all layouts are added to the main layout.

The weird thing now is that when I try to fix the swu size it simply won't work. I tried a dozen different ways, including:

self.setMaximumSize(QtCore.QSize(400, 300)) and
self.setFixedSize(QtCore.QSize(400, 300))

but to no avail...
Pages: 1 2