Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Converting c++ class to python class



  • I 'm trying to convert a c++ class to python class.

    My class 's c++ code (in epnccombomodel.cpp file):

    #include "epnccombomodel.h"
     
    EPNCComboModel::EPNCComboModel(QObject *parent) : QAbstractProxyModel(parent)
    {
    }
    

    My class 's python code (in epnccombo.py file):

    from PyQt4.QtCore import QObject
    from PyQt4.QtGui import QAbstractProxyModel
     
     
    class EPNCComboModel(QObject) :
        def __init__(self, parent):
            QAbstractProxyModel(EPNCComboModel, self).__init__(parent)
    

    But I get an error (TypeError: init() missing 1 required positional argument: 'parent') on initialization.
    I initialize it this way: EPNCproxyModel = EPNCComboModel()

    First of all, this line: EPNCComboModel::EPNCComboModel(QObject *parent) : QAbstractProxyModel(parent)
    What exactly is it saying?
    "Create a Class deriving from QObject"? (child of QObject)
    And variable 'parent' equals to this QObject?


  • Lifetime Qt Champion

    Hi,

    Do you mean you just want to translate or do you want to create a wrapper on top of your C++ code ?


  • Qt Champions 2019

    @Panoss said in Converting c++ class to python class:

    def init(self, parent)

    Your constructor requires a non optional parameter, so you have to give one:

    EPNCproxyModel = EPNCComboModel(some_parent_object)
    

    Parent can be nullptr in C++ if you do not want to have a parent by default (but you can still provide one if needed):

    EPNCComboModel(QObject *parent=nullptr)
    

    In this case you can omit parent.
    In Python:

    def __init__(self, parent=None):
    

    Read this about child/parent: http://doc.qt.io/qt-5.9/objecttrees.html



  • @SGaist said in Converting c++ class to python class:

    Hi,

    Do you mean you just want to translate or do you want to create a wrapper on top of your C++ code ?

    Not a wrapper of C++.
    I want to create a python class that will behave excactly like my C++ function.
    So I thought the best way would be to 'translate' C++ to Python.

    Up to here, I think we are ok:

    class EPNCComboModel(QObject):
        def __init__(self, parent=None):
    

    But QAbstractProxyModel has to 'get into the game' somehow.


  • Lifetime Qt Champion

    No you're not. Why doesn't EPNCComboMode inherit QAbstractProxyModel ?



  • This is what I finally did, I made my class inherit QAbstractProxyModel.

    Now, another part of the class' code.
    How do I 'translate' this:

    QModelIndex EPNCComboModel::mapFromSource(const QModelIndex & sourceIndex) const
    

    to python?

    The hard part for me is this: QModelIndex & sourceIndex
    Maybe in python becomes??:

    sourceIndex
    

  • Lifetime Qt Champion

    It's then just

    mapped = model.mapFromSource(sourceIndex)
    

    [edit: Fixed variable name SGaist]



  • Hi SGaist.
    what is map.p?

    I think the correct code is:

    def mapToSource(self, proxyIndex):
    

    It seems to work. ('self' is like 'this' in C++. It's used (in a class' function) in order to refer to the class)


  • Lifetime Qt Champion

    That was a typo.

    Indeed the python function signature is def mapToSource(self, proxyIndex):.



  • How about this?
    This is from optiongroup.h file:

    class OptionGroup : public QWidget
    {
    Q_OBJECT
    Q_PROPERTY(int currentSelection READ currentSelection WRITE setCurrentSelection USER true)
    

    This is from optiongroup.cpp file:

    OptionGroup::OptionGroup(QWidget *parent) :QWidget(parent), currentSelection_(-1)
    {
    }
    

    How can I convert it to python?



  • How does this look? Am I on the right way?

    class OptionGroup(QtGui.QWidget) :
        def __init__(self, parent):
            super(OptionGroup, self).__init__(parent)
            self.currentSelection_ = -1
            self.currentSelection = pyqtProperty(int, self.getCurrentSelection, self.setCurrentSelection)
    

    So this:

    Q_PROPERTY(int currentSelection READ currentSelection WRITE setCurrentSelection USER true)
    

    equals to this?

    self.currentSelection = pyqtProperty(int, self.getCurrentSelection, self.setCurrentSelection)
    

  • Lifetime Qt Champion

    You have an example in the PyQt5 documentation.



  • The instances of this class are mapped to a QWidgetDataMapper.
    The problem is that it seems that they don't 'bind' to the QWidgetDataMapper.

    In the C++ class, I think, that this job does this line:

    OptionGroup::OptionGroup(QWidget *parent) :QWidget(parent), currentSelection_(-1)
    

    I think it means: 'set property for mapping the property named "currentSelection_" '.

    So I think (again :) ) that my problem is that I can't do the same in Python.


  • Lifetime Qt Champion

    You have to mark the property as USER like explained in the QDataWidgetMapper documentation.



  • I changed this line from:

    currentSelection = pyqtProperty(int, currentSelection, setCurrentSelection)
    

    ...to:

    currentSelection = pyqtProperty(int, currentSelection, setCurrentSelection, user = True)
    

    and it works! I can't believe I was struggling for so many days for 2 f***ng words!

    SGaist you can't imagine how much you helped me. THANK YOU!


Log in to reply