Qt.py icon indicating copy to clipboard operation
Qt.py copied to clipboard

wrapInstance: Search inheritance hierarchy for a suitable class

Open mitchellsimmons opened this issue 3 years ago • 2 comments

Hi, I would like to suggest a change to the implementation of QtCompat.wrapInstance.

Issue

In the current implementation, wrapInstance only checks if the direct superclass is a QtWidgets class. Therefore if the class has a deeper inheritance hierarchy you end up getting a QObject.

In the below example, a pointer to an instance of class B will return a QObject instead of a QDialog.

class A(QtWidgets.QDialog):
    pass
    
class B(A):
    pass

Implementation

I've made changes for when base is None. Here the loop will eventually find QObject if nothing more significant is found. Alternatively you could use while meta_object is not None and add an else clause to check if the loop broke but I don't think it is necessary.

def _wrapinstance(ptr, base=None):
    assert isinstance(ptr, long), "Argument 'ptr' must be of type <long>"
    assert (base is None) or issubclass(base, Qt.QtCore.QObject), (
        "Argument 'base' must be of type <QObject>")

    if Qt.IsPyQt4 or Qt.IsPyQt5:
        func = getattr(Qt, "_sip").wrapinstance
    elif Qt.IsPySide2:
        func = getattr(Qt, "_shiboken2").wrapInstance
    elif Qt.IsPySide:
        func = getattr(Qt, "_shiboken").wrapInstance
    else:
        raise AttributeError("'module' has no attribute 'wrapInstance'")

    if base is None:
        q_object = func(long(ptr), Qt.QtCore.QObject)
        meta_object = q_object.metaObject()

        while True:
            class_name = meta_object.className()

            try:
                base = getattr(Qt.QtWidgets, class_name)
            except AttributeError:
                try:
                    base = getattr(Qt.QtCore, class_name)
                except AttributeError:
                    meta_object = meta_object.superClass()
                    continue

            break

    return func(long(ptr), base)

mitchellsimmons avatar Sep 04 '20 00:09 mitchellsimmons

Yes, this is fantastic. Could you transform this into a PR? That way we can get tests running and hunt down any potential issue. The idea is sound, and from a glance it looks solid.

mottosso avatar Sep 04 '20 05:09 mottosso

Hey Marcus, I've added the PR. I'm a bit new to this so let me know if I there's anything wrong. Thanks

mitchellsimmons avatar Sep 04 '20 09:09 mitchellsimmons