在Pyside/PyQt中从子部件调用父方法

8
我试图从子类中调用父类的一个方法。具体来说,我的父类是一个PySide.QtGui.QMainWindow对象,而我的子类是一个PySide.QtGui.QWidget对象;后者被设置为前者的中央小部件。我试图将子类中的一个按钮连接到父类中的一个方法。在过去,我曾经使用self.parent().method_name成功实现了这一点,但在下面的示例中它不起作用,我不明白为什么:
import sys
from PySide import QtGui, QtCore


class MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.do_something() #sanity check
        self.cw = ChildWidget()
        self.setCentralWidget(self.cw)
        self.show()

    def do_something(self):

        print 'doing something!'


class ChildWidget(QtGui.QWidget):

    def __init__(self):
        super(ChildWidget, self).__init__()

        self.button1 = QtGui.QPushButton()
        self.button1.clicked.connect(self.do_something_else)

        self.button2 = QtGui.QPushButton()
        self.button2.clicked.connect(self.parent().do_something)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.button1)
        self.layout.addWidget(self.button2)
        self.setLayout(self.layout)
        self.show()

    def do_something_else(self):

        print 'doing something else!'


def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

这里是错误信息:

self.button2.clicked.connect(self.parent().do_something)
AttributeError: 'NoneType' object has no attribute 'do_something'
2个回答

8
你从未将你的 `MainWindow` 设置为 `ChildWidget` 的父对象。 因此,`self.parent()` 的值为 `None`,因此没有 `do_something` 函数可用。
尝试:
import sys
from PySide import QtGui, QtCore


class MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.do_something() #sanity check
        self.cw = ChildWidget(self)
        self.setCentralWidget(self.cw)
        self.show()

    def do_something(self):

        print 'doing something!'


class ChildWidget(QtGui.QWidget):

    def __init__(self, parent):
        super(ChildWidget, self).__init__(parent)

        self.button1 = QtGui.QPushButton()
        self.button1.clicked.connect(self.do_something_else)

        self.button2 = QtGui.QPushButton()
        self.button2.clicked.connect(self.parent().do_something)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.button1)
        self.layout.addWidget(self.button2)
        self.setLayout(self.layout)
        self.show()

    def do_something_else(self):

        print 'doing something else!'


def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

我不理解在def __init__(self, parent):super(ChildWidget, self).__init__(parent)中的_parent_是什么?它在哪里定义?它是从self.cw = ChildWidget(self)的隐式父窗口MainWindow吗? - Hrvoje T
1
这就是如何设置父级。ChildWidget实例化时使用父级self(即MainWindow的实例)。起初,我对Python中基类的概念和Qt中父子关系的概念感到困惑。 - sammosummo

5

以下是可用的代码:

import sys
from PySide import QtGui, QtCore


class MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.do_something() #sanity check
        self.cw = ChildWidget(self)
        self.setCentralWidget(self.cw)
        self.show()

    def do_something(self):

        print 'doing something!'


class ChildWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(ChildWidget, self).__init__(parent=parent)

        self.button1 = QtGui.QPushButton()
        self.button1.clicked.connect(self.do_something_else)

        self.button2 = QtGui.QPushButton()
        self.button2.clicked.connect(self.parent().do_something)

        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.button1)
        self.layout.addWidget(self.button2)
        self.setLayout(self.layout)
        self.show()

    def do_something_else(self):

        print 'doing something else!'


def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Hopes, can help you.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接