Qt / PyQt: QGraphicsItem против Геометрия QGraphicsWidget, положение, взаимодействие с мышью

#qt #geometry #pyqt #qgraphicsitem

#qt #геометрия #pyqt #qgraphicsitem

Вопрос:

Я конвертирую большую программу QGraphicsItems в QGraphicsWidgets (давайте назовем их item и widget для удобства ввода). При наведении курсора мыши происходит сбой, поскольку положение и / или прямоугольник виджетов не совпадают со старыми элементами. Я свел все к простому варианту с видом, сценой, элементом и виджетом. Синий элемент отображается с разрешением 100×50 пикселей, и hoverEnterEvent происходит, как и ожидалось. Однако красный виджет отображается в два раза меньше заданной ширины. Я могу это исправить, если переопределю чисто виртуальную функцию boundingRect для виджета, но событие наведения по-прежнему запускается только поверх левой половины размером 50×50. Какие методы pos / rect / geometry мне нужно использовать / переопределить, чтобы виджет правильно взаимодействовал с мышью так же, как элемент? Спасибо. Вот мой пример кода

 #!/usr/local/bin/python

import os, sys
from PyQt4.Qt import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyView(QGraphicsView):
    def __init__(self):
        QGraphicsView.__init__(self)
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.scene = QGraphicsScene(self)
        self.item = GraphicsItem('item', 100, 50)
        self.item.moveBy(50, 50)
        self.scene.addItem(self.item)
        self.widget = GraphicsWidget('widget', 100, 50)
        self.scene.addItem(self.widget)
        self.setScene(self.scene)

class GraphicsItem(QGraphicsItem):
    def __init__(self, name, width, height):
        QGraphicsItem.__init__(self)
        self.setAcceptHoverEvents(True)
        self.name = name
        self.__width = width
        self.__height = height

    def boundingRect(self): 
        return QRectF(0, 0, self.__width, self.__height)

    def hoverEnterEvent(self, event):
        self.__printGeometryDetails()

    def paint(self, painter, option, widget):
        bgRect = self.boundingRect()
        painter.drawRects(bgRect)
        painter.fillRect(bgRect, QColor('blue'))

    def __printGeometryDetails(self):
        print self.name
        print '  pos (%.0f, %0.0f)' % (self.pos().x(), self.pos().y())
        print '  boundingRect (%.0f, %0.0f, %.0f, %0.0f)' % (self.boundingRect().x(), self.boundingRect().y(), self.boundingRect().width(), self.boundingRect().height())

class GraphicsWidget(QGraphicsWidget):
    def __init__(self, name, width, height):
        QGraphicsWidget.__init__(self)
        self.setAcceptHoverEvents(True)
        self.name = name
        self.__width = width
        self.__height = height

    def boundingRect(self):
        return QRectF(0, 0, self.__width, self.__height)

    def hoverEnterEvent(self, event):
        self.__printGeometryDetails()

    def paint(self, painter, option, widget):
        bgRect = self.boundingRect()
        painter.drawRects(bgRect)
        painter.fillRect(bgRect, QColor('red'))

    def __printGeometryDetails(self):
        print self.name
        print '  pos (%.0f, %0.0f)' % (self.pos().x(), self.pos().y())
        print '  boundingRect (%.0f, %0.0f, %.0f, %0.0f)' % (self.boundingRect().x(), self.boundingRect().y(), self.boundingRect().width(), self.boundingRect().height())
        print '  geometry (%.0f, %0.0f, %.0f, %0.0f)' % (self.geometry().x(), self.geometry().y(), self.geometry().width(), self.geometry().height())
        print '  rect (%.0f, %0.0f, %.0f, %0.0f)' % (self.rect().x(), self.rect().y(), self.rect().width(), self.rect().height())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    view = MyView()
    view.setGeometry(600, 100, 400, 370)
    view.show()
    sys.exit(app.exec_())
  

Ответ №1:

Кажется, что это работает правильно, если вы используете self.resize(width, height) вместо переопределения boundingRect .