Je suis en train de créer une application PyQt qui est censée recevoir des clics avec le bouton droit de la souris sur un QGraphicsView, dessiner un "lasso" (une ligne qui s'étend de l'origine cercle à la position de la souris), puis, à la libération de la souris, effacez les graphiques lasso et affichez une boîte de dialogue de saisie pour la partie suivante de l'application.Artefact du menu Qt lors de l'appel de la boîte de dialogue
Pour une raison quelconque, lorsque j'utilise la souris pour cliquer sur "Ok" dans la boîte de dialogue de saisie, un artefact de menu apparaît sur QGraphicsView qui contenait le lasso. L'artefact de menu est une ligne de menu déroulant qui indique "(coche) Exit". Parfois, il peut aussi s'agir du menu contextuel d'un de mes QGraphicsObjects personnalisés - mais pour une raison quelconque, l'appel de la boîte de dialogue puis un clic sur "Ok" provoquent un événement indésirable de type clic droit sur QGraphicsView. Cela ne semble se produire que lorsque la dernière étape avant le retour de la méthode est le QInputDialog - le remplacer par un passage ou un appel à une autre méthode n'aboutit pas à l'artefact. Je serais très reconnaissant à quiconque avec une idée de ce qui cause ce problème!
Voici le code minimal:
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_())
À titre expérimental, essayez d'appeler la méthode de classe de base au début de votre implémentation, c'est-à-dire 'super(). MouseReleaseEvent (event)'. Vous pouvez également essayer d'appeler 'event.ignore()' avant l'appel de la classe de base. L'idée est de laisser tout comportement par défaut se produire (ou de l'ignorer explicitement) avant de faire vos propres trucs. – ekhumoro
Aucun changement lorsque j'appelle la méthode de classe de base, même avec event.ignore() avant elle. Cependant, je ne suis pas complètement surpris, car la méthode de classe de base ne produisait pas ces artefacts avant d'avoir ajouté QInputDialog (et aussi, l'artefact "(* check *) Exit" n'est pas ce que j'ai vu auparavant dans le comportement de ces vues et objets graphiques – Grav
Pouvez-vous fournir un exemple minimal et autonome pour que d'autres personnes puissent essayer de reproduire le problème? Sinon, vous forcez les gens à recourir à des devinettes – ekhumoro