简体   繁体   English

第二次实例化 class 时出错

[英]Error when instantiating a class for the second time

I'm new to python and PyQt and was developing my first app using it, and I've been stuck in a problem when trying to instantiate a class I made again.我是 python 和 PyQt 的新手,并且正在使用它开发我的第一个应用程序,并且在尝试实例化我再次制作的 class 时遇到了问题。 I've got the following error:我有以下错误:

Traceback (most recent call last):
  File "ConfiguradorAnx.py", line 16, in <lambda>
     self.ProductInfo.clicked.connect(lambda: self.newWindow(InfoProduct))
TypeError: 'InfoProduct' object is not callable
Aborted

The code goes like this:代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets, uic
import sys

class StartWindow(QtWidgets.QMainWindow):   #This function should inherit the class
                                            #used to make the ui file  
    def __init__(self):
        super(StartWindow,self).__init__()   #Calling the QMainWindow constructor
        uic.loadUi('Janela_inicial.ui',self)

        #defining quit button from generated ui
        self.QuitButton = self.findChild(QtWidgets.QPushButton, 'QuitButton')
        self.QuitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)

        #defining product info button
        self.ProductInfo = self.findChild(QtWidgets.QPushButton, 'ProductInformation')
        self.ProductInfo.clicked.connect(lambda: self.newWindow(InfoProduct))
        self.show() #Show the start window

    def newWindow(self, _class):
        self.newWindow = _class()
        del self.newWindow

class InfoProduct(QtWidgets.QMainWindow):
    def __init__(self):
        super(InfoProduct,self).__init__()
        uic.loadUi('informacao_prod.ui',self)
        self.QuitButton = self.findChild(QtWidgets.QPushButton, 'pushButton')
        self.QuitButton.clicked.connect(lambda: self.destroy())
        self.show()

def main():
    app = QtWidgets.QApplication(sys.argv)  #Creates a instance of Qt application
    InitialWindow = StartWindow()
    app.exec_() #Start application

if __name__ == '__main__':
    main()

The first time I click on self.ProductInfo button it works and the InfoProduct window opens, but when I close the window and click on the same button again, I've got the error.我第一次单击self.ProductInfo按钮时它可以工作并且 InfoProduct window 打开,但是当我关闭 window 并再次单击相同的按钮时,我得到了错误。 I can't figure out what is it that I'm missing, I hope you guys could help!我无法弄清楚我错过了什么,希望你们能提供帮助!

Cheers!干杯!

You're overwriting the newWindow function in its execution:您在执行过程中覆盖了newWindow function:

def newWindow(self, _class):
    self.newWindow = _class()

By doing this, the result is that the next time you click the button, the lambda will try to call self.newWindow(InfoProduct) , but at that point self.newWindow is an instance of InfoProduct , which obviously is not callable.通过这样做,结果是下次单击按钮时,lambda 将尝试调用self.newWindow(InfoProduct) ,但此时self.newWindowInfoProduct的一个实例,显然不可调用。

The solution is simple (and very important) use different names for the function and the variable that points to the instance:解决方案很简单(并且非常重要)为 function 和指向实例的变量使用不同的名称:

        self.ProductInfo.clicked.connect(lambda: self.createNewWindow(InfoProduct))

    def createNewWindow(self, _class):
        self.newWindow = _class()

Two small side notes:两个小注解:

  • There's no need to use findChild , as loadUi already creates python instance attributes for widgets: you already can access self.QuitButton , etc.无需使用findChild ,因为loadUi已经为小部件创建了 python 实例属性:您已经可以访问self.QuitButton等。
  • Avoid using capitalized names for variables and attributes.避免对变量和属性使用大写的名称。 Read more about this and other code styling suggestions on the Style Guide for Python Code (aka, PEP-8).Python 代码(又名 PEP-8)的样式指南中阅读有关此代码样式建议和其他代码样式建议的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM