Как передать событие click брату в Qt? - PullRequest
12 голосов
/ 06 апреля 2011

У меня есть два перекрывающихся виджета в окне: дочерний A и дочерний B. Дочерний A находится выше B и получает события мыши, но иногда щелчок должен пройти и в конечном итоге ударить дочерний B.

Идеальное решение будет иметьиспользовался event->ignore(), но это передает событие родительскому виджету, а не братьям и сестрам.

Решение "pass all" setAttribute(Qt::WA_TransparentForMouseEvents); также не работает, потому что дочернему элементу A необходимо перехватить некоторые события.

Как мне сказать Qt "Я не хочу обрабатывать это событие, действуй так, как будто меня там нет"?

Ответы [ 4 ]

3 голосов
/ 24 сентября 2013

Более простое решение (если применимо) - установить WA_TransparentForMouseEvents в зависимости от вашего условия перехода.

Например, если вы хотите щелкнуть по определенным регионам Child-A, вы можете использовать его mouseMoveEvent(), чтобы проверить, нужно ли устанавливать или не устанавливать WA_TransparentForMouseEvents. Затем события клика проходят автоматически.

Если вы не можете определить, следует ли принимать событие щелчка до его фактического запуска, вы можете сделать что-то вроде этого:

void ChildA::mousePressEvent(QMouseEvent* event) {
    const bool accepted = ...; //insert custom logic here
    if (accepted) {
        ... //handle event here
    } else {
        //not accepting event -> resend a copy of this event...
        QMouseEvent* eventCopy = new QMouseEvent(*event);
        QApplication::instance()->postEvent(eventCopy);
        //...but this time, ignore it
        setAttribute(Qt::WA_TransparentForMouseEvents, true);
        QTimer::singleSlot(1, this, SLOT(resetClickTransparency()));
        //don't propagate original event any further
        event->accept();
    }
}

void ChildA::resetClickTransparency() { //slot
    setAttribute(Qt::WA_TransparentForMouseEvents, false);
}

Отказ от ответственности: Все это записано наизусть после года бездействия Qt, поэтому, пожалуйста, исправьте меня в именах или ошибках типа.

1 голос
/ 14 сентября 2016

Вы можете также подойти к вопросу с другой стороны. Вместо того, чтобы пересылать события в «другой» виджет, вы могли бы, чтобы ваш другой виджет прослушивал события для первого виджета, используя фильтр событий. Я не уверен, подходит ли это вашему варианту использования, это зависит от того, кто / кто определяет, какие события должны обрабатываться каким объектом.

1 голос
/ 28 января 2013

Если событие должно быть проигнорировано Child-A, сгенерировать сигнал и захватить его своим родителем, тогда родитель генерирует новый сигнал, который будет захвачен Child-B

Child-A ->Родитель -> Ребенок-B
(Сигнал) -> (Слот) (Сигнал) -> (Слот)

0 голосов
/ 23 июля 2015

Вот возможный вариант:

  1. дать дочернему объекту B указатель на дочерний объект A.
  2. переопределить bool QObjet :: event (QEvent * event), чтобы при необходимости перенаправить событие дочернему элементу B.

Например:

bool WidgetA::event(QEvent *event)
 {
    QWidget::event( event);
    QEvent::Type type = event->type();
    if ( (type != QEvent::KeyPress) &&
         (type != QEvent::Wheel) &&
         (type != QEvent::MouseButtonDblClick) &&
         (type != QEvent::MouseMove) &&
         (type != QEvent::MouseButtonPress) )
        return true;
    //forward the event
    if ( m_pChildB )
         m_pChildB->event( event);
    return true;

 }

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...