[英]QPainter draw line between two widgets
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.
此外,新按钮单击了 function,当我单击它时,我删除了这个按钮,它在这个按钮和前一个按钮之间画了线,并更新了布局。
Seems complicated, but I see some application do this.Maybe they don't use same layout I am using.看起来很复杂,但我看到一些应用程序这样做。也许他们不使用我正在使用的相同布局。
@eyllanesc, helped to install this event, but it was more static. @eyllanesc,帮助安装了这个事件,但更多的是 static。 I need to make it more dynamic every time I update the layout.
每次更新布局时,我都需要使其更加动态。 Pyqt5 draw a line between two widgets .
Pyqt5 在两个小部件之间画一条线。 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_())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.