2010-12-15 37 views
30

Tengo un QWidget que contiene varios elementos secundarios. El objetivo final es poder arrastrar y soltar de un widget al otro, moviendo algo entre widgets. Tengo una señal que se dispara al controlador de mi widget padre y puedo determinar cuándo el arrastre se inicia y finaliza correctamente. Mi problema actual es determinar si el mouse está arriba del widget de destino o no.Qt - Determine el widget absoluto y la posición del cursor

Me entusiasmé cuando vi underMouse en los documentos, pero no funciona durante los eventos de arrastrar y soltar (cuando lo probé, parecía devolver valores incorrectos). A falta de esto, mi objetivo era encontrar el rectángulo que contenía el widget de destino y encontrar si contenía las coordenadas del mouse con el mouse hacia arriba. No puedo simplemente usar contentsRect, ya que devuelve las posiciones relativas al widget al que se está llamando. Pensé que mapToGlobal me daría valores de píxel de pantalla absolutos, pero también falla. Intenté llamar a mapTo en la ventana del widget principal, pero también pareció fallar.

A continuación se muestra un código que muestra los diversos QRects y QPoints que he obtenido con los diversos métodos. Tal vez haya un error simple con una de ellas, así que las he proporcionado todas.

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 no va a funcionar para mis propósitos, ya que el control destino es en realidad secundario de ningún hijo de la matriz de nivel superior.

Actualización Aquí está el código que terminó funcionando. En mi aparato de nivel superior (que era un antepasado de la fuente y el destino de widgets), que añadió esto:

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

Respuesta

32

Como ya he dicho, debería usar targetWidget->geometry() en lugar de contentsRect() en este caso especial.

Siguiente Me pregunto a qué clase pertenece el código que ha publicado. El método QWidget::mapToGlobal() debe invocarse desde el QWidget cuyas coordenadas son relativas. Si te tengo derecho, que debe ser similar o menos así:

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

continuación, anote QCursor::pos() ya se está volviendo coordenadas de pantalla a nivel mundial, por lo que no hay necesidad de direccionar nada aquí:

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

EDIT: Probablemente es aún mejor para no asignar el rect a lo global, pero para mapear la posición del cursor global para el widget:

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

Aha, gracias! He actualizado mi pregunta con el código que terminó resolviendo mi problema. –

2

Quizás esté interesado para geometry() o frameGeometry() en QWidget. Ver here para más detalles.

0

Este método PyQt devolverá true si la posición del ratón está dentro del widge rect de t - incluyendo casos como ser el puntero del ratón sobre una vista combinado dentro el 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)) 
Cuestiones relacionadas