Python 单击按钮时PYQT5图形区域未更新
我在一个图形场景中画了一些正方形和一个圆圈,我想用多条线连接这些正方形,这些线从圆圈开始,像树一样分支。当用户单击左下角的按钮时,应在场景中绘制线条。在场景中绘制线后,用户应该能够放大线并选择线,就像使用圆和正方形一样 路径由名为Python 单击按钮时PYQT5图形区域未更新,python,python-3.x,pyqt,pyqt5,qgraphicsview,Python,Python 3.x,Pyqt,Pyqt5,Qgraphicsview,我在一个图形场景中画了一些正方形和一个圆圈,我想用多条线连接这些正方形,这些线从圆圈开始,像树一样分支。当用户单击左下角的按钮时,应在场景中绘制线条。在场景中绘制线后,用户应该能够放大线并选择线,就像使用圆和正方形一样 路径由名为group的函数确定。此函数将获取点,并绘制一个图形结构,以概述点应如何连接。我知道这可以更好,我也希望它更好,但我不想在这篇文章中问太多问题。例如,输出应该如下所示 {0: [1, 5, 6], 1: [7], 7: [12], 5: [4]} 这意味着点0连接到点
group
的函数确定。此函数将获取点,并绘制一个图形
结构,以概述点应如何连接。我知道这可以更好,我也希望它更好,但我不想在这篇文章中问太多问题。例如,输出应该如下所示
{0: [1, 5, 6], 1: [7], 7: [12], 5: [4]}
这意味着点0
连接到点1
、5
和6
,点1
连接到点7
,依此类推
然后,我有一个名为PathLine
的类,它应该设置所有属性,以便在选中时更改颜色,以及我希望用户将来能够看到的其他内容
当用户单击按钮时,它将在我的Viewer
类中运行一个名为drawConnectingLines
的函数,这就是我希望它绘制线条的地方。我可以告诉你函数正在运行,我没有收到任何错误,但是窗口中没有显示任何内容
我已经尝试添加QApplication.processEvents()
,self.update()
,和self.scene().update()
,但似乎没有什么不同。另外,如果我试图在程序的负载上画线,它不会画任何东西。甚至连要点都没有
非常感谢您的帮助
rom PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
from math import sqrt,cos,acos,asin,degrees,pi,hypot
class LogObject(QObject):
hovered = pyqtSignal()
notHovered = pyqtSignal()
def create_square():
scale = 250
path = QPainterPath()
path.addRect(-0.076,-0.07,0.1520,0.1400)
tr = QTransform()
tr.scale(scale, scale)
path = tr.map(path)
return path
def create_circle():
scale = 250
path = QPainterPath()
path.addEllipse(QPointF(0,0), 0.0750, 0.0750) # Using QPointF will center it
tr = QTransform()
tr.scale(scale, scale)
path = tr.map(path)
return path
def drawPath(x1,y1,x2,y2):
scale = 250
path = QPainterPath()
path.moveTo(x1,y1)
path.lineTo(x2,y2)
tr = QTransform()
tr.scale(scale, scale)
path = tr.map(path)
return path
class PathLine(QGraphicsPathItem):
def __init__(self,x1,y1,x2,y2):
super(PathLine,self).__init__()
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
# self.name = name
self.setFlag(QGraphicsItem.ItemIsSelectable,True)
self.setScale(1.5)
self.setPath(drawPath(x1,y1,x2,y2))
self.setAcceptHoverEvents(True)
self.log = LogObject()
self.setPos(x1, y1)
self.isSelected = False
def findLineWidth(self,zoomValue): # This function is for creating the line width value of all the drawn Objects
if zoomValue > 18:
zoomValue = 18
lineWidthF = -0.0000177256625115696*(zoomValue)**4 + 0.000440875172476041*(zoomValue)**3 + 0.00941580772740735*(zoomValue)**2 - 0.370069940941448*(zoomValue) + 3
self.updateLineWidth(lineWidthF)
def updateLineWidth(self,lineWidth):
pen = self.pen()
pen.setWidthF(lineWidth)
self.setPen(pen)
def itemChange(self, change, value):
if change == self.ItemSelectedChange:
color = QColor(Qt.green) if value else QColor(Qt.white)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
return QGraphicsItem.itemChange(self, change, value)
def hoverEnterEvent(self, event):
color = QColor("red")
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.hovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
def hoverLeaveEvent(self, event):
color = QColor(Qt.green) if self.isSelected else QColor(Qt.white)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.notHovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
class Point(QGraphicsPathItem):
def __init__(self, x, y, r, name):
super(Point, self).__init__()
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.name = name
if self.name.split('__')[1] == '0':
self.setPath(create_circle())
else:
self.setPath(create_square())
self.setScale(1.5)
self.x = x
self.y = y
self.r = r
self.setRotation(180+self.r)
self.setAcceptHoverEvents(True)
self.log = LogObject()
self.setPos(x, y)
self.isSelected = False
pen = QPen(Qt.white)
pen.setStyle(Qt.SolidLine)
pen.setWidthF(3)
self.setPen(pen)
def findLineWidth(self,zoomValue): # This function is for creating the line width value of all the drawn Objects
if zoomValue > 18:
zoomValue = 18
lineWidthF = -0.0000177256625115696*(zoomValue)**4 + 0.000440875172476041*(zoomValue)**3 + 0.00941580772740735*(zoomValue)**2 - 0.370069940941448*(zoomValue) + 3
self.updateLineWidth(lineWidthF)
def updateLineWidth(self,lineWidth):
pen = self.pen()
pen.setWidthF(lineWidth)
self.setPen(pen)
def itemChange(self, change, value):
if change == self.ItemSelectedChange:
color = QColor(Qt.green) if value else QColor(Qt.white)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
return QGraphicsItem.itemChange(self, change, value)
def hoverEnterEvent(self, event):
color = QColor("red")
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.hovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
def hoverLeaveEvent(self, event):
color = QColor(Qt.green) if self.isSelected else QColor(Qt.white)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.notHovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
def mouseDoubleClickEvent(self,event):
print(self.name)
class Viewer(QGraphicsView):
photoClicked = pyqtSignal(QPoint)
rectChanged = pyqtSignal(QRect)
def __init__(self, parent):
super(Viewer, self).__init__(parent)
self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
self.setMouseTracking(True)
self.origin = QPoint()
self.changeRubberBand = False
self.setRenderHints(QPainter.Antialiasing)
self._zoom = 0
self._empty = True
self.setScene(QGraphicsScene(self))
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setFrameShape(QFrame.NoFrame)
self.area = float()
self.setPoints()
self.viewport().setCursor(Qt.ArrowCursor)
QTimer.singleShot(0, self.reset_fit)
self.selectedItems = []
self.setBackgroundBrush(Qt.black)
def setItems(self):
self.data = {
"x": [
-2415594.9965,
-2414943.8686,
-2417160.6592,
# -2417160.6592,
-2417856.1783,
-2417054.7618,
-2416009.9966,
-2416012.5232,
# -2418160.8952,
-2418160.8952,
# -2416012.5232,
# -2417094.7694,
-2417094.7694,
],
"y": [
10453172.2426,
10454269.7008,
10454147.2672,
# 10454147.2672,
10453285.2456,
10452556.8132,
10453240.2808,
10455255.8752,
# 10455183.1912,
10455183.1912,
# 10455255.8752,
# 10456212.5959,
10456212.5959,
],
"rotation":[
0,
313.9962,
43.9962,
# 223.9962,
227.7070,
227.7070,
313.9962,
43.9962,
# 43.9962,
223.9962,
# 223.9962,
# 43.9962,
223.9962,
]
}
self.adjustedPoints = {}
for i, (x, y,r) in enumerate(zip(self.data["x"], self.data["y"],self.data["rotation"])):
p = Point(x, y,r, "Point__" + str(i))
p.log.hovered.connect(self.hoverChange)
p.log.notHovered.connect(self.notHoverChange)
self.scene().addItem(p)
self.adjustedPoints[i] = [x,y]
# if i == 0:
# self.adjustedPoints['c__'+str(i)] = [x,y]
# else:
# self.adjustedPoints['s__'+str(i)] = [x,y]
def drawConnectingLines(self):
# result = self.group(self.adjustedPoints, 'c__0')
result = self.group(self.adjustedPoints, 0)
for startPoint in result.items():
x1 = self.adjustedPoints[startPoint[0]][0]
y1 = self.adjustedPoints[startPoint[0]][1]
for endPoint in startPoint[1]:
x2 = self.adjustedPoints[endPoint][0]
y2 = self.adjustedPoints[endPoint][1]
connectingLine = PathLine(x1,y1,x2,y2)
# connectingLine.drawPath()
self.scene().addItem(connectingLine)
# QApplication.processEvents()
self.scene().update()
def findMinDistance(self,data, start):
xStart, yStart = data[start]
distances = []
for item,[x,y] in data.items():
if item != start and item != 0:
distances.append(hypot(abs(xStart - x),abs(yStart-y)))
output = self.mean(distances)-min(distances)
if output < min(distances):
output = min(distances)
return output
def mean(self,numbers):
return float(sum(numbers)) / max(len(numbers), 1)
def group(self,d, start,seen = []):
x, y = d[start]
r =[]
print(start)
dist = self.findMinDistance(d,start)
print(dist)
for a, [j, k] in d.items():
if a != start and a not in seen and hypot(abs(x-j), abs(y-k)) <= dist:
r.append(a)
if not r:
return {}
result = {start:r}
for i in r:
result.update(self.group(d, i, seen+[start, *r]))
return result
def setPoints(self):
self.setItems()
# self.drawConnectingLines()
self.setDragMode(self.ScrollHandDrag)
def wheelEvent(self, event):
for item in self.scene().items():
item.findLineWidth(self._zoom)
if event.angleDelta().y() > 0: # angleDelta is positive 120 zooming in and -120 going out
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.scale(factor, factor)
elif self._zoom == 0:
self.reset_fit()
else:
self._zoom = 0
def hoverChange(self):
self.viewport().setCursor(Qt.PointingHandCursor)
def notHoverChange(self):
self.viewport().setCursor(Qt.ArrowCursor)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
singleItem = self.itemAt(event.pos().x(), event.pos().y())
if singleItem != None:
if QApplication.keyboardModifiers() == Qt.ShiftModifier: # This will determine if the shift key is depressed
if singleItem.isSelected == True:
singleItem.setSelected(False)
singleItem.isSelected = False
self.selectedItems.remove(singleItem)
elif singleItem.isSelected == False:
singleItem.setSelected(True)
singleItem.isSelected = True
self.selectedItems.append(singleItem)
else:
self.origin = event.pos()
self.rubberBand.setGeometry(QRect(self.origin, QSize()))
self.rectChanged.emit(self.rubberBand.geometry())
self.rubberBand.show()
self.changeRubberBand = True
return
elif event.button() == Qt.MidButton:
self.viewport().setCursor(Qt.ClosedHandCursor)
self.original_event = event
handmade_event = QMouseEvent(
QEvent.MouseButtonPress,
QPointF(event.pos()),
Qt.LeftButton,
event.buttons(),
Qt.KeyboardModifiers(),
)
QGraphicsView.mousePressEvent(self, handmade_event)
super(Viewer, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
point = event.pos()
if event.button() == Qt.LeftButton:
self.changeRubberBand = False
if self.rubberBand.isVisible():
self.rubberBand.hide()
rect = self.rubberBand.geometry()
rect_scene = self.mapToScene(rect).boundingRect()
selected = self.scene().items(rect_scene)
if selected:
# print(selected)
for selectedPoints in selected:
if QApplication.keyboardModifiers() == Qt.ShiftModifier: # This will determine if the shift key is depressed
if selectedPoints.isSelected == True:
selectedPoints.setSelected(False)
selectedPoints.isSelected = False
self.selectedItems.remove(selectedPoints)
elif selectedPoints.isSelected == False: # if the shif key is not depressed and its not selected, then select it
selectedPoints.setSelected(True)
selectedPoints.isSelected = True
self.selectedItems.append(selectedPoints)
print( "".join("Item: %s\n" % child.name for child in self.selectedItems))
else:
print(" Nothing\n")
for selected in self.selectedItems:
selected.setSelected(False)
selected.isSelected = False
self.selectedItems.clear()
QGraphicsView.mouseReleaseEvent(self, event)
elif event.button() == Qt.MidButton:
self.viewport().setCursor(Qt.ArrowCursor)
handmade_event = QMouseEvent(
QEvent.MouseButtonRelease,
QPointF(event.pos()),
Qt.LeftButton,
event.buttons(),
Qt.KeyboardModifiers(),
)
QGraphicsView.mouseReleaseEvent(self, handmade_event)
def mouseMoveEvent(self, event):
if self.changeRubberBand:
self.rubberBand.setGeometry(
QRect(self.origin, event.pos()).normalized()
)
self.rectChanged.emit(self.rubberBand.geometry())
QGraphicsView.mouseMoveEvent(self, event)
super(Viewer, self).mouseMoveEvent(event)
def reset_fit(self):
r = self.scene().itemsBoundingRect()
self.resetTransform()
self.setSceneRect(r)
self.fitInView(r, Qt.KeepAspectRatio)
self._zoom = 0
self.scale(1, -1)
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.viewer = Viewer(self)
self.btnFindPath = QToolButton(self)
self.btnFindPath.setText("Draw Path")
self.btnFindPath.clicked.connect(self.autoDrawLines)
VBlayout = QVBoxLayout(self)
VBlayout.addWidget(self.viewer)
HBlayout = QHBoxLayout()
HBlayout.setAlignment(Qt.AlignLeft)
HBlayout.addWidget(self.btnFindPath)
VBlayout.addLayout(HBlayout)
def autoDrawLines(self):
self.viewer.drawConnectingLines()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())
rom PyQt5.QtCore导入*
从PyQt5.QtGui导入*
从PyQt5.QtWidgets导入*
导入系统
从数学导入sqrt、cos、acos、asin、学位、pi、海波
类LogObject(QObject):
悬停=pyqtSignal()
notHovered=pyqtSignal()
def create_square():
比例=250
路径=QPainterPath()
路径addRect(-0.076,-0.07,0.1520,0.1400)
tr=QTransform()
tr.刻度(刻度,刻度)
路径=tr.map(路径)
返回路径
def create_circle():
比例=250
路径=QPainterPath()
路径.加法(QPointF(0,0),0.0750,0.0750)#使用QPointF将其居中
tr=QTransform()
tr.刻度(刻度,刻度)
路径=tr.map(路径)
返回路径
def牵引路径(x1、y1、x2、y2):
比例=250
路径=QPainterPath()
路径移动到(x1,y1)
路径行到(x2,y2)
tr=QTransform()
tr.刻度(刻度,刻度)
路径=tr.map(路径)
返回路径
类路径线(QGraphicsPathItem):
定义初始化(self,x1,y1,x2,y2):
超级(路径线,自我)。\uuuu初始化
self.x1=x1
self.y1=y1
self.x2=x2
self.y2=y2
#self.name=名称
self.setFlag(QGraphicsItem.ItemIsSelectable,True)
自整定标度(1.5)
自设置路径(绘图路径(x1、y1、x2、y2))
self.setAcceptHoverEvents(True)
self.log=LogObject()
自我设定位置(x1,y1)
self.isSelected=False
def findLineWidth(self,zoomValue):#此函数用于创建所有绘制对象的线宽值
如果zoomValue>18:
zoomValue=18
线宽F=-0.0000177256625115696*(缩放值)**4+0.000440875172476041*(缩放值)**3+0.00941580772740735*(缩放值)**2-0.370069940941448*(缩放值)+3
自更新线宽(线宽F)
def UPDATELINEWITH(自身,线宽):
pen=self.pen()
笔设置宽度F(线宽)
self.setPen(笔)
def itemChange(自身、更改、值):
如果change==self.ItemSelectedChange:
颜色=QColor(Qt.green)如果值为其他QColor(Qt.white)
pen=self.pen()
pen.setColor(颜色)
self.setPen(笔)
返回QGraphicsItem.itemChange(self、change、value)
def hoverEnterEvent(自我,事件):
颜色=QColor(“红色”)
pen=self.pen()
pen.setColor(颜色)
self.setPen(笔)
self.log.hovered.emit()
QGraphicsItem.hoverMoveEvent(self,event)
def hoverLeaveEvent(自我,事件):
颜色=QColor(Qt.绿色),如果选择self.Is,则为QColor(Qt.白色)
pen=self.pen()
pen.setColor(颜色)
self.setPen(笔)
self.log.notHovered.emit()
QGraphicsItem.hoverMoveEvent(self,event)
类点(QGraphicsPathItem):
定义初始化(self,x,y,r,name):
超级(点,自我)。\uuuuu初始化
self.setFlag(QGraphicsItem.ItemIsSelectable,True)
self.name=名称
如果self.name.split(“”“”)[1]=“0”:
self.setPath(创建_circle())
其他:
self.setPath(create_square())
自整定标度(1.5)
self.x=x
self.y=y
self.r=r
自整定旋转(180+自整定)
self.setAcceptHoverEvents(True)
self.log=LogObject()
自我设定位置(x,y)
self.isSelected=False
pen=QPen(Qt.白色)
笔设置样式(Qt.实线)
笔设置宽度f(3)
self.setPen(笔)
def findLineWidth(self,zoomValue):#此函数用于创建所有绘制对象的线宽值
如果zoomValue>18:
zoomValue=18
线宽F=-0.0000177256625115696*(缩放值)**4+0.000440875172476041*(缩放值)**3+0.00941580772740735*(缩放值)**2-0.370069940941448*(缩放值)+3
自更新线宽(线宽F)
def UPDATELINEWITH(自身,线宽):
pen=self.pen()
笔设置宽度F(线宽)
self.setPen(笔)
def itemChange(自身、更改、值):
如果change==self.ItemSelectedChange:
颜色=QColor(Qt.green)如果值为其他QColor(Qt.white)
pen=self.pen()
pen.setColor(颜色)
自动设置笔(
def drawPath(x1,y1,x2,y2):
path = QPainterPath()
path.moveTo(x1,y1)
path.lineTo(x2,y2)
return path
class PathLine(QGraphicsPathItem):
def __init__(self,x1,y1,x2,y2):
super(PathLine,self).__init__()
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
# self.name = name
self.setFlag(QGraphicsItem.ItemIsSelectable,True)
self.setPath(drawPath(x1,y1,x2,y2))
self.setAcceptHoverEvents(True)
self.log = LogObject()
pen = QPen(Qt.white)
pen.setStyle(Qt.SolidLine)
pen.setWidthF(4)
self.setPen(pen)
self.isSelected = False