I have a few questions regarding the pyqtProperty class of PyQt5 package, and the standard built-in property class of python:
Why use
pyqtPropertyover standard property? The codes given below works in both ways. What's the advantage of usingpyqtPropertyinstead of Python's plain oldproperty(used as a decorator on a method)? I know that I must specify the return type of apyqtProperty, but why would I want to use it?Does
pyqtPropertyinherits fromproperty? The attributepyqtProperty.__mro__does not show that (the result isPyQt5.QtCore.pyqtProperty, object) and I can't find a source code file ofpyqtProperty. PyDoc's command refers to a.pydfile of the modulePyQt5.QtCore(which is not a source code plain text file), and there is no stub file for it. But the commandhelp(pyqtProperty)gives me information very similar to the one get withhelp(property), different from the one found on the official documentaion. So, where that information comes from?Why the methods decorated with
@pyqtPropertyor even with@propertyare executed when the Qobject is set up?Back to the codes given below: the property methods (in the both cases
@pyqtPropertyand@property) are executed before creating the attribute_custom_property, which gives aAttributeError. But that should not happen, and really does not happen with@propertydecorator with regular python classes (I've tried that too, there's a snipet below). When I use simple getter and setter methods (not decorated), that doesn't happen at all (which is normal). The strangest phenomenon is: thisAttributeErroroccurs when I run in debug mode. In normal mode (python main.py) the property methods get executed anyway, but the error is not raised.
I'm using PyQt5 version 5.9.2 installed with Anaconda Distribution, python 3.8.
This is the contents of Ui_MainWindow.py file, generated with pyuic5:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(419, 196)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 419, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.lineEdit.setText(_translate("MainWindow", "test"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
This is the content of the main.py file using property decorator:
from Ui_MainWindow import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow,Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self._custom_property = 1
@property
def custom_property(self):
print("This method is executed")
return self._custom_property
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
This is the content of the main.py file using pyqtProperty decorator:
from Ui_MainWindow import Ui_MainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtProperty
class MainWindow(QMainWindow,Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self._custom_property = 1
@pyqtProperty(int)
def custom_property(self):
print("This method is executed")
return self._custom_property
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
I won't put the content of the main file with no decorator (just remove the @ lines in the code above).
But this is a simple file with property decorator showing it is not executed in the __init__ method
class Test:
def __init__(self) -> None:
pass
@property
def x(self):
print("This method is not executed in init")
return self._x
def setx(self,value):
self._x = value
if __name__ == "__main__":
a = Test()