Как отключить доставку событий мыши виджету, но не его дочерним элементам в Qt?
С последних двух дней я ищу и выясняю способ передачи событий мыши виджетам позади виджета, используемого в качестве контейнера/родителя для его детей. Я знаю, что есть способ сделать виджет прозрачным для событий мыши, как это:
QWidget w;
w.setAttribute( Qt::WA_TransparentForMouseEvents );
но это также отключает доставку событий мыши своим детям! На самом деле я хочу, чтобы дети переднего виджета и виджеты за передним виджетом реагировали на события мыши.
Qt:: WA_TransparentForMouseEvents: при включении этот атрибут отключает доставку событий мыши виджету и его дочерним элементам. События мыши доставляются в другие виджеты, как если бы виджет и его дети не присутствовали в иерархии виджетов; щелчки мыши и другие события эффективно "проходят" через них. Этот атрибут по умолчанию отключено.
Если у вас есть идеи о том, как сделать виджет прозрачным для событий мыши, но не для детей тогда, пожалуйста, поделитесь!
2 ответов
наконец-то я нашел решение :) Этот ответ для тех, кто находится в поисках решения для такого рода проблем.
решение OP является удивительным и очень элегантным. Просто для полноты другой вариант-игнорировать события мыши, когда они достигают виджета контейнера. Это можно сделать либо путем подкласса, либо через eventFilter
.
это решение может быть полезно, если виджет скрывает / показывает много дочерних виджетов динамически и вычисление маски становится трудным.
Примечание: В случае, если вы хотите отслеживать мышь-перемещение событий в фоновых виджетах, тебе придется ... --13-->setMouseTracking(true)
чтобы получить (а затем игнорировать)QEvent::MouseMove
когда кнопка не нажата.
пример по подклассу
ContainerWidget::ContainerWidget(...) {
setMouseTracking(true);
}
void ContainerWidget::mouseMoveEvent(QMouseEvent* e) {
e->ignore();
}
void ContainerWidget::mousePressEvent(QMouseEvent* e) {
e->ignore();
}
пример использования фильтра событий
// Assume the container widget is configured in the constructor
MainWindow::MainWindow(...) {
// ...
containerWidget->installEventFilter(this);
containerWidget->setMouseTracking(true);
// ...
}
bool MainWindow::eventFilter(QObject* o, QEvent* e) {
if (o == containerWidget &&
(e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonPress)) {
e->ignore();
return false;
}
return QMainWindow::eventFilter(o, e);
}