【问题标题】:Python: How can object call the object that created it?Python:对象如何调用创建它的对象?
【发布时间】:2016-12-16 00:08:56
【问题描述】:

在 Python 3.5 中,对象如何调用实例化它的对象中的函数?

我创建了一个 PyQt 应用程序,它实例化了一个简单的数据库对象 db。我希望 db 对象能够更新主窗口对象中的进度条,但我无法弄清楚传递给 db 对象的内容以使其成为可能。

我花了几个小时在线阅读,但无法弄清楚这一点。我以为我可以将 self 作为 MainWindow 对象的标识符传递给 db 对象,但是在 db =photoDb(self) 失败并出现 NameError:“名称'self'未定义”。显然,尽管阅读了很多关于它的网页或网页,但我并不完全理解 self

我怀疑这一定是构造函数中的简单信息传递,但我想不通。 (而且我已经花了几个小时阅读可能与此相关的 StackOverflow 条目。抱歉,如果这应该是显而易见的,或者已经在我没有找到的条目中得到了回答。)我正在使用 Python 3.5、PyQt4 和 Ubuntu 16.10。

我的代码要点:

class photoDb(self, mainwindow):

    def __init__(self):
        self.db = []

    def addPhotosToDb(self, filenames):
        i = 0
        for f in filenames:
        (do a bunch of stuff here with f)
        self.db.append(f)
        mainwindow.updateProgressBar(int(100*i/len(filenames))


class MainWindow(QtGui.QMainWindow, photoOrg_MainWindow.Ui_MainWindow):

    db =photoDb(self)

    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        (lots more GUI widget connection code here)

    def updateProgressBar(self, percentage):
        self.progressBar.setValue(percentage)

    def addPhotosToDb(self):
        self.db.addPhotosToDb(listOfFiles) #the list is gotten from a dialog box generated elsewhere in the mainwindow class code


def main():
    app = QtGui.QApplication(sys.argv)
    form = MainWindow()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python qt oop pyqt


    【解决方案1】:

    在 MainWindow 的 __init__() 方法中移动 db = photoDb(self)

    【讨论】:

    • 您需要通过向构造函数添加参数来将主窗口传递给 photoDb。当您调用 photoDb(self) 时,photoDb 类中的 __init__ 方法实际上是使用 2 个参数调用的:新的 photoDb 实例和主窗口实例。
    • 谢谢!我还需要将传递的对象名称存储到 db 的 __initi__() 方法中的 self. 变量中,以便 db 类中的其他方法可以使用它。现在对我来说这一切似乎都是显而易见的。非常感谢您的耐心和善意的指点。
    【解决方案2】:

    感谢@Gribouillis 为我指明了正确的方向。这是有效的。

    1. 将db对象的实例化放入主窗口的__init__()方法中,确保self.在db对象的名称之前,以便主窗口类中的其他方法可以访问db对象。

    2. 在 db 对象中,确保将主窗口的 ID(在调用 db 对象时传递)分配给 self。变量,所以__init__() 类之外的方法也可以访问它。

    这是有效的代码:

    class photoDb(): 
    
        def __init__(self, mainwindow): #mainwindow is the name passed from the main object
            self.db = []
            self.mainwindow = mainwindow #store name of calling object so other methods in this class can use it
    
    
        def addPhotosToDb(self, filenames):
            i = 0
            for f in filenames:
            (do a bunch of stuff here with f)
            self.db.append(f)
            self.mainwindow.updateProgressBar(int(100*i/len(filenames))
    
    
    class MainWindow(QtGui.QMainWindow, photoOrg_MainWindow.Ui_MainWindow):
    
        def __init__(self):
            super(self.__class__, self).__init__()
            self.setupUi(self) 
            self.db =photoDb(self) #passing self lets the photoDb object store the calling object's name
            (lots more GUI widget connection code here)
    
        def updateProgressBar(self, percentage):
            self.progressBar.setValue(percentage)
    
        def addPhotosToDb(self):
            self.db.addPhotosToDb(listOfFiles) #the list is gotten from a dialog box generated elsewhere in the mainwindow class code
    
    def main():
        app = QtGui.QApplication(sys.argv)
        form = MainWindow()
        form.show()
        app.exec_()
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 您忘记了第一个 __init__(self, mainwindow) 中的主窗口。 class photoDb(...)中应该没有参数
    • @Gribouillis:再次感谢。我已经修复了答案中的代码。
    猜你喜欢
    • 2014-01-14
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多