无法访问子 window 中的 "def" - "MainWindow object has no attribute 'updateTime' "
Unable to acces a "def" in a sub window - "MainWindow object has no attribute 'updateTime' "
我有一个主窗口,我在其中通过按钮调用子窗口(弹出窗口),但我无法访问 def updateTime(self),它给我一个属性错误:
AttributeError: 'MainWindow' object has no attribute '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()
试试这个:
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()
您的命名空间有误。您必须确保使用正确的命名空间,否则解释器不知道在正确的位置查找 class.
您的问题始于行
self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
让我们解构它在做什么。
您有一个按钮 self.MyButton
,它存在于 class MainWindow
的实例中(您在 main()
函数)
您正在连接到按钮的clicked
信号。
您连接到此信号的函数是一个 lambda
函数,它 调用 class widgetWindow
[=48= 中的一个函数].请注意,这与调用 class 实例的方法不同。您没有在此处实例化 class (您没有创建对象)。您是说,在 class widgetWindow
中使用方法定义 start
但使其作用于对象 self
,其中 self
是 class MainWindow
.
希望您现在开始看到您所做的问题。您没有创建 widgetWindow
class 的实例,而是尝试使用 widgetWindow
的方法,就好像它是 MainWindow
的方法一样。如果您仍然遇到问题(特别是如果您不清楚 class 和对象之间的区别)
因此,解决方案是创建 widgetWindow
的实例(而不是直接访问 class 的方法),并将您的按钮连接到该实例的方法。我已经修改了您的代码来执行此操作,已在下面发布。我已经评论了我已经更改的部分。如果您对我所做的有任何疑问,请告诉我。
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()
我有一个主窗口,我在其中通过按钮调用子窗口(弹出窗口),但我无法访问 def updateTime(self),它给我一个属性错误:
AttributeError: 'MainWindow' object has no attribute '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()
试试这个:
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()
您的命名空间有误。您必须确保使用正确的命名空间,否则解释器不知道在正确的位置查找 class.
您的问题始于行
self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
让我们解构它在做什么。
您有一个按钮
self.MyButton
,它存在于 classMainWindow
的实例中(您在main()
函数)您正在连接到按钮的
clicked
信号。您连接到此信号的函数是一个
lambda
函数,它 调用 classwidgetWindow
[=48= 中的一个函数].请注意,这与调用 class 实例的方法不同。您没有在此处实例化 class (您没有创建对象)。您是说,在 classwidgetWindow
中使用方法定义start
但使其作用于对象self
,其中self
是 classMainWindow
.
希望您现在开始看到您所做的问题。您没有创建 widgetWindow
class 的实例,而是尝试使用 widgetWindow
的方法,就好像它是 MainWindow
的方法一样。如果您仍然遇到问题(特别是如果您不清楚 class 和对象之间的区别)
因此,解决方案是创建 widgetWindow
的实例(而不是直接访问 class 的方法),并将您的按钮连接到该实例的方法。我已经修改了您的代码来执行此操作,已在下面发布。我已经评论了我已经更改的部分。如果您对我所做的有任何疑问,请告诉我。
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()