QGraphicsGridLayout работает в PySide, но не в PyQt4

Я несколько часов пытался заставить QGraphicsGridLayout работать с PyQt4. У меня установлено PySide, поэтому я переключил импорт на него для быстрой проверки, и все заработало, как и ожидалось! Для приведенного ниже кода, когда используется PySide, метод paint для RectangleWidget вызывается, как и ожидалось, но когда вы используете PyQt4, метод paint никогда не вызывается.

Я знаю, что RectangleWidget должен переопределить еще несколько виртуальных методов для правильной реализации, но я убирал некоторые вещи, чтобы попытаться получить минимальный объем кода, чтобы сузить проблему.

from PySide import QtGui, QtCore
# from PyQt4 import QtGui, QtCore


class RectangleWidget(QtGui.QGraphicsWidget):
    def __init__(self, rect, parent=None):
        super(RectangleWidget, self).__init__(parent)
        self.rect = rect

    def paint(self, painter, *args, **kwargs):
        print('Paint Called')
        painter.drawRect(self.rect)


class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.central_widget = QtGui.QWidget(self)
        central_layout = QtGui.QHBoxLayout()
        self.central_widget.setLayout(central_layout)
        self.setCentralWidget(self.central_widget)
        self.resize(500, 500)

        self.view = QtGui.QGraphicsView()
        self.scene = QtGui.QGraphicsScene()
        self.view.setScene(self.scene)

        panel = QtGui.QGraphicsWidget()
        self.scene.addItem(panel)

        layout = QtGui.QGraphicsGridLayout()
        panel.setLayout(layout)

        for i in range(4):
            for j in range(4):
                rectangle = RectangleWidget(QtCore.QRectF(0, 0, 50, 50))
                layout.addItem(rectangle, i, j)

        central_layout.addWidget(self.view)

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)
    widget = MainWindow()
    widget.show()
    app.exec_()

Любая помощь приветствуется! Я хотел бы сохранить совместимость как с PyQt4, так и с PySide, поэтому продолжать использовать только PySide на самом деле не идеальное решение. Спасибо


person D2B    schedule 15.02.2014    source источник


Ответы (1)


QGraphicsGridLayout становится владельцем добавленных к нему элементов (см. документы подробнее).

В вашем примере может показаться, что все элементы RectangleWidget находятся под угрозой сбора мусора, как только они выходят за рамки. Итак, если вы дадите им родителя:

    rectangle = RectangleWidget(QtCore.QRectF(0, 0, 50, 50), panel)

все должно быть хорошо.

person ekhumoro    schedule 15.02.2014
comment
Есть ли какая-то конкретная причина, по которой это произошло только с GridLayout в PyQt4? LinearLayout отлично работал как в PyQt4, так и в PySide. Я обычно игнорировал аспект собственности на данный момент, но я думаю, пришло время перестать его упускать из виду. Спасибо. - person D2B; 16.02.2014
comment
@D2B. Трудно сказать: сборка мусора может быть непредсказуемой. И именно поэтому игнорирование права собственности может быть рискованным. - person ekhumoro; 16.02.2014