Как использовать QPainter для рисования линий в QScrollArea?

Я пытаюсь использовать PyQt5 для создания симулятора визуализации структуры данных. Внутри есть QWidget и QScrollArea.

class test(QWidget):
    def __init__(self):
        super().__init__()  
        ...
        ...
        self.setUI() 

    def setUI(self):
        self.setGeometry(250, 200, 1500, 750)
        self.setWindowTitle('data structure visualization simulator')

        self.topFiller = QWidget()
        self.topFiller.setMinimumSize(1200, 2000)
        self.scroll = QScrollArea()
        self.scroll.setWidget(self.topFiller)

        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.scroll)
        self.setLayout(self.vbox)

Теперь мне нужно нарисовать линии в QScrollArea, что мне написать в QPainter?

    def paintEvent(self, e):
        qp = QPainter(self)
        pen = QPen()
        pen.setWidth(1)
        qp.setPen(pen)
        qp.drawLine(15, 80, 1080, 120)

person TK1602    schedule 16.11.2019    source источник


Ответы (1)


PaintEvent получает виджет, который на самом деле будет раскрашен, вы не можете реализовать его из другого виджета, даже если это его родительский элемент; вам нужно будет либо создать подкласс области прокрутки и реализовать оттуда paintEvent, либо перехватить событие с помощью фильтра событий. В обоих случаях целью рисования должен быть viewport() области прокрутки.

Подклассы:

class MyScrollArea(QScrollArea):
    def paintEvent(self, event):
        qp = QPainter(self.viewport())
        pen = QPen()
        pen.setWidth(1)
        qp.setPen(pen)
        qp.drawLine(15, 80, 1080, 120)

Фильтрация событий:

class test(QWidget):
    def setUI(self):
        # ...
        # install the event filter on the area's *viewport*
        self.scroll.viewport().installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QEvent.Paint:
            super().eventFilter(source, event)
            # "source" is the viewport
            qp = QPainter(source)
            pen = QPen()
            pen.setWidth(1)
            qp.setPen(pen)
            qp.drawLine(15, 80, 1080, 120)
            return False
        return super().eventFilter(source, event)
person musicamante    schedule 17.11.2019