我试图创建一个具有以下行为的QGraphicsView:的QGraphicsView双击事件和ScrollHandDrag模式项目问题
当控制键被和鼠标左键向下,认为应设置以ScrollHandDrag模式允许用户平移。
当ScrollHandDrag模式,项目不应该选择/移动,如问题在这里:In ScrollHandDrag mode of QGraphicsView, How to stop movement of QGraphicsItems on scene?
如果控制键举行,鼠标左键被点击,然后控制键被释放,那么视图应该保持在ScrollHandDrag模式,直到鼠标被释放,或者如果在释放鼠标时控制键被关闭,它将保持在这种模式下。
对我来说这听起来应该是相当简单的。我已经实现了链接问题的逻辑,还有一些额外的逻辑来满足我的额外需求。然而,这似乎会导致以下两个搅局者:
在mousePressEvent,设置鼠标下的项目不具有可移动的和可选的标志,调用基类,然后重新应用标志导致项目变成“冻结”。解决这个问题的唯一方法似乎是在项目之外单击几次控制+单击,释放控制+释放。同样,当它进入这种状态时,没有物品可以移动(尽管它们仍然可以被选择)。
双击该视图会导致一个mousePressEvent,然后是两个mouseReleaseEvents!这打破了我的逻辑。
所以我想知道我怎么能解决这个项目的问题变得冻结当使用从In ScrollHandDrag mode of QGraphicsView, How to stop movement of QGraphicsItems on scene?逻辑,以及如何处理与陌生的鼠标双击事件 - 有没有办法把他们离开?
这里是我的代码(这也几乎是我的Hello World的Python,所以如果我做了一些可怕的Python错误,请让我知道):
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Test")
self.gv = MyGraphicsView()
self.setCentralWidget(self.gv)
self.setGeometry(170, 130, 450, 250)
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setup()
def setup(self):
self.m_MouseIsDown = False
self.m_ControlKeyDown = False
self.setDragMode(QGraphicsView.RubberBandDrag)
def mouseMoveEvent(self, event):
# print "mouseMoveEvent: " + str(event.pos().x()) + "," + str(event.pos().y())
super(MyGraphicsView, self).mouseMoveEvent(event);
def mousePressEvent(self, event):
print "mousePressEvent"
itemUnderMouse = self.itemAt(event.pos())
if itemUnderMouse is not None:
bHadMovableFlagSet = itemUnderMouse.flags() & QGraphicsItem.ItemIsMovable
bWasSelected = itemUnderMouse.isSelected()
bHadSelectableFlagSet = itemUnderMouse.flags() & QGraphicsItem.ItemIsSelectable
if bHadMovableFlagSet:
print "has ItemIsMovable"
else:
print "hasn't ItemIsMovable"
if bHadSelectableFlagSet:
print "has ItemIsSelectable"
else:
print "hasn't ItemIsSelectable"
if bWasSelected:
print "isSelected true"
else:
print "isSelected false"
itemUnderMouse.setSelected(False)
if event.button() == Qt.LeftButton:
print "mousePressEvent: left button is now down"
self.m_MouseIsDown = True
if self.dragMode() == QGraphicsView.ScrollHandDrag and event.button() == Qt.LeftButton:
print "mousePressEvent: left button down and ScrollHandDrag set"
self.PreventItemsFromMovingOrBeingSelectedWhenPannning(event)
return
print "mousePressEvent: pass through"
super(MyGraphicsView, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
print "mouseReleaseEvent"
if event.button() == Qt.LeftButton:
print "mouseReleaseEvent - left button is now up"
self.m_MouseIsDown = False
if self.dragMode() == QGraphicsView.ScrollHandDrag and self.m_ControlKeyDown == False:
print "mouseReleaseEvent - left button up, in ScrollHandDrag mode and control key is not pressed, change to RubberBandDrag"
self.setDragMode(QGraphicsView.RubberBandDrag)
super(MyGraphicsView, self).mouseReleaseEvent(event)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Control:
print "control key down"
self.m_ControlKeyDown = True
# ignore if mouse already down since we don't want to suddenly change to pan mode if an item is being moved
if event.key() == Qt.Key_Control and self.dragMode() != QGraphicsView.ScrollHandDrag and self.m_MouseIsDown == False:
print "keyPressEvent - control key down, mouse isn't down and drag mode is not ScrollHandDrag, change to ScrollHandDrag"
self.setDragMode(QGraphicsView.ScrollHandDrag)
super(MyGraphicsView, self).keyPressEvent(event)
def keyReleaseEvent(self, event):
if event.key() == Qt.Key_Control:
print "control key up"
self.m_ControlKeyDown = False
if event.key() == Qt.Key_Control and self.dragMode() == QGraphicsView.ScrollHandDrag and self.m_MouseIsDown == False:
print "keyReleaseEvent - control key up and drag mode is ScrollHandDrag, mouse is not pressed, change to RubberBandDrag"
self.setDragMode(QGraphicsView.RubberBandDrag)
super(MyGraphicsView, self).keyReleaseEvent(event)
def wheelEvent(self, event):
factor = 1.2;
if event.delta() < 0:
factor = 1.0/factor
self.scale(factor, factor)
def PreventItemsFromMovingOrBeingSelectedWhenPannning(self, mouseEvent):
itemUnderMouse = self.itemAt(mouseEvent.pos())
if itemUnderMouse is not None:
print "preventing item from moving"
bHadMovableFlagSet = itemUnderMouse.flags() & QGraphicsItem.ItemIsMovable
itemUnderMouse.setFlag(QGraphicsItem.ItemIsMovable, False)
bWasSelected = itemUnderMouse.isSelected()
bHadSelectableFlagSet = itemUnderMouse.flags() & QGraphicsItem.ItemIsSelectable
itemUnderMouse.setFlag(QGraphicsItem.ItemIsSelectable, False)
super(MyGraphicsView, self).mousePressEvent(mouseEvent)
if bHadMovableFlagSet:
print "set ItemIsMovable"
itemUnderMouse.setFlag(QGraphicsItem.ItemIsMovable, True)
if bHadSelectableFlagSet:
print "set ItemIsSelectable"
itemUnderMouse.setFlag(QGraphicsItem.ItemIsSelectable, True)
if bWasSelected:
print "setSelected True"
itemUnderMouse.setSelected(True)
else:
print "no item under mouse - pass through"
super(MyGraphicsView, self).mousePressEvent(mouseEvent)
class MyGraphicsScene(QGraphicsScene):
def __init__(self, parent):
super(MyGraphicsScene, self).__init__()
def main():
a = QApplication(sys.argv)
w = MyMainWindow()
w.show()
scene = MyGraphicsScene(w)
w.gv.setScene(scene)
rect = scene.addRect(10, 10, 40, 40)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
rect = scene.addRect(40, 40, 40, 40)
rect.setFlag(QGraphicsItem.ItemIsSelectable)
rect.setFlag(QGraphicsItem.ItemIsMovable)
sys.exit(a.exec_())
if __name__ == '__main__':
main()
我可以通过设置的QGraphicsView没有互动,而在ScrollHandDrag模式修复具有可以移动/可选项目的问题。 setInteractive(真); (C++) – FSaccilotto 2013-04-22 15:01:53