QPainter在QScrolla区域内绘制线

2024-10-06 11:24:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我之前提出了一个关于如何在小部件之间画线的问题。而@eyllanesc很好地解决了这个问题。但我面临另一个问题。我尝试用QScrollarea制作小部件。但是这些线没有显示出来

当使用Widget时,它可以很好地绘制线条,但QScrollArea似乎需要另一个paint_event。我不知道怎么做

有人能帮我展示一下QScrollarea的台词吗

import functools
import sys

from PyQt5.QtCore import QEvent, QLine
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget, QScrollArea


class Drawer:
    def __init__(self):
        self._lines = []

    @property
    def lines(self):
        return self._lines

    @lines.setter
    def lines(self, l):
        self._lines = l[:]
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        for line in self.lines:
            painter.drawLine(line)


class Example(QScrollArea, Drawer):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        self.AddButton = QPushButton("Add")
        self.AddButton.clicked.connect(self.addbuttonwithline)

        self.w = QWidget()
        self.setWidget(self.w)
        self.setWidgetResizable(True)

        self.vbox = QVBoxLayout(self.w)
        self.vbox.addWidget(self.AddButton)

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle("Buttons")

        self.buttons = []

    def addbuttonwithline(self):
        button = QPushButton("delete")
        button.clicked.connect(functools.partial(self.remove_button, button))
        button.installEventFilter(self)
        self.vbox.addWidget(button)
        self.buttons.append(button)
        self.recalculate_position()

    def remove_button(self, button):
        self.buttons.remove(button)
        button.deleteLater()
        self.recalculate_position()

    def recalculate_position(self):
        lines = []
        for last_button, next_button in zip(self.buttons, self.buttons[1:]):
            l = QLine(last_button.pos().x()+50, last_button.pos().y(), next_button.pos().x()+50, next_button.pos().y())
            lines.append(l)
        self.lines = lines

    def eventFilter(self, o, e):
        if e.type() == QEvent.Move and o in self.buttons:
            self.recalculate_position()
        return super().eventFilter(o, e)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

Tags: fromposimportselfinitdefsysposition
1条回答
网友
1楼 · 发布于 2024-10-06 11:24:43

QScrollArea被设计成一个容器,因此您不应该在该项目上绘画,因为内容覆盖了它,而是在内容小部件中设置绘画

根据我从my previous answer开始的代码,只需更改为:

if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = Example()
    w = QScrollArea(widgetResizable=True)
    w.setWidget(ex)
    w.show()
    sys.exit(app.exec_())

enter image description here

相关问题 更多 >