вызов родительского метода из дочернего виджета в pyside/pyqt

Я пытаюсь вызвать метод родительского класса из дочернего класса. В частности, мой родительский класс — это объект 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'

person sammosummo    schedule 19.06.2014    source источник


Ответы (2)


Вы никогда не устанавливали свой 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()
person GuiTeK    schedule 19.06.2014
comment
Я не понимаю в def __init__(self, parent): и super(ChildWidget, self).__init__(parent) что такое parent? Где это определено? Это неявное MainWindow из self.cw = ChildWidget(self)? - person Hrvoje T; 16.08.2015
comment
Вот как вы устанавливаете родителя. Экземпляр ChildWidget инициализируется родительским self (т. е. экземпляром MainWindow). Сначала я запутался между концепцией базовых классов Python и концепцией родителей и детей Qt. - person sammosummo; 16.08.2018

Вот рабочий код:

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

Надежда, может вам помочь.

person Tok Soegiharto    schedule 19.06.2014