我正在构建一个PyQt应用程序,它应该在QGraphicsView上接收鼠标右键单击的拖动,绘制一条“套索”(从拖动原点延伸到鼠标位置的直线,在鼠标位置画一个圆圈),然后,在鼠标释放时,删除套索图形并显示应用程序下一部分的输入对话框。在
出于某种原因,当我用鼠标点击输入对话框上的“确定”时,一个菜单工件出现在包含套索的QGraphicsView上。菜单工件是一个下拉菜单行,显示“(复选标记)Exit”。有时它也可能是我的一个自定义QGraphicsObject的上下文菜单,但是不管出于什么原因,调用对话框然后单击“确定”会导致QGraphicsView上出现意外的类似右键单击的事件。在
只有在方法返回之前的最后一步是QInputDialog时才会出现这种情况—用pass或对其他方法的调用替换它不会导致工件。如果有人知道是什么导致了这个问题,我将非常感激!在
以下是最小的代码:
import sys
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
# The app main window.
def __init__(self):
super(Window, self).__init__()
# Initialize window UI
self.initUI()
def initUI(self, labelText=None):
# Set user-interface attributes.
# Set up menu-, tool-, status-bars and add associated actions.
self.toolbar = self.addToolBar('Exit')
# Create a menu item to exit the app.
exitAction = QtGui.QAction(QtGui.QIcon('icons/exit.png'), '&Exit', self)
exitAction.triggered.connect(QtGui.qApp.quit)
self.toolbar.addAction(exitAction)
# Create the main view.
self.viewNetwork = NetworkPortal()
self.viewNetwork.setMinimumWidth(800)
self.viewNetwork.setMinimumHeight(800)
self.setCentralWidget(self.viewNetwork)
self.show()
class NetworkPortal(QtGui.QGraphicsView):
# A view which allows you to see and manipulate a network of nodes.
def __init__(self):
super(NetworkPortal, self).__init__(QtGui.QGraphicsScene())
# Add the CircleThing graphic to the scene.
circleThing = CircleThing()
self.scene().addItem(circleThing)
class CircleThing(QtGui.QGraphicsEllipseItem):
# Defines the graphical object.
def __init__(self):
super(CircleThing, self).__init__(-10, -10, 20, 20)
# Set flags for the graphical object.
self.setFlags(
QtGui.QGraphicsItem.ItemIsSelectable |
QtGui.QGraphicsItem.ItemIsMovable |
QtGui.QGraphicsItem.ItemSendsScenePositionChanges
)
self.dragLine = None
self.dragCircle = None
def mouseMoveEvent(self, event):
# Reimplements mouseMoveEvent to drag out a line which can, on
# mouseReleaseEvent, form a new Relationship or create a new Thing.
# If just beginning a drag,
if self.dragLine == None:
# Create a new lasso line.
self.startPosX = event.scenePos().x()
self.startPosY = event.scenePos().y()
self.dragLine = self.scene().addLine(
self.startPosX,
self.startPosY,
event.scenePos().x(),
event.scenePos().y(),
QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.SolidLine)
)
# Create a new lasso circle at the location of the drag position.
self.dragCircle = QtGui.QGraphicsEllipseItem(-5, -5, 10, 10)
self.dragCircle.setPos(event.scenePos().x(),
event.scenePos().y())
self.scene().addItem(self.dragCircle)
# If a drag is already in progress,
else:
# Move the lasso line and circle to the drag position.
self.dragLine.setLine(QtCore.QLineF(self.startPosX,
self.startPosY,
event.scenePos().x(),
event.scenePos().y()))
self.dragCircle.setPos(event.scenePos().x(),
event.scenePos().y())
def mouseReleaseEvent(self, event):
# If the line already exists,
if self.dragLine != None:
# If the released button was the right mouse button,
if event.button() == QtCore.Qt.RightButton:
# Clean up the link-drag graphics.
self.scene().removeItem(self.dragLine)
self.dragLine = None
self.scene().removeItem(self.dragCircle)
self.dragCircle = None
# Create the related Thing.
# Display input box querying for name value.
entry, ok = QtGui.QInputDialog.getText(None, 'Enter some info: ',
'Input:', QtGui.QLineEdit.Normal, '')
return
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
newWindow = Window()
sys.exit(app.exec_())
对于这个错误的原因没有直接的答案,但是使用单发QTimer()调用对话框(与QSignalMapper结合以输入参数)是一种功能性解决方法,它将对话框与发生错误的方法分开。感谢@Avaris。在
这是我的猜测,但我以前见过这种奇怪的事。在
一些Qt小部件对某些类型的事件具有默认行为。我从未使用过QGraphicsView,但通常右键单击的默认设置是打开一个上下文相关的弹出菜单(在我的经验中,通常是无用的)。这可能发生在您的案例中,这就解释了为什么只有右键单击时才会看到这个。在
在从
mouseReleaseEvent.
返回之前,可以通过调用event.ignore()
来抑制默认的Qt行为相关问题 更多 >
编程相关推荐