我有一个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()
答案 0 :(得分:2)
您的问题从第
行开始self.MyButton.clicked.connect(lambda: widgetWindow.start(self))
让我们解构这是在做什么。
您有一个按钮self.MyButton
,它存在于类MainWindow
的实例中(您在main()
函数中实例化该类)
您正在连接按钮的clicked
信号。
您连接到此信号的功能是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()
答案 1 :(得分:-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()
您的命名空间错误。您必须确保使用正确的命名空间,否则解释器不知道查找该类的正确位置。