Как PyQt понимает, что наш класс наследует от чего-то? - PullRequest
0 голосов
/ 17 апреля 2019

Недавно я много копался в PyQt и работал с ним, но внезапно понял, что не понимаю некоторых основных сотрудников, которые я выполнял.Как класс, который наследует, скажем, от QGraphicsView, становится сам QGraphicsView или как он становится QWidget?Также, насколько я понимаю, когда вы наследуете что-то, класс просто получает все методы из класса, который вы наследуете.Вот некоторый код ниже:

import PyQt5.QtWidgets as QtWidgets
import PyQt5.QtCore as QtCore


class First(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(First, self).__init__(parent)
        print('hello')

class Window(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.window = 'test'
        self.title = 'test'
        self.size = (1000, 650)
        self.create()

    def create(self):
        self.setWindowTitle(self.title)
        self.resize(QtCore.QSize(*self.size))
        self.graphicsWidget = First(self)

        self.mainLayout = QtWidgets.QVBoxLayout( )
        self.mainLayout.addWidget(self.graphicsWidget)
        self.setLayout(self.mainLayout)

if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    window = Window( )
    window.setGeometry(500, 300, 800, 600)
    window.show( )
    sys.exit(app.exec_( ))

Например, в этом коде я создал класс с именем 'First', и он наследуется от QtWidgets.QGraphicsView, а затем я добавляю его как виджет в mainLayout в моем классе Окна.До сих пор я воспринимал это как должное и не особо задумывался об этом, но может ли кто-нибудь объяснить мне, как мой mainLayout.addWidget(), принимающий только QWidgets, понимает, что перед ним QWidget?Потому что если вы сделаете print(type(First)), это даст <class 'sip.wrappertype'> не виджет.Спасибо

Ответы [ 2 ]

2 голосов
/ 17 апреля 2019

Наследование направлено на специализацию класса, то есть унаследованный класс должен обладать определенными характеристиками того класса, от которого он наследует.


QGraphicsView - это QWidget, потому что, если вы создадите диаграмму целостности QGraphicsView:

┌--------------┐   ┌--------------┐ 
|   QObject    |   | QPaintDevice |
└------┬-------┘   └-------┬------┘ 
       |                   |
       └---------┬---------┘
                 |
          ┌------┴------┐
          |   QWidget   |
          └------┬------┘
                 |
          ┌------┴------┐
          |   QFrame    |
          └------┬------┘
                 |
       ┌---------┴---------┐
       |QAbstractScrollArea|
       └---------┬---------┘
                 |
       ┌---------┴---------┐
       |   QGraphicsView   |
       └-------------------┘

Из этого следует, что:

  • QGraphicsView - это QAbstractScrollArea.
  • QGraphicsView - это QFrame.
  • QGraphicsView - это QWidget.
  • QGraphicsView - это объект QObject.
  • QGraphicsView - это QPaintDevice.

Почему print(type(First)) возвращает <class 'sip.wrappertype'>?

Если рассматриваются документы :

[...]
SIP реализует два супертипа, sip.simplewrapper и sip.wrapper и мета-тип, sip.wrappertype.

sip.simplewrapper - супер-тип sip.wrapper. Супер-тип sip.simplewrapper это объект.

sip.wrappertype - это мета-тип как sip.simplewrapper, так и sip.wrapper. Супертипом sip.wrappertype является тип.

sip.wrapper поддерживает концепцию владения объектом, описанную в Владение объектами и, по умолчанию, является супертипом всех типы, которые генерирует SIP.
[...]

Из этого следует, что sip.wrappertype является метаклассом QObject. И это то, что вы делаете, так как type(FooClass) возвращает метакласс FooClass.

Если вы хотите напечатать класс, вы должны использовать объект:

print(type(self.graphicsWidget))

Выход:

<class '__main__.First'>

Чтобы определить, что объект принадлежит к классу (или его родительским классам), вы можете использовать следующие методы, например, если это QWidget:

1.

if isinstance(obj, QtWidgets.QWidget):
    print("is QWidget")

2. Если это QObject

2,1

if qobject.inherits("QWidget"):
    print("is QWidget")

2,2

if qobject.isWidgetType():
    print("is QWidget")
1 голос
/ 17 апреля 2019

Экземпляр First() также является экземпляром QtWidgets.QGraphicsView именно потому, что вы так сказали, т.е. вы сделали класс наследованным от QtWidgets.QGraphicsView.Вы можете проверить это:

f = First()
isinstance(f, QtWidgets.QGraphicsView)  # True

Поскольку QtWidgets.QGraphicsView в свою очередь наследует от QtWidgets.QWidget, верно также следующее:

isinstance(f, PyQt5.QtWidgets.QWidget)

Таким образом, addWidget с радостью принимает экземпляркак QWidget.(Обратите внимание, что addWidget не нужно выполнять явную проверку типов в полученном экземпляре. Код может работать исключительно из-за того, что экземпляр «крякает как утка», т. Е. Имеет соответствующие методы QWidget).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...