我建立這應該接收鼠標右鍵拖動上的QGraphicsView一個PyQt的應用程序時,得出一個「套索」(線從拖拽源延伸到鼠標的位置,和然後在鼠標釋放時擦除套索圖形並顯示應用程序下一部分的輸入對話框。Qt的菜單神器調用輸入對話框
出於某種原因,當我用鼠標點擊「確定」輸入對話框,菜單神器出現在其包含的套索的QGraphicsView。菜單工件是一個下拉菜單行,其中顯示「(複選標記)退出」。偶爾它也可能是我的一個自定義QGraphicsObjects的上下文菜單 - 但無論出於何種原因,調用對話框然後單擊「確定」都會導致QGraphicsView出現意外的右鍵單擊事件。
這似乎只發生在方法的返回前的最後一步是QInputDialog - 有通行證或其他一些方法的調用不會導致神器替換它。我會非常感謝任何人提供有關導致此問題的線索。
下面是最少的代碼:
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_())
作爲一個實驗,嘗試調用基類的方法,在你開始執行,即'超()。mouseReleaseEvent(事件)'。你也可以在基類調用之前嘗試調用'event.ignore()'。這個想法是讓任何默認行爲在做自己的事情之前發生(或明確地忽略它)。 – ekhumoro
當我調用基類方法時,即使事先調用event.ignore(),也不會改變。然而,我並不完全感到驚訝,因爲基類方法沒有產生這些工件,直到我添加了QInputDialog(並且「(* check mark *)Exit」工件不是我以前見過的任何東西。這些意見和圖形對象的行爲 – Grav
你能提供一個最小的,自包含的例子,這樣其他人可以嘗試重現該問題,否則,你只是迫使人們訴諸猜測 – ekhumoro