2010-12-15 59 views
30

J'ai un QWidget qui contient plusieurs enfants. Le but ultime est d'être capable de glisser et déposer d'un widget à l'autre, en déplaçant quelque chose entre les widgets. J'ai un signal envoyé au contrôleur de mon widget parent et je peux déterminer quand le glisser commence et se termine correctement. Mon problème actuel consiste à déterminer si la souris est au-dessus du widget cible à la souris.Qt - Déterminer la position absolue du widget et du curseur

Je me suis excité quand j'ai vu underMouse dans les docs, mais cela ne fonctionne pas pendant les événements de glisser-déposer (quand j'ai testé, il semblait retourner des valeurs incorrectes). A défaut, mon but était de trouver le rectangle contenant le widget cible et de trouver s'il contenait les coordonnées de la souris sur une souris. Je ne peux pas simplement utiliser contentsRect, car il renvoie des positions relatives au widget sur lequel il est appelé. Je pensais que mapToGlobal me donnerait des valeurs absolues de pixels d'écran, mais il continue à échouer aussi bien. J'ai essayé d'appeler mapTo sur la fenêtre du widget parent, mais cela semblait également échouer.

Ci-dessous est le code montrant les différents QRects et QPoints que j'ai obtenus avec les différentes méthodes. Peut-être qu'il y a une erreur simple avec l'un d'entre eux, alors je les ai tous fournis.

QRect relativeWidgetRect = targetWidget->contentsRect(); 
QRect *absoluteWidgetRect = new QRect(QWidget::mapToGlobal(relativeWidgetRect.topLeft()), QWidget::mapToGlobal(relativeWidgetRect.bottomRight())); 
QRect *widgetRect = new QRect(mapTo(window(), relativeWidgetRect.topLeft()), mapTo(window(), relativeWidgetRect.bottomRight())); 
QPoint relativeMousePos = QCursor::pos(); 
QPoint absoluteMousePos = QWidget::mapToGlobal(relativeMousePos); 
QPoint widgetMousePos = mapTo(window(), relativeMousePos); 

mapToParent ne fonctionnera pas pour mes besoins, puisque le widget cible est en fait par un enfant parented du parent haut niveau.

Mise à jour Voici le code qui a fini par s'arranger. Dans mon widget de haut niveau (qui était un ancêtre à la fois la source et des widgets cibles), j'ajouté:

QRect widgetRect = targetWidget->Geometry(); 
QPoint mousePos = targetWidget->mapFromGlobal(QCursor::pos()); 
if(widgetRect.contains(mousePos)) 
{ 
// Logic 
} 

Répondre

32

Comme déjà dit, vous devriez plutôt utiliser targetWidget->geometry() au lieu de contentsRect() dans ce cas particulier.

Ensuite, je me demande à quelle classe le code que vous avez posté appartient. La méthode QWidget::mapToGlobal() doit être appelée à partir du QWidget auquel vos coordonnées sont relatives. Si je vous ai droit, il devrait ressembler à quelque chose comme ceci:

QRect widgetRect = targetWidget->geometry(); 
widgetRect.moveTopLeft(targetWidget->parentWidget()->mapToGlobal(widgetRect.topLeft())); 

noter ensuite QCursor::pos() a déjà fourni coordonnées écran, donc pas besoin de carte quoi que ce soit ici:

if (widgetRect.contains(QCursor::pos())) { 
    /* swap widgets */ 
}

EDIT: C'est probablement encore mieux de ne pas cartographier le rect au global, mais pour cartographier la position globale du curseur sur le widget:

if (targetWidget->rect().contains(targetWidget->mapFromGlobal(QCursor::pos()))) { 
    /* do stuff */ 
}
+1

Aha, merci! J'ai mis à jour ma question avec le code qui a fini par résoudre mon problème. –

2

Peut-être que vous cherchez geometry() ou frameGeometry() à QWidget. Voir here pour plus de détails.

0

Cette méthode PyQt retourne vrai si la position de la souris est dans le widge Le rect de t - y compris cas tels que la souris étant sur une vue combo intérieur le widget

def underMouse(self): 
    pos = QtGui.QCursor.pos() 
    rect = self.rect() 
    leftTop  = self.mapToGlobal(QtCore.QPoint(rect.left(),rect.top())) 
    rightBottom = self.mapToGlobal(QtCore.QPoint(rect.right(),rect.bottom())) 
    globalRect = QtCore.QRect(leftTop.x(), leftTop.y(), rightBottom.x(), rightBottom.y()) 
    return globalRect.contains(self.mapToGlobal(pos))