Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-1232

Type issues when trying to mix C++ and Python classes.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Not Evaluated
    • None
    • 5.14.1
    • PySide, Shiboken
    • None
    • Linux/X11

    Description

      I believe this is fair to categorize as a bug, it certainly gives a worse Python wrapping experience compared to PyQt. The issue below demonstrates a particular problem when trying to set one widget as a parent of another but it exposes a more general problem of interoperability.

      Specifically, when embedding Python in a C++ application, if that application has Qt widgets the QWidget base class of those widgets is not the same as the base class of widgets created by Python.

      I am not providing any source code here because the issue can be replicated with the scriptedapplication example code provided with PySide2.  To follow along, you simply need to build that application and then post and execute the following snippets in the text editor window.

      First some setup:

      from PySide2 import QtWidgets
      
      def get_menu_bar():
          """Returns the only QMenuBar in the application."""
          for w in QtWidgets.QApplication.instance().allWidgets():
              if w.metaObject().className() == 'QMenuBar':
                  return w
      # create a new menu
      menu = QtWidgets.QMenu()
      # retrieve the menubar
      menuBar = get_menu_bar()
      

      Then you can try the following:

      menu.setParent(menuBar)
      

      You will then hit this traceback:

      Traceback (most recent call last):
        File "<string>", line 8, in <module>
      TypeError: 'PySide2.QtWidgets.QWidget.setParent' called with wrong argument types:
        PySide2.QtWidgets.QWidget.setParent(QMenuBar)
      Supported signatures:
        PySide2.QtWidgets.QWidget.setParent(PySide2.QtWidgets.QWidget)
        PySide2.QtWidgets.QWidget.setParent(PySide2.QtWidgets.QWidget, PySide2.QtCore.Qt.WindowFlags)
      

      You will notice that you do not get a traceback if you do the following instead:

      from shiboken2 import wrapInstance, getCppPointer
      menu.setParent(wrapInstance(getCppPointer(menuBar)[0], QtWidgets.QMenuBar))
      

      In tracking the above error down the issue is that isinstance(menuBar, QtWidgets.QWidget) is failing. The reason for that is that although menuBar inherits from QtWidgets.QWidget it is a different QtWidgets.QWidget that the one Python expects.

      Here is some more Python code to run to show the issue in more detail:

      print "menuBar", getattr(menuBar.__class__, '__bases__', None), issubclass(menuBar.__class__, QtWidgets.QWidget)
      print "menu", getattr(menu.__class__, '__bases__', None), issubclass(menu.__class__, QtWidgets.QWidget)
      
      print "id of first base class of menuBar", id(menuBar.__class__.__bases__[0])
      print "id of first base class of menu", id(menu.__class__.__bases__[0])
      print "id of QtWidgets.QWidget", id(QtWidgets.QWidget)
      

      This produces the following output:

      menuBar (<class 'PySide2.QtWidgets.QWidget'>,) False
      menu (<class 'PySide2.QtWidgets.QWidget'>,) True
      id of first base class of menuBar 36258560
      id of first base class of menu 43100800
      id of QtWidgets.QWidget 43100800
      

      This shows you the root issue that the id of the two base classes are different and therefore are not equal causing isinstance to fail.

      Ideally there would be only 1 instance of the PySide2.QtWidgets.QWidget class at runtime.

      Thank you for reading !

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              crmaurei Cristian Maureira-Fredes
              barry_rogerson Barry Rogerson
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes