aking76
aking76

Reputation: 67

Python/ PYQT5- Crashing when hiding menu, if ran from the main window

Code has been edited per requests

Here's the code-

Test.py

    from PyQt5 import QtCore, QtGui, QtWidgets
from Test2 import *

class Ui_MainWindow(object):
    def ipDombtn(self):
        self.window=QtWidgets.QMainWindow()
        self.ui=Ui_MainWindow1()
        self.ui.setup(self.window)
        self.window.show()


    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(412, 440)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")



        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)
        self.pushButton.clicked.connect(self.ipDombtn)


        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 412, 31))
        self.menubar.setObjectName("menubar")

        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Investigation"))


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_())

Here is the second menu's code. It's set to call specific functions based on what they select. If I comment out the MainWindow.hide() I can run the MainMenu, select investigations and then click on one of the options and they work. If I run this code without running the main menu, and nothing commented out, it works just fine. Is it an issue with two menus, even though they are renamed?

Test2.py

    from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow1(object):

    def exIpDomInv_clicked(self):
        MainWindow1.hide()
        print("You clicked a button...")
        MainWindow1.show()





    def setup(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(412, 440)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")


        self.exIpDomInv = QtWidgets.QPushButton(self.centralwidget)
        self.exIpDomInv.setObjectName("exIpDomInv")
        self.verticalLayout.addWidget(self.exIpDomInv)


        MainWindow.setCentralWidget(self.centralwidget)
        self.Menu = QtWidgets.QMenuBar(MainWindow)
        self.Menu.setGeometry(QtCore.QRect(0, 0, 412, 31))
        self.Menu.setObjectName("Menu")

        MainWindow.setMenuBar(self.Menu)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")

        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.exIpDomInv.clicked.connect(self.exIpDomInv_clicked)



    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Investigation"))
        MainWindow.setAccessibleName(_translate("MainWindow", "InvestigationMenu"))
        self.exIpDomInv.setText(_translate("MainWindow", "External IP/ Domain Investigation"))



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow1 = QtWidgets.QMainWindow()
    ui2 = Ui_MainWindow1()
    ui2.setup(MainWindow1)
    MainWindow1.show()
    sys.exit(app.exec_())

Upvotes: 2

Views: 585

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

Note that the program is broken does not help, you are probably using some IDE, many times the IDEs do not handle these types of errors correctly so I recommend you execute it in a CMD, if you do so you will get the following message:

Traceback (most recent call last):
  File "/path/of/Test2.py", line 6, in exIpDomInv_clicked
    MainWindow1.hide()
NameError: name 'MainWindow1' is not defined
Aborted (core dumped)

Well, more or less, it gives us an idea of the problem, it tells us that MainWindow1 is not defined, and this leads me to think that you are not clear about some concepts:

  • The expression if __name__ == "__main__": can have all the files but only the first one is observed so that the if __name__ == "__main__": of Test2.py will not run and therefore the MainWindow1 that you assume exists will not exist.

  • Classes are abstractions ie they describe a behavior of their objects, besides they only access the members of their scope, that is, it is like a black box, if the object is not defined within the class it can not be accessed, so if you want to access the Ui_MainWindow of Test.py you can not do it directly as it is, there are several methods to achieve it but it is based on the above.

  • On the other hand the classes that generate Qt Designer are recommended not to edit them because if you modify something in the .ui and recompile it will erase all the changes, besides they are not widgets so you have limitations such as overwriting of the methods. For more information read this.

Considering the above, I am going to divide it into several files:

ui_mainwindow1.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow1(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(412, 440)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")


        self.exIpDomInv = QtWidgets.QPushButton(self.centralwidget)
        self.exIpDomInv.setObjectName("exIpDomInv")
        self.verticalLayout.addWidget(self.exIpDomInv)


        MainWindow.setCentralWidget(self.centralwidget)
        self.Menu = QtWidgets.QMenuBar(MainWindow)
        self.Menu.setGeometry(QtCore.QRect(0, 0, 412, 31))
        self.Menu.setObjectName("Menu")

        MainWindow.setMenuBar(self.Menu)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")

        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Investigation"))
        MainWindow.setAccessibleName(_translate("MainWindow", "InvestigationMenu"))
        self.exIpDomInv.setText(_translate("MainWindow", "External IP/ Domain Investigation"))



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow1 = QtWidgets.QMainWindow()
    ui2 = Ui_MainWindow1()
    ui2.setup(MainWindow1)
    MainWindow1.show()
    sys.exit(app.exec_())

ui_mainwindow.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(412, 440)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout.addWidget(self.pushButton)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 412, 31))
        self.menubar.setObjectName("menubar")

        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Investigation"))


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_())

main.py

from PyQt5 import QtWidgets

from ui_mainwindow1 import Ui_MainWindow1
from ui_mainwindow import Ui_MainWindow


class MainWindow1(QtWidgets.QMainWindow, Ui_MainWindow1):
    def __init__(self, parent=None):
        super(MainWindow1, self).__init__(parent)
        self.setupUi(self)


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.other_window = MainWindow1()
        self.pushButton.clicked.connect(self.other_window.show)
        self.other_window.exIpDomInv.clicked.connect(self.hide)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

As you see the object other_window is in the same scope of the class so it can be accessed and therefore all the elements are defined. Also each file has its if __name__ == "__main__":, these serve to test the operation of each class, but only the one in the main.py will be executed, the others will be ignored.

Upvotes: 1

Related Questions