Подтвердить что ты не робот

Qt - определение абсолютного виджета и положения курсора

У меня есть QWidget, содержащий несколько дочерних элементов. Конечной целью является возможность перетаскивания с одного виджета на другой, перемещение чего-то между виджетами. У меня есть сигнал, который запускается в контроллер родительского виджета и может определить, когда перетаскивание начинается и заканчивается правильно. Моя текущая проблема - определить, находится ли мышь над целевым виджетами на мыши вверх.

Я взволновался, когда увидел в документах underMouse, но он не работает во время событий перетаскивания (когда я тестировал, он, казалось, возвращал неверные значения). В противном случае моя цель состояла в том, чтобы найти прямоугольник, содержащий целевой виджет, и найти, содержит ли он координаты мыши с помощью мыши. Я не могу просто использовать contentsRect, так как он возвращает позиции относительно виджета, на который он вызывается. Я подумал, что mapToGlobal даст мне абсолютные значения пикселя экрана, но он также будет терпеть неудачу. Я попытался вызвать mapTo в окне родительского виджета, но это также, казалось, не получилось.

Ниже приведен код, показывающий различные QRect и QPoints, которые я получил с помощью различных методов. Может быть, есть простая ошибка с одним из них, поэтому я предоставил их всем.

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 не будет работать для моих целей, так как целевой виджет на самом деле является родителем родителя верхнего уровня.

Обновить. Здесь код, который закончился разработкой. В моем виджете верхнего уровня (который был предком как для исходного, так и для целевого виджета), я добавил следующее:

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

Ответ 1

Как уже говорилось, вы должны использовать targetWidget->geometry() вместо contentsRect() в этом специальном случае.

Далее я задаюсь вопросом, к какому классу принадлежит ваш код. Метод QWidget::mapToGlobal() должен быть вызван из QWidget, к которому относятся ваши координаты. Если я правильно понял, это должно выглядеть примерно так:

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

Затем обратите внимание, что QCursor::pos() уже возвращает глобальные координаты экрана, поэтому здесь ничего не нужно сопоставлять:

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

РЕДАКТИРОВАТЬ: Возможно, даже лучше не сопоставить прямую глобальную, а отобразить позицию глобального курсора в виджетах:

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

Ответ 2

Возможно, вы ищете geometry() или frameGeometry() в QWidget. Подробнее см. здесь.

Ответ 3

Этот метод PyQt вернет True, если позиция мыши находится внутри прямоугольника виджетов, включая такие случаи, как мышь, находящаяся над комбинированным представлением внутри виджета

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))