代码之家  ›  专栏  ›  技术社区  ›  user3723727

无法在子窗口中访问“def”-“MainWindow对象没有属性'updateTime'”

  •  0
  • user3723727  · 技术社区  · 9 年前

    我有一个MainWindow,我从一个按钮调用一个子窗口(弹出),我无法访问defupdateTime(self),它给我一个属性错误:

    AttributeError:“MainWindow”对象没有属性“updateTime”

    如果我去掉主窗口部分,它工作得很好,所以我真的不明白问题是什么。如果能提供任何帮助,我将不胜感激。

    from PyQt4 import QtGui, QtCore
    from PyQt4 import *
    from PyQt4.QtCore import *
    import sys
    
    CurrentTime = 0
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            self.central = QtGui.QWidget(self)
            self.setCentralWidget(self.central)
    
            self.hboxPB = QtGui.QHBoxLayout()
            self.vboxPB = QtGui.QVBoxLayout()
            self.MyButton = QtGui.QPushButton(self.central)
            self.MyButton.setText("Push Me")
            self.hboxPB.addWidget(self.MyButton)
            self.vboxPB.addLayout(self.hboxPB)
            self.MyButton.resize(90,90)
            self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
    
    class widgetWindow(QtGui.QWidget):
        def __init__(self, parent = None):
            QtGui.QWidget.__init__(self,parent)
            super(widgetWindow, self).__init__()
            widgetWindow.start(self)
    
        def start(self):
            window = QtGui.QMainWindow(self)
            window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
            CentralWidget = QtGui.QWidget()
            self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
            CentralWidgetLayout = QtGui.QHBoxLayout()
            VBox = QtGui.QVBoxLayout()
            CentralWidgetLayout.addWidget(self.timeSlider)
            VBox.addLayout(CentralWidgetLayout)
            CentralWidget.setLayout(VBox)
            window.setCentralWidget(CentralWidget)
            window.show()
    
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self.updateTime)
            self.timer.start(1000)
    
        def updateTime(self):
            global CurrentTime
            CurrentTime = CurrentTime + 1
            self.timeSlider.setValue(CurrentTime)
    
    def main():
        app = QtGui.QApplication(sys.argv)
        win = MainWindow()
        win.show()
        win.resize(800,450)
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   three_pineapples    9 年前

    你的问题从这行开始

    self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
    

    让我们去构造它在做什么。

    1. 你有一个按钮, self.MyButton 它存在于类的实例中 MainWindow (在 main() 功能)

    2. 您正在连接到 clicked 按钮的信号。

    3. 连接到此信号的函数是 lambda 功能 调用类中的函数 widgetWindow 注意,这与调用类实例的方法不同。您没有在此处实例化类(您没有创建对象)。你是说,使用方法定义 start 在课堂上 小部件窗口 但使其作用于对象 self 哪里 自己 是类的实例 主窗口 .

    希望你现在开始看到你所做的事情的问题。而不是创建 小部件窗口 类,您尝试使用 小部件窗口 好像这是一种 主窗口 。如果您仍然有困难(尤其是如果您不清楚类和对象之间的区别),我建议您阅读更多关于Python中面向对象编程的内容,以了解这一点

    因此,解决方案是创建 小部件窗口 (而不是直接访问类的方法),并将按钮连接到该实例的方法。我已经修改了你的代码来实现这一点,这在下面发布。我已经对我更改的部分进行了评论。如果你对我的所作所为有疑问,请告诉我。

    from PyQt4 import QtGui, QtCore
    from PyQt4 import *
    from PyQt4.QtCore import *
    import sys
    
    CurrentTime = 0
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            self.central = QtGui.QWidget(self)
            self.setCentralWidget(self.central)
    
            self.hboxPB = QtGui.QHBoxLayout()
            self.vboxPB = QtGui.QVBoxLayout()
            self.MyButton = QtGui.QPushButton(self.central)
            self.MyButton.setText("Push Me")
            self.hboxPB.addWidget(self.MyButton)
            self.vboxPB.addLayout(self.hboxPB)
            self.MyButton.resize(90,90)
    
            # instantiate the widgetWindow (pass this window as the parent)
            self.widgetwindow = widgetWindow(self)
            # connect the button to the start method of this instance we created above
            self.MyButton.clicked.connect(self.widgetwindow.start)
    
    # no need to subclass QWidget here. This is just a wrapper class to hold your main window
    class widgetWindow(object):
        def __init__(self, parent = None):
            # Store the parent for use later
            self.parent = parent
    
        def start(self):
            # change the window parent to be the parent we stored in the __init__ method
            window = QtGui.QMainWindow(self.parent)
            window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
            # Add a signal to stop the timer when the window is destroyed
            window.destroyed.connect(self.stopTimer)
            CentralWidget = QtGui.QWidget()
            # Change the parent to be the window we just created
            self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, window)
            CentralWidgetLayout = QtGui.QHBoxLayout()
            VBox = QtGui.QVBoxLayout()
            CentralWidgetLayout.addWidget(self.timeSlider)
            VBox.addLayout(CentralWidgetLayout)
            CentralWidget.setLayout(VBox)
            window.setCentralWidget(CentralWidget)
            window.show()
    
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self.updateTime)
            self.timer.start(1000)
    
        def updateTime(self):
            global CurrentTime
            CurrentTime = CurrentTime + 1
            self.timeSlider.setValue(CurrentTime)
    
        # Method to stop the timer once the window is destroyed
        def stopTimer(self):
            self.timer.stop()
    
    def main():
        app = QtGui.QApplication(sys.argv)
        win = MainWindow()
        win.show()
        win.resize(800,450)
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    
        2
  •  -2
  •   GEOCHET S.Lott    9 年前

    试试看:

    from PyQt4 import QtGui, QtCore
    from PyQt4 import *
    from PyQt4.QtCore import *
    import sys
    
    CurrentTime = 0
    class widgetWindow(QtGui.QWidget):
        def __init__(self, parent = None):
            QtGui.QWidget.__init__(self,parent)
            super(widgetWindow, self).__init__()
            widgetWindow.start(self)
    
        def start(self):
            window = QtGui.QMainWindow(self)
            window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
            CentralWidget = QtGui.QWidget()
            self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
            CentralWidgetLayout = QtGui.QHBoxLayout()
            VBox = QtGui.QVBoxLayout()
            CentralWidgetLayout.addWidget(self.timeSlider)
            VBox.addLayout(CentralWidgetLayout)
            CentralWidget.setLayout(VBox)
            window.setCentralWidget(CentralWidget)
            window.show()
    
            self.timer = QtCore.QTimer()
            self.timer.timeout.connect(self.updateTime)
            self.timer.start(1000)
    
        def updateTime(self):
            global CurrentTime
            CurrentTime = CurrentTime + 1
            self.timeSlider.setValue(CurrentTime)
    
    
    
    class MainWindow(QtGui.QMainWindow,widgetWindow):#here add subclass
        def __init__(self, parent=None):
            QtGui.QMainWindow.__init__(self, parent)
            self.central = QtGui.QWidget(self)
            self.setCentralWidget(self.central)
    
            self.hboxPB = QtGui.QHBoxLayout()
            self.vboxPB = QtGui.QVBoxLayout()
            self.MyButton = QtGui.QPushButton(self.central)
            self.MyButton.setText("Push Me")
            self.hboxPB.addWidget(self.MyButton)
            self.vboxPB.addLayout(self.hboxPB)
            self.MyButton.resize(90,90)
            self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
    
    
    
    def main():
        app = QtGui.QApplication(sys.argv)
        win = MainWindow()
        win.show()
        win.resize(800,450)
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

    您的命名空间错误。必须确保使用正确的命名空间,否则解释器不知道查找类的正确位置。