Невозможно получить доступ к определению в подокне — объект MainWindow не имеет атрибута «updateTime»

У меня есть MainWindow, в котором я вызываю подокно (всплывающее окно) с помощью кнопки, и я не могу получить доступ к def updateTime (self), и это дает мне ошибку атрибута:

AttributeError: объект «MainWindow» не имеет атрибута «updateTime»

Если я удалю раздел MainWindow, он отлично работает, поэтому я действительно не понимаю, в чем проблема. Любая помощь будет принята с благодарностью.

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

person user3723727    schedule 23.08.2015    source источник


Ответы (2)


Попробуй это:

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

У вас было неправильное пространство имен. Вы должны убедиться, что используете правильное пространство имен, иначе интерпретатор не знает, где правильно искать класс.

person dsgdfg    schedule 23.08.2015

Ваша проблема начинается со строки

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

Давайте разберем, что это делает.

  1. У вас есть кнопка self.MyButton, которая существует в экземпляре класса MainWindow (вы создаете экземпляр класса в функции main())

  2. Вы подключаетесь к сигналу clicked кнопки.

  3. Функция, которую вы подключаете к этому сигналу, является функцией lambda, которая вызывает функцию класса widgetWindow. Обратите внимание, что это отличается от вызова метода экземпляра класса. Здесь вы не создаете экземпляр класса (вы не создаете объект). Вы говорите, используйте определение метода start в классе widgetWindow, но заставьте его воздействовать на объект self, где self является экземпляром класса MainWindow.

Надеюсь, теперь вы начинаете видеть проблему в том, что вы сделали. Вместо создания экземпляра вашего класса widgetWindow вы попытались использовать метод из widgetWindow, как если бы это был метод MainWindow. Я бы посоветовал прочитать больше об объектно-ориентированном программировании на Python, чтобы понять это, если у вас все еще есть проблемы (особенно если вы не понимаете различия между классом и объектом)

Таким образом, решение состоит в том, чтобы создать экземпляр widgetWindow (вместо прямого доступа к методам класса) и подключить вашу кнопку к методу этого экземпляра. Я изменил ваш код, чтобы сделать это, который размещен ниже. Я прокомментировал разделы, которые я изменил. Если у вас есть вопросы о том, что я сделал, дайте мне знать.

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()
person three_pineapples    schedule 23.08.2015