[PyQt] How to add an argument to derived class's constructor

J Barchan jnbarchan at gmail.com
Mon Feb 18 16:51:41 GMT 2019


On Thu, 14 Feb 2019 at 17:48, J Barchan <jnbarchan at gmail.com> wrote:

>
>
> On Thu, 14 Feb 2019 at 14:56, Vincent Vande Vyvre <
> vincent.vande.vyvre at telenet.be> wrote:
>
>> Le 14/02/19 à 14:56, J Barchan a écrit :
>>
>>
>>
>> On Thu, 14 Feb 2019 at 13:34, J Barchan <jnbarchan at gmail.com> wrote:
>>
>>> This may be as much a Python question as a PyQt one.  I come from a C++
>>> background.  I do not understand the syntax/code I need in a class I am
>>> deriving from a PyQt class to allow a new parameter to be passed to the
>>> constructor.
>>>
>>> I see that I asked this question a long time ago at
>>> https://stackoverflow.com/questions/45999732/python3-typing-overload-and-parameters
>>> but never got an answer.
>>>
>>> I now want to sub-class from QListWidgetItem.  That starts with these
>>> constructors:
>>>
>>> QListWidgetItem(QListWidget *parent = nullptr, int type = Type)
>>> QListWidgetItem(const QString &text, QListWidget *parent = nullptr, int
>>> type = Type)
>>> QListWidgetItem(const QIcon &icon, const QString &text, QListWidget
>>> *parent = nullptr, int type = Type)
>>> QListWidgetItem(const QListWidgetItem &other)
>>>
>>> My sub-class should still support these constructors.  In addition to
>>> the existing text, I want my sub-class to be able to store a new
>>> optional value. At minimum/sufficient I want a new possible constructor
>>> like one of the following:
>>>
>>> MyListWidgetItem(const QString &text, const QVariant &value, QListWidget
>>> *parent = nullptr, int type = Type)
>>> # or
>>> MyListWidgetItem(const QString &text, QVariant value = QVariant(), QListWidget
>>> *parent = nullptr, int type = Type)
>>>
>>> So for Python I know I start with a *typing overload* definition (for
>>> my editor) like
>>>
>>> @typing.overload
>>> def MyListWidgetItem(self, text: str, value: typing.Any, parent:
>>> QListWidget=None, type: int=Type)
>>>     pass
>>>
>>> Then I get to the *definition* bit.  To cater for everything am I
>>> supposed to do:
>>>
>>> def __init__(self, *__args)
>>>     # Now what??
>>>     super().__init__(__args)
>>>
>>> Is that how we do it?  Is it then my responsibility to look at __args[1]
>>> to see if it's my value argument?  And remove it from __args before
>>> passing it onto super().__init__(__args)?
>>>
>>> Or, am I not supposed to deal with __args, and instead have some
>>> definition with all possible parameters explicitly and deal with them like
>>> that?
>>>
>>> Or what?  This is pretty fundamental to sub-classing to add parameters
>>> where you don't own the code of what you're deriving from.  It's easy in
>>> C-type languages; I'm finding it real to hard to understand what I
>>> can/can't/am supposed to do for this, I'd be really gratefully for a couple
>>> of lines to show me, please...! :)
>>>
>>> --
>>> Kindest,
>>> Jonathan
>>>
>>
>> P.S.
>> I think I got my overload a bit mixed up.  I meant I (think I) will have:
>>
>> class MyListWidgetItem(QListWidgetItem)
>>     @typing.overload
>>     def __init__(self, text: str, value: typing.Any, parent:
>> QListWidget=None, type: int=Type)
>>         pass
>>
>>     def __init__(self, *__args)
>>         # Now what??
>>         super().__init__(__args)
>>
>>
>> --
>> Kindest,
>> Jonathan
>>
>> _______________________________________________
>> PyQt mailing list    PyQt at riverbankcomputing.comhttps://www.riverbankcomputing.com/mailman/listinfo/pyqt
>>
>> Hi,
>>
>> I use just that:
>>
>> class ListItem(QListWidgetItem):
>>     def __init__(self, img, text, parent=None):
>>         super().__init__(parent)
>>         icon = QIcon()
>>         icon.addPixmap(QPixmap(img), QIcon.Normal, QIcon.Off)
>>         self.setIcon(icon)
>>         self.setText(text)
>>
>> The arguments are examples, not mandatory.
>>
>> Vincent
>> _______________________________________________
>> PyQt mailing list    PyQt at riverbankcomputing.com
>> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>>
>
> Hello Vincent,
>
> Thank you for replying.  I'm afraid the suggestion you give is so
> significantly different from what I am asking that I don't see how it
> addresses it.  I could write a lot about the differences between what you
> show and what I am asking.  Here are some:
>
>    - I don't see that you're adding any argument that QListWidgetItem
>    does not already accept??  Please bear in mind there is already QListWidgetItem(const
>    QIcon &icon, const QString &text, QListWidget *parent = nullptr, int type =
>    Type).  I want to add a new argument.
>    - Your super().__init__() is not passing anything other than parent to
>    the base constructor, yet the base constructor accepts more arguments than
>    that, just like your derived class does.
>    - (untested) it seems to me that your code will break the existing QListWidgetItem(const
>    QIcon &icon, const QString &text, QListWidget *parent = nullptr, int type =
>    Type) constructor overload (i.e. what happens when I pass a QIcon() as
>    the img parameter to your ListItem constructor?)
>    - how does your code allow for the existing QListWidgetItem(const
>    QString &text, QListWidget *parent = nullptr, int type = Type) overload
>    - you are not using any typing hints so this will lose my editor's
>    context completion
>
> I don't know whether one of us is misunderstanding the other, or we're on
> different planes? :)
>
> --
> Kindest,
> Jonathan
>

May I politely try bumping this question?  I have had one answer, which as
far as I understand does not work.

How *exactly* could/would you derive from QListWidgetItem from Python to
add a "value" parameter in a constructor?   I could do it easily from C++.
It does seem to me this is at least partly a PyQt question, I've tried
asking it at
https://stackoverflow.com/questions/54746309/python-3-add-argument-when-subclassing-from-complex-arguments
,
I'm getting comments like "If PyQT makes it impossible to use common Python
idioms then I can't do much about it actually <g>" and "The OP needs to
have a re-think and accept that some compromises are inevitable when trying
to fake c++ idioms in pure python."

This is a bit above my head.  I'm either getting a generic answer which is
inadequate or no answer or told it may not be doable.  I don't understand
this.  Can someone tell me how to add the argument I have in mind, or
something similar (you do need to read through the precise example I am
asking about), or explain why it can't be done, or something?  I should be
so obliged!


-- 
Kindest,
Jonathan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20190218/692f3d7b/attachment-0001.html>


More information about the PyQt mailing list