0

I am trying to convert a Qt4 custom widget written in C++ to a Python 2.7 custom widget. However, I have not been able to figure out how QLabel(parent) would be written in Python. This is the original C++ code from the ".ccp" file:

DocumentWidget::DocumentWidget(QWidget *parent)
    : QLabel(parent)
{
    currentPage = -1;
    setAlignment(Qt::AlignCenter);
}

The QLabel(parent) seems to be some sort of initializer list. I've tried using multiple inheritance in Python in parallel, but this leads to the following error: Cannot create a consistent method resolution order (MRO) for bases QLabel, QWidget.

I'm trying to port the code instead of creating a wrapper for the C++ widget, because I don't know C++ and think I will have to customize the widget further in the future.

I'm not trained as a programmer and this is the first day I ran into C++, so feel free to correct me even if I'm doing something silly. I will not feel embarrassed.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Colin Lee
  • 27
  • 5
  • That notation is for calling the base class's constructor ([like this](https://stackoverflow.com/questions/10282787/calling-the-base-class-constructor-in-the-derived-class-constructor)), so it would be equivalent to [calling `super. __init__`](https://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods) – Cory Kramer May 22 '15 at 11:39
  • Yes that looks about right. – Cory Kramer May 22 '15 at 14:57

2 Answers2

3

The code defines a constructor for the DocumentWidget class, which inherits QLabel and requires a QWidget as parent.

The equivalent PyQt code would be:

from PyQt4 import QtCore, QtGui

class DocumentWidget(QtGui.QLabel):
    def __init__(self, parent):
        super(DocumentWidget, self).__init__(parent)
        # or QtGui.QLabel.__init__(self, parent)
        self.currentPage = -1
        self.setAlignment(QtCore.Qt.AlignCenter)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Usually `parent` is optional, so it should be something like `def __init__(self, parent = None)`. – Pavel Strakhov May 23 '15 at 08:18
  • @PavelStrakhov. Yes, of course - but then it wouldn't be strictly equivalent (i.e. the C++ signature is not `QWidget * parent = 0`). There may be good reasons why it's currently not optional (maybe some methods require access to the parent). But in any case, I think the first stage of porting code should always be very conservative, and aim to be purely syntactic. That makes it much easier to spot regressions by testing the python version directly against the C++ original. Design changes can come later. – ekhumoro May 23 '15 at 15:43
  • With this approach, how do you pass QWidget as a parent? When I call `DocumentWidget(QWidget)` I get `argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType'` – Colin Lee May 24 '15 at 08:22
  • @ColinLee. You don't pass the *class*, you pass an *instance* of the class. So you might have a `QMainWindow` (which is a subclass of `QWidget`), with one of its methods creating instances of the document widget like this: `docwidget = DocumentWidget(self)`. – ekhumoro May 24 '15 at 15:17
0

Multiple inheritance worked, but the base classes had to be called in the correct order (i.e., DocumentWidget(QLabel, QWidget) instead of DocumentWidget(QLabel, QWidget)).

In full:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class DocumentWidget(QLabel, QWidget):
    def __init__(self, parent=None):
        super(DocumentWidget, self).__init__()
        self.currentPage = -1
        self.setAlignment(Qt.AlignCenter)
Colin Lee
  • 27
  • 5
  • This code is wrong, and only "works" because `QLabel` is a subclass of `QWidget`. Qt almost exclusively uses *single* inheritance, so you should never try to use multiple inheritance in PyQt. Most of the time, doing so will just produce an error. In this case, it is merely redundant to also inherit `QWidget`, so you should just remove it. Also, you must do `__init__(parent)` with the `super` call, otherwise it will have no effect. It's okay to pass `None` (which is the default), because `QLabel` only optionally requires a parent. – ekhumoro May 24 '15 at 15:36