Issue
I'm using Qt Designer and trying to promote a subclass QLabel
. I created a ui.file and tried to load it with the individual Label. The code (main.py
file) looks like this:
from PyQt5.QtWidgets import *
from PyQt5 import uic
import os
import sys
class MyDialog(QDialog):
def __init__(self):
super(MyDialog, self).__init__()
uic.loadUi(os.path.join(basedir, "gui", "Test.ui"))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyDragDropWindow()
window.setGeometry(800, 100, 1000, 800)
window.show()
sys.exit(app.exec_())
The corresponding code of MyLabel
is:
from PyQt5.QtWidgets import *
class MyLabel(QLabel):
def __init__(self):
super(MyLabel).__init__()
When running the code, the following error occurs: TypeError: __init__() takes 1 positional argument but 2 were given
.
The promoting window looks like this:
The MyLabel
file is located in the MyWidgets
folder, which is in the same folder as the main.py
file.
This solution does not work.
Solution
All QWidget based classes always accept a keyword argument for their parent, which defaults to None
.
The UI loader always creates widgets with their parent as argument.
While, for most situations, it's normally enough to just declare the __init__
with a single "parent" positional argument, it's considered best practice to always use the *args, **kwargs
signature for both the function definition and the super call (as long as the arguments respect the base class constructors).
class MyLabel(QLabel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
In case you need custom arguments for dynamically created widgets, then you have different choices, considering that the first argument will always be the parent:
- define a specific signature, like
def __init__(self, parent, someArg, [...][, *args][, **kwargs]):
and thensuper().__init__(parent)
; - (better) use keyworder/named arguments, and, in that case:
- if you declare named arguments, always use a default
parent=None
as first argument; - pop other possible keyworded arguments from
kwargs
before calling the base implementation; - use keyworded arguments for custom Qt properties through the
pyqtProperty
(Property
for PySide) decorator or function, but also remember that they will always be set in thesuper().__init__()
call, so if there's anything that's required to the processing of those arguments happens after that, you need to pop those values fromkwargs
and eventually set the property afterwards;
- if you declare named arguments, always use a default
Note: since Python 3, super()
doesn't normally need any argument, but if you specify them, they have to be correct: super(MyLabel).__init__()
is wrong, as the instance must be declared along with the class in order to properly resolve the initialization: you either do super(MyLabel, self).__init__()
or you just use the default and normally suggested super().__init__()
.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.