diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b760748..851676a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ### Changed +* [#58](https://github.com/stlehmann/PyQt5-stubs/pull/50) improves QObject.findChild and findChildren * [#50](https://github.com/stlehmann/PyQt5-stubs/pull/50) fixes QTest QAbstractItemModelTester.FailureReportingMode attributes * [#46](https://github.com/stlehmann/PyQt5-stubs/pull/46) fixes QCoreApplication and QObject signals * [#48](https://github.com/stlehmann/PyQt5-stubs/pull/48) fixes some signals for QClipBoard, QWindows, QQuickView and QQml{Application,}Engine diff --git a/PyQt5-stubs/QtCore.pyi b/PyQt5-stubs/QtCore.pyi index 568a99dc..3df7c2fa 100644 --- a/PyQt5-stubs/QtCore.pyi +++ b/PyQt5-stubs/QtCore.pyi @@ -51,6 +51,9 @@ class pyqtSignal: PYQT_SLOT = typing.Union[typing.Callable[..., object], pyqtBoundSignal] +QObjectT = typing.TypeVar("QObjectT", bound="QObject") + + class QtMsgType(int): ... QtDebugMsg = ... # type: QtMsgType QtWarningMsg = ... # type: QtMsgType @@ -1801,21 +1804,21 @@ class QObject(sip.wrapper): def setObjectName(self, name: str) -> None: ... def objectName(self) -> str: ... @typing.overload - def findChildren(self, type: type, name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, type: typing.Type[QObjectT], name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List[QObjectT]: ... @typing.overload - def findChildren(self, types: typing.Tuple, name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, types: typing.Tuple[typing.Type[QObject], ...], name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... @typing.overload - def findChildren(self, type: type, regExp: 'QRegExp', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, type: typing.Type[QObjectT], regExp: 'QRegExp', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List[QObjectT]: ... @typing.overload - def findChildren(self, types: typing.Tuple, regExp: 'QRegExp', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, types: typing.Tuple[typing.Type[QObject], ...], regExp: 'QRegExp', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... @typing.overload - def findChildren(self, type: type, re: 'QRegularExpression', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, type: typing.Type[QObjectT], re: 'QRegularExpression', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List[QObjectT]: ... @typing.overload - def findChildren(self, types: typing.Tuple, re: 'QRegularExpression', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... + def findChildren(self, types: typing.Tuple[typing.Type[QObject], ...], re: 'QRegularExpression', options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.List['QObject']: ... @typing.overload - def findChild(self, type: type, name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> 'QObject': ... + def findChild(self, type: typing.Type[QObjectT], name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> typing.Optional[QObjectT]: ... @typing.overload - def findChild(self, types: typing.Tuple, name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> 'QObject': ... + def findChild(self, types: typing.Tuple[typing.Type[QObject], ...], name: str = ..., options: typing.Union[Qt.FindChildOptions, Qt.FindChildOption] = ...) -> 'typing.Optional[QObject]': ... def tr(self, sourceText: str, disambiguation: typing.Optional[str] = ..., n: int = ...) -> str: ... def eventFilter(self, a0: 'QObject', a1: 'QEvent') -> bool: ... def event(self, a0: 'QEvent') -> bool: ... diff --git a/tests/qobject.py b/tests/qobject.py new file mode 100644 index 00000000..c210fd31 --- /dev/null +++ b/tests/qobject.py @@ -0,0 +1,15 @@ +import typing + +from PyQt5 import QtCore +from PyQt5 import QtWidgets + + +q = QtCore.QObject() + +a = q.findChildren(QtCore.QObject) # type: typing.List[QtCore.QObject] +b = q.findChildren(QtWidgets.QWidget) # type: typing.List[QtWidgets.QWidget] +c = q.findChildren((QtCore.QObject,)) # type: typing.List[QtCore.QObject] +d = q.findChildren((QtWidgets.QWidget,)) # type: typing.List[QtCore.QObject] +# desired error +# Incompatible types in assignment (expression has type "List[QObject]", variable has type "List[QWidget]") +# e = q.findChildren((QtWidgets.QWidget,)) # type: typing.List[QtWidgets.QWidget]