删除所选项目上的虚线矩形
Removing dotted rectangle on selected item
我一直在尝试通过查看此处的示例来更多地了解 QGraphicsView 小部件:
我发现这很有帮助,但是我注意到选择时会出现选项时出现的侯爵东西。我正在寻找摆脱这个问题的方法,似乎在 C++ 中对此有一个一致的答案,我在这里看到了一个例子:
https://www.qtcentre.org/threads/39659-About-QGraphicsItem-question
但是我对如何将其转换为 pyqt 感到非常困惑,所以我想知道是否有人可以从第一个 link 开始就如何在示例项目中执行此操作提供任何见解。...
我一直在通过查看如下代码来寻找可能的等效项:
https://www.riverbankcomputing.com/pipermail/pyqt/2012-November/032110.html
虽然说实话我都不知道这些示例代码的应用是什么...
如果您想从 python 中的项目选择中删除矩形,您必须使用以下命令:
class GraphicsEllipseItem(QGraphicsEllipseItem):
def paint(self, painter, option, widget):
option.state &= ~QStyle.State_Selected
super(GraphicsEllipseItem, self).paint(painter, option, widget)
完成脚本
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import random
class GraphicsEllipseItem(QGraphicsEllipseItem):
def paint(self, painter, option, widget):
option.state &= ~QStyle.State_Selected
super(GraphicsEllipseItem, self).paint(painter, option, widget)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setScene(MyGraphicsScene(self))
self.scene().selectionChanged.connect(self.selection_changed)
self._current_selection = []
def select_items(self, items, on):
pen = QPen(
QColor(255, 255, 255) if on else QColor(255, 128, 0),
0.5,
Qt.SolidLine,
Qt.RoundCap,
Qt.RoundJoin,
)
for item in items:
item.setPen(pen)
def selection_changed(self):
try:
self.select_items(self._current_selection, False)
self._current_selection = self.scene().selectedItems()
self.select_items(self._current_selection, True)
except RuntimeError:
pass
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__(parent)
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.setCentralWidget(self.gv)
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 = GraphicsEllipseItem(x, y, r, r)
rect.setPen(
QPen(QColor(255, 128, 0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
)
rect.setBrush(QBrush(QColor(255, 128, 20, 128)))
scene.addItem(rect)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect = GraphicsEllipseItem(300, 500, 20, 20)
rect.setPen(
QPen(QColor(255, 128, 0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
)
rect.setBrush(QBrush(QColor(255, 0, 0, 128)))
scene.addItem(rect)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
def main():
app = QApplication(sys.argv)
ex = MyMainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
option.state &= ~QStyle.State_Selected
的解释:
state是QStyleOptionGraphicsItem的一个属性,它存储了绘画状态的信息,可能包含以下标志的组合:
在这种情况下,可以使用“|”组合标记运算符,并使用“&~”停用。
为了更好地理解它,让我们使用以下示例:我们将 State_Active 和 State_Editing 中的状态设置为初始状态:
state = State_Active | State_Editing
= 0x00010000 | 0x00400000
= 0x00410000
并停用 State_Active 标志:
state & ~State_Active
0x00410000 & ~(0x00010000)
0x00410000 & 0xFFFEFFFF
0x00400000
如您所见,标志 State_Active 被删除而没有仅通过二元运算删除其他标志。
那么你想如何停用State_Selected标志,并将其替换为状态然后必须这样做:
option.state = option.state & ~QStyle.State_Selected
option.state &= ~QStyle.State_Selected
我一直在尝试通过查看此处的示例来更多地了解 QGraphicsView 小部件:
我发现这很有帮助,但是我注意到选择时会出现选项时出现的侯爵东西。我正在寻找摆脱这个问题的方法,似乎在 C++ 中对此有一个一致的答案,我在这里看到了一个例子:
https://www.qtcentre.org/threads/39659-About-QGraphicsItem-question
但是我对如何将其转换为 pyqt 感到非常困惑,所以我想知道是否有人可以从第一个 link 开始就如何在示例项目中执行此操作提供任何见解。...
我一直在通过查看如下代码来寻找可能的等效项:
https://www.riverbankcomputing.com/pipermail/pyqt/2012-November/032110.html
虽然说实话我都不知道这些示例代码的应用是什么...
如果您想从 python 中的项目选择中删除矩形,您必须使用以下命令:
class GraphicsEllipseItem(QGraphicsEllipseItem):
def paint(self, painter, option, widget):
option.state &= ~QStyle.State_Selected
super(GraphicsEllipseItem, self).paint(painter, option, widget)
完成脚本
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import random
class GraphicsEllipseItem(QGraphicsEllipseItem):
def paint(self, painter, option, widget):
option.state &= ~QStyle.State_Selected
super(GraphicsEllipseItem, self).paint(painter, option, widget)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setScene(MyGraphicsScene(self))
self.scene().selectionChanged.connect(self.selection_changed)
self._current_selection = []
def select_items(self, items, on):
pen = QPen(
QColor(255, 255, 255) if on else QColor(255, 128, 0),
0.5,
Qt.SolidLine,
Qt.RoundCap,
Qt.RoundJoin,
)
for item in items:
item.setPen(pen)
def selection_changed(self):
try:
self.select_items(self._current_selection, False)
self._current_selection = self.scene().selectedItems()
self.select_items(self._current_selection, True)
except RuntimeError:
pass
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__(parent)
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.setCentralWidget(self.gv)
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 = GraphicsEllipseItem(x, y, r, r)
rect.setPen(
QPen(QColor(255, 128, 0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
)
rect.setBrush(QBrush(QColor(255, 128, 20, 128)))
scene.addItem(rect)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect = GraphicsEllipseItem(300, 500, 20, 20)
rect.setPen(
QPen(QColor(255, 128, 0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
)
rect.setBrush(QBrush(QColor(255, 0, 0, 128)))
scene.addItem(rect)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
def main():
app = QApplication(sys.argv)
ex = MyMainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
option.state &= ~QStyle.State_Selected
的解释:
state是QStyleOptionGraphicsItem的一个属性,它存储了绘画状态的信息,可能包含以下标志的组合:
在这种情况下,可以使用“|”组合标记运算符,并使用“&~”停用。
为了更好地理解它,让我们使用以下示例:我们将 State_Active 和 State_Editing 中的状态设置为初始状态:
state = State_Active | State_Editing
= 0x00010000 | 0x00400000
= 0x00410000
并停用 State_Active 标志:
state & ~State_Active
0x00410000 & ~(0x00010000)
0x00410000 & 0xFFFEFFFF
0x00400000
如您所见,标志 State_Active 被删除而没有仅通过二元运算删除其他标志。
那么你想如何停用State_Selected标志,并将其替换为状态然后必须这样做:
option.state = option.state & ~QStyle.State_Selected
option.state &= ~QStyle.State_Selected