Skip to content

super() does not work for Qt classes #39

Description

@usiems

I just want to share some insights into this issue, I currently have no intention to fix the issue, as that would be somewhat complicated.

This is an example of what does not work:

from PythonQt.QtGui import QDoubleValidator

class MyFunnyValidator(QDoubleValidator):
  def setRange(self, minimum, maximum, decimals):
    super().setRange(minimum, maximum, decimals+1)

The problem boils down to the fact that the method lookup of super() directly accesses the internal tp_dict member of the super classes, which is only filled to an absolute minimum by PythonQt (for performance reasons). Everything else is delivered through tp_getattro calls, but this does not work for super.

I discussed with Florian Link what would have to be done to fill the tp_dict.

  • This would probably need to happen in PythonQtInstanceWrapper_init the first time an instance of the class is created.
  • One could have a look at PythonQtClassWrapper_getattro how this is done, where the __dict__ member is dynamically filled.
  • But one would have to have in mind that QObject class wrappers can get updated methods when, e.g., the Qt bindings are loaded, so the class tp_dict would have to be updated then or at least flushed.
  • There might be other unforeseen consequences.

We both agreed that this change is somewhat tricky and probably currently not worthwhile.

Activity

  1. tonka3000 commented on Oct 26, 2023

    @tonka3000
    Contributor

    @usiems Is there any known workaround on the python-code side for this?

  2. usiems commented on Oct 27, 2023

    @usiems
    ContributorAuthor

    When taking the above example, you can always do
    QDoubleValidator.setRange(self, minimum, maximum, decimals+1)
    instead.

  3. tonka3000 commented on Oct 27, 2023

    @tonka3000
    Contributor

    I had a problem yesterday with sizeHint from QWidget. I was aware of the variant you described for QDoubleValidator but I had problems with a property.

    My Class is a simple Code block which should resize the content of the text.

    Here is a rough version (not working 100% for the resize).

    class Code(QPlainTextEdit):
        def __init__(self, parent=None):
            super(Code, self).__init__(parent)
    
       def heightForWidth(self):
            # some calc here
            return 30
    
        def sizeHint(self):
            original_hint = super(QWidget, self).sizeHint # does not work as described in the description of the issue
            original_hint = QPlainTextEdit.sizeHint(self) # exception: QSize object no callable
            original_hint = QPlainTextEdit(self).sizeHint # the only which seems to work
            
            return QSize(original_hint.width(), self.heightForWidth(original_hint.width()))

    original_hint = QPlainTextEdit(self).sizeHint # the only which seems to work was the only version which was working or in other words don't throw an exception. It creates a second QPlainTextEdit as far as I can see.

    What iss the correct way to get a property?

  4. usiems commented on Oct 27, 2023

    @usiems
    ContributorAuthor

    QPlainTextEdit(self).sizeHint
    is probably not what you want; this should create a new QPlainTextEdit with your instance as the parent.
    QPlainTextEdit.sizeHint(self)
    would be the correct solution, but PythonQt seems to treat sizeHint like a property, though only instances have properties, not their classes. I wonder which QSize is returned here. Anyway, I consider this a bug, but no promises by me if and when this will be fixed.

    So, I believe there is currently no way to do this correctly for properties.

  5. tonka3000 commented on Oct 27, 2023

    @tonka3000
    Contributor

    @usiems Thanks for looking into this. QPlainTextEdit.sizeHint(self) was also my logical answer, good to know that this should be right. I'm not on the latest PythonQt version, so I will migrate and will try again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions