QPainter 在两个小部件之间画线 [英] QPainter draw line between two widgets

查看:85
本文介绍了QPainter 在两个小部件之间画线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个布局,我将向该布局添加一个按钮(通过单击添加按钮).

I have a layout, and I am going to add a button to this layout (by clicking on the add button).

每次添加按钮时,我都想在上一个按钮和新按钮之间画一条线.每次我添加一个按钮时都会这样做.此外,新按钮有一个点击功能,当我点击它时,我删除了这个按钮,它在这个按钮和上一个按钮之间画了一条线,并更新了布局.

Everytime I add a button, I wanna draw a line between Previous button and new button. This is done everytime I add a button. Also, The new button, has a clicked function that when I click it I delete this button and it's line draw between this button and previous one, and update the layout.

看起来很复杂,但我看到一些应用程序这样做.也许他们使用的布局与我使用的布局不同.

Seems complicated, but I see some application do this.Maybe they don't use same layout I am using.

@eyllanesc,帮助安装此事件,但它更静态.每次更新布局时,我都需要让它更加动态.Pyqt5 在两个小部件之间画一条线.下面是我的一些虚拟试验

@eyllanesc, helped to install this event, but it was more static. I need to make it more dynamic every time I update the layout. Pyqt5 draw a line between two widgets. Below is some dummy trials of me

import sys

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


class Drawer:
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawLine(self.p1, self.p2)


class Example(QWidget, 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.vbox = QVBoxLayout(self)
        self.vbox.addWidget(self.AddButton)

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

    def addbuttonwithline(self):

        # Add buttons
        b = QPushButton('delete')
        self.vbox.addWidget(b)

        # delete the button and it's corresponding line
        b.clicked.connect(self.deletebuttonandlines)

        # Define buttons
        curr_ind = self.vbox.indexOf(b)
        previous_but = self.vbox.itemAt(curr_ind-1).widget()

        # Draw lines
        self.p1, self.p2 = previous_but.pos(), b.pos()

        previous_but.installEventFilter(self)
        b.installEventFilter(self)

    def deletebuttonandlines(self):
        # Delete this button and it's corresponding line and update the layout


    def eventFilter(self, o, e):
        if e.type() == QEvent.Move:
            self.p1 = self.p1
            self.p2 = self.p2
            self.update()
        return super().eventFilter(o, e)


if __name__ == "__main__":

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

推荐答案

逻辑类似:跟踪事件和变化(例如创建和销毁小部件),然后使用信息获取信息来画线:

The logic is similar: Trace the events and changes (such as creating and destroying widgets) and then use the information to get the information to draw the lines:

import functools
import sys

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


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(QWidget, 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.vbox = QVBoxLayout(self)
        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(), next_button.pos())
            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_())

这篇关于QPainter 在两个小部件之间画线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆