Russian Qt Forum
Ноябрь 23, 2024, 12:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Пересекающиеся MouseAreas  (Прочитано 7804 раз)
vregess
Гость
« : Сентябрь 01, 2013, 20:22 »

Есть красный квадрат, а над ним серая "панель" с синим квадратом.
Нужно изолировать мышиные события внутри серой панели (topRect).

Частично проблему решил добавлением MouseArea для topRect - теперь клики не передаются ниже.
Но вот при наведении на красный квадрат курсор меняет вид.
Как исправить?

Код
Javascript
import QtQuick 2.0
 
Rectangle {
   width: 500; height: 400; color: "#fff"
 
   Rectangle {
       id: bottomRect
       width: 100; height: 100; x: 20; y: 50; color: "red"
 
       MouseArea {
           anchors.fill: parent
           cursorShape: Qt.PointingHandCursor
           onClicked: console.log("red clicked")
       }
   }
 
   Rectangle {
       id: topRect
       anchors.fill: parent; opacity: 0.8; color: "#ccc";
 
       MouseArea {
           anchors.fill: parent
           hoverEnabled: true
           preventStealing: true
           propagateComposedEvents: false
           cursorShape: Qt.ArrowCursor
           acceptedButtons: Qt.AllButtons
           //onPositionChanged: mouse.accepted = true
       }
       Rectangle {
           width: 100; height: 100; x: 200; y: 250; color: "blue"
           MouseArea {
               anchors.fill: parent
               cursorShape: Qt.PointingHandCursor
               propagateComposedEvents: false
               onClicked: console.log("blue clicked")
           }
       }        
   }
}
 
« Последнее редактирование: Сентябрь 02, 2013, 20:44 от ck » Записан
vregess
Гость
« Ответ #1 : Сентябрь 02, 2013, 07:49 »

Придумал 2 варианта.

1) Средствами QML
У "обычных" MouseArea используем:
Код
Javascript
 hoverEnabled: true
 cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
 

У "блокирующего" MouseArea:
Код
Javascript
 cursorShape: Qt.ArrowCursor
 acceptedButtons: Qt.AllButtons
 hoverEnabled: true
 
Пример во вложении (example1.qml)
Недостаток в том, что везде надо указывать hoverEnabled, что по идее генерирует много событий. Плюс containsMouse тоже надо везде.

2) Средствами с++
Наследуемся от QQuickItem и запрещаем дальнейшую обработку событий мыши.
Код
C++ (Qt)
class MouseBlocker: public QQuickItem
{
   Q_OBJECT
public:
   MouseBlocker(QQuickItem *parent = 0);
 
protected:
   ...
   virtual void mouseMoveEvent(QMouseEvent *event);
   ...
};
 
...
void MouseBlocker::mouseMoveEvent(QMouseEvent *event)
{
   event->accept();
}
 

Регистрируем
Код
C++ (Qt)
qmlRegisterType<MouseBlocker>("aux.tools", 1, 0, "MouseBlocker");
 

и используем
Код
Javascript
import aux.tools 1.0
 
Item {
   MouseBlocker {
       anchors.fill: parent
   }
}
 
Недостаток: нужно использовать с++

Есть ли более очевидные решения? Хотелось бы все сделать только на стороне QML.
Очень странно, что нет каких-то стандартных способов.
Записан
lighting
Гость
« Ответ #2 : Сентябрь 02, 2013, 11:40 »

Очень странно, что нет каких-то стандартных способов.
Ничего странного, сложные расчеты надо проводить в C++. QML не на это заточен, поэтому там и ограничиваются прямоугольной областью MouseArea
Записан
OKTA
Гость
« Ответ #3 : Сентябрь 02, 2013, 11:41 »

у MouseArea всегда была штучка "accepted", которая отвечала за распространение событий.
Записан
vregess
Гость
« Ответ #4 : Сентябрь 02, 2013, 11:57 »

Ничего странного, сложные расчеты надо проводить в C++. QML не на это заточен, поэтому там и ограничиваются прямоугольной областью MouseArea

Даже и не знаю, у меня наверное треугольная область. И где тут сложные расчеты?

у MouseArea всегда была штучка "accepted", которая отвечала за распространение событий.

Да, у событий есть такое свойство, и вроде как сейчас не надо явно его указывать в обработчике, чтобы запретить дальнейшую обработку.
Я пробовал и с ним, на изменение курсора это не повлияло (пробовал onPositionChanged: mouse.accepted = true).
Записан
OKTA
Гость
« Ответ #5 : Сентябрь 02, 2013, 18:03 »

попробовать не могу, к сожалению.( сижу в 4.7.4 еще))
Записан
vregess
Гость
« Ответ #6 : Сентябрь 02, 2013, 20:44 »

Ничего страшного. Я пока остановился на варианте с++.
Мне кажется это либо баг, либо какое-то упущение в АПИ или реализации.
Записан
lighting
Гость
« Ответ #7 : Сентябрь 03, 2013, 10:08 »

Ничего странного, сложные расчеты надо проводить в C++. QML не на это заточен, поэтому там и ограничиваются прямоугольной областью MouseArea

Даже и не знаю, у меня наверное треугольная область. И где тут сложные расчеты?
Проверка для прямоугольной области:
Если больше х1 и меньше х2 и y больше y1 и меньше y2 тогда ...
Плюс преобразование координат - масштабирование и поворот.
Вот это простые расчеты, ваш случай несколько отличается. Я не говорю что расчеты в вашем случае невероятно трудны, но они несколько сложнее вышеприведенных. QML и JS в применении к QML не для расчетов - для этого есть C++, вот примерно такая логика я думаю была у троллей. Впрочем если вы считаете что это баг то напишите багрепорт, если тролли с вами согласны в этом вопросе то они быстро этот баг устранят.
Записан
vregess
Гость
« Ответ #8 : Сентябрь 10, 2013, 09:50 »

Да, может пороюсь в багтрекере, когда время появится.
Записан
qml_hello
Гость
« Ответ #9 : Июнь 10, 2014, 16:40 »

propagateComposedEvents : bool

This property holds whether composed mouse events will automatically propagate to other MouseAreas that overlap with this MouseArea but are lower in the visual stacking order.

Код:

import QtQuick 2.0

Rectangle {
    color: "yellow"
    width: 100; height: 100

    MouseArea {
        anchors.fill: parent
        onClicked: console.log("clicked yellow")
    }

    Rectangle {
        color: "blue"
        width: 50; height: 50

        MouseArea {
            anchors.fill: parent
            propagateComposedEvents: true
            onClicked: {
                console.log("clicked blue")
                mouse.accepted = false
            }
        }
    }
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.097 секунд. Запросов: 21.