在pyside/pyqt中从子组件调用父类方法

8 投票
2 回答
16968 浏览
提问于 2025-04-18 10:23

我想在一个子类里面调用父类的方法。具体来说,我的父类是一个 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 个回答

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

希望这能帮到你。

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

撰写回答