#python #pyqt #pyqt5
#python #pyqt #pyqt5
Вопрос:
Недавно я много копался в 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 внутри моего класса Window. До сих пор я принимал это как должное и не думал об этом много, но может кто-нибудь объяснить мне, как мой mainLayout.addWidget()
, который принимает только QWidgets , понимает, что перед ним QWidget? Потому что, если вы это сделаете print(type(First))
, это не даст <class 'sip.wrappertype'>
виджета. Спасибо
Ответ №1:
Наследование направлено на специализацию класса, то есть унаследованный класс должен обладать специфическими характеристиками, присущими классу, от которого он наследует.
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 является object .
sip.wrappert — это мета-тип как sip.simplewrapper, так и sip.wrapper . Супертипом sip.wrappert является type .
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")
Ответ №2:
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).