【发布时间】:2018-05-20 10:35:48
【问题描述】:
如何切换所选图形视图项目的 QPen 颜色?理想情况下,我想在图形视图或图形场景对象中处理这种颜色变化,而不是直接在主窗口选择事件中处理它。
感谢任何帮助。目前,选择对象时,它会转动笔色白色。我不确定如何将其转回以避免循环遍历所有对象。
有没有一种方法可以在 MyGraphicsView 类本身中添加一个函数来处理图表中任何和所有选定项目的笔颜色变化?
更新:更多详细信息 以下是我正在尝试解决的选择问题列表:
- 当用户单击并选择矩形时,它应该取消选择所有项目,将它们恢复为默认的笔颜色。新选择的项目应该是白色的笔颜色。如果用户正在控制它应该添加新选择的项目。如果项目已被选中并且矩形跨越它们,它仍应保持它们处于选中状态。
- 如果用户在光标下没有出现任何项目的负区域单击,它应该清除当前选择。
- 如果用户单击某个项目,则应选择该项目并将 Pen 颜色设为白色。
- 如果用户保持控制,则应始终添加到选择中。
代码
import sys
from PySide.QtGui import *
from PySide.QtCore import *
import random
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
# self.setBackgroundBrush(QImage("C:/Users/jmartini/Desktop/Temp/images/flag_0140.jpg"))
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff )
self.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff )
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self._mousePressed = True
if self._isPanning:
self.setCursor(Qt.ClosedHandCursor)
self._dragPos = event.pos()
event.accept()
else:
super(MyGraphicsView, self).mousePressEvent(event)
elif event.button() == Qt.MiddleButton:
self._mousePressed = True
self._isPanning = True
self.setCursor(Qt.ClosedHandCursor)
self._dragPos = event.pos()
event.accept()
def mouseMoveEvent(self, event):
if self._mousePressed and self._isPanning:
newPos = event.pos()
diff = newPos - self._dragPos
self._dragPos = newPos
self.horizontalScrollBar().setValue(self.horizontalScrollBar().value() - diff.x())
self.verticalScrollBar().setValue(self.verticalScrollBar().value() - diff.y())
event.accept()
else:
super(MyGraphicsView, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
if self._isPanning:
self.setCursor(Qt.OpenHandCursor)
else:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
self._mousePressed = False
elif event.button() == Qt.MiddleButton:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
self._mousePressed = False
super(MyGraphicsView, self).mouseReleaseEvent(event)
def mouseDoubleClickEvent(self, event):
self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)
pass
def keyPressEvent(self, event):
if event.key() == Qt.Key_Space and not self._mousePressed:
self._isPanning = True
self.setCursor(Qt.OpenHandCursor)
else:
super(MyGraphicsView, self).keyPressEvent(event)
def keyReleaseEvent(self, event):
if event.key() == Qt.Key_Space:
if not self._mousePressed:
self._isPanning = False
self.setCursor(Qt.ArrowCursor)
else:
super(MyGraphicsView, self).keyPressEvent(event)
def wheelEvent(self, event):
# zoom factor
factor = 1.25
# Set Anchors
self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)
# Save the scene pos
oldPos = self.mapToScene(event.pos())
# Zoom
if event.delta() < 0:
factor = 1.0 / factor
self.scale(factor, factor)
# Get the new position
newPos = self.mapToScene(event.pos())
# Move scene to old position
delta = newPos - oldPos
self.translate(delta.x(), delta.y())
class MyGraphicsScene(QGraphicsScene):
def __init__(self, parent):
super(MyGraphicsScene, self).__init__()
self.setBackgroundBrush(QBrush(QColor(50,50,50)))
# self.setSceneRect(50,50,0,0)
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__()
self.setWindowTitle("Test")
self.resize(800,600)
self.gv = MyGraphicsView()
self.gv.setScene(MyGraphicsScene(self))
self.setCentralWidget(self.gv)
self.gv.scene().selectionChanged.connect(self.selection_changed)
self.populate()
def populate(self):
scene = self.gv.scene()
for i in range(500):
x = random.randint(0, 1000)
y = random.randint(0, 1000)
r = random.randint(2, 8)
rect = scene.addEllipse(x, y, r, r, QPen(QColor(255,128,0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin), QBrush(QColor(255,128,20,128)))
rect.setFlag( QGraphicsItem.ItemIsSelectable )
rect.setFlag( QGraphicsItem.ItemIsMovable )
rect = scene.addEllipse(300, 500, 20, 20, QPen(QColor(255,128,0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin), QBrush(QColor(255,0,0,128)))
rect.setFlag( QGraphicsItem.ItemIsSelectable )
rect.setFlag( QGraphicsItem.ItemIsMovable )
def selection_changed(self):
selection = self.gv.scene().selectedItems()
print 'Selected:', len(selection)
for i in selection:
i.setPen(QPen(QColor(255,255,255), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
def main():
app = QApplication(sys.argv)
ex = MyMainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
【问题讨论】:
-
你能解释一下吗
-
据我了解,如果您选择了一个项目,请将您的 QPen 更改为白色,如果您重新选择相同的项目,您应该返回到以前的状态。我是对的?
-
当项目被选中时,它会变为白色,如果取消选择该项目,它应该会恢复到原来的颜色。
标签: python selection pyside qgraphicsview qgraphicsscene