如何在同一窗口上绘制两个对象?



序言:下面表示的两个对象都在同一窗口中。

我遇到不更新的问题 我遇到了与self.setGeometry(x,y,w,h)功能有关的问题。因此,我想要实现的是多个矩形,并行渲染,单击每个矩形时都有一条线从其矩形中突出。(创建连接器,但这不是本主题的重点(。

在这种情况下,我将矩形A和矩形B渲染放在一起。矩形A有一条线突出到鼠标的位置。

(obj A)           (obj B)
____              ____
|    |            |    |
|   |            |    |
---              ----

(Mouse)

我试图实现的目标的示例代码。

# File: connectors.py
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QWidget
class Connector(QWidget):
def __init__(self, rect: List[int]):
super().__init__()
self.setGeometry(0, 0, 1920, 1080)
self.rect = rect
self.clicked = False
self.begin = QPoint(rect[0], rect[1])
self.end = QPoint(0,0)
def paintEvent(self, event):
qp = QPainter()
qp.begin(self)
qp.setPen(Qt.red)
qp.drawRect(*self.rect)
if self.clicked:
qp = QPainter()
qp.begin(self)
qp.setPen(Qt.red)
qp.drawLine(self.begin, self.end)
self.update()
def mousePressEvent(self, event):
if event.button() == 1:
self.clicked = True
self.end = event.pos()
def mouseMoveEvent(self, event):
if self.clicked:
self.end = event.pos()
def mouseReleaseEvent(self, event):
if event.button() == 1:
self.clicked = False
self.end = event.pos()
# File: main.py
scene = QGraphicsScene()
scene.addWidget( Connector((400, 400, 100, 100)) )
scene.addWidget( Connector((400, 600, 100, 100)) )

但我最终的结果是 PyQt 在屏幕上显示最顶层的对象,因此只显示一个对象,我也试图最小化导致突出线的几何形状,当单击时,在边界上切断。

解释:

在您的情况下,它有 2 个小部件,您可以在其中绘制一个位于另一个之上的矩形,因此您只会看到其中一个:上面的那个。

溶液:

Qt GraphicsView 框架(QGraphicsView,QGraphicsScene,QGraphicsXItem等(的工作方式不同,并且不直接使用绘画,因为它们提供了实现所有功能的基本项目,因此在这种情况下,您必须将QGraphicsRectItem与QGraphicsLineItem一起使用,并使用QGraphicsView的信息对其进行修改。

考虑到上述情况,解决方案是:

import sys
from PyQt5.QtCore import QRectF, Qt
from PyQt5.QtWidgets import (
QApplication,
QGraphicsLineItem,
QGraphicsRectItem,
QGraphicsScene,
QGraphicsView,
)

class RectItem(QGraphicsRectItem):
def __init__(self, rect, parent=None):
super().__init__(parent)
self.setRect(QRectF(*rect))
self.setPen(Qt.red)
self._line_item = QGraphicsLineItem(self)
self.line_item.setPen(Qt.red)
l = self.line_item.line()
l.setP1(self.rect().topLeft())
l.setP2(self.rect().topLeft())
self.line_item.setLine(l)
self.line_item.hide()
@property
def line_item(self):
return self._line_item
def move_line_to(self, sp):
lp = self.mapFromScene(sp)
l = self.line_item.line()
l.setP2(lp)
self.line_item.setLine(l)

class GraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setScene(QGraphicsScene())
self.scene().addItem(RectItem((400, 400, 100, 100)))
self.scene().addItem(RectItem((400, 600, 100, 100)))
def mousePressEvent(self, event):
vp = event.pos()
sp = self.mapToScene(vp)
self.move_lines(sp)
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
vp = event.pos()
sp = self.mapToScene(vp)
self.move_lines(sp)
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
for item in self.items():
if isinstance(item, RectItem):
item.line_item.hide()
super().mouseReleaseEvent(event)
def move_lines(self, sp):
for item in self.items():
if isinstance(item, RectItem):
item.line_item.show()
item.move_line_to(sp)

if __name__ == "__main__":
app = QApplication(sys.argv)
w = GraphicsView()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

相关内容

  • 没有找到相关文章

最新更新