Обработка событий средствами Qt (проблема с QTreeWidget)

Модератор: Модераторы разделов

Аватара пользователя
Алан
Сообщения: 18
ОС: Debian

Обработка событий средствами Qt

Сообщение Алан »

Есть приложение на базе QMainWindow. На форму помещаем два виджета QLabel и QTreeWidget. Задача - отловить и обработать все нажатия на кнопки мыши, когда курсор находится над одним из двух виджетов. Причем использовать для этой цели нужно именно события.
Поступаем как сказано в документации - устанавливаем фильтр событий (который event filter).

Код вот такой:

Код: Выделить всё

 class MainWindowImpl : public QMainWindow // наследуем от QMainWindow
 {
Q_OBJECT
     QWidget        centralWidget;

     QLabel           *label;
     QTreeWidget    *treeWidget;
     QHBoxLayout     *hBoxLayout;

     MainWindowImpl();

     bool eventFilter(QObject *target, QEvent *event);
 };


Код: Выделить всё

MainWindowImpl::MainWindowImpl() - конструктор формы
{
    hBoxLayout = new QHBoxLayout(&centralWidget); //привязываемся к центральному виджету
    treeWidget = new QTreeWidget();

       treeWidget->insertTopLevelItem(0, new QTreeWidgetItem); //чтобы TreeWidget не был пустым
       treeWidget->topLevelItem(0)->setText(0, "1");
       treeWidget->insertTopLevelItem(1, new QTreeWidgetItem);
       treeWidget->topLevelItem(1)->setText(0, "2");

     label = new QLabel("Click here");

    hBoxLayout->addWidget(label);
    hBoxLayout->addWidget(treeWidget);

    setCentralWidget(&centralWidget);

    hBoxLayout->installEventFilter(this); //устанавливаем фильтр
};

bool MainWindowImpl::eventFilter(QObject *target, QEvent *event) //наш обработчик событий
{
    if (event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *mouseEvent = (QMouseEvent *) event;
        std::cout<<mouseEvent->pos().x()<<"     "<<mouseEvent->pos().y()<<std::endl;    //в консоль выводим координаты
        return true;    //возвращаю true, событие обработано, дальнейшая обработка не требуется
    }
    return false;    //Событие должно быть обработано родительским виджетом
};


В результате, при клике на QLabel координаты нормально выводятся в консоль (произошел перехват события), а если кликнуть на QTreeWidget в консоль ничего не сбрасывается - т.е. событие не перехватывается. Строчки в QTreeWidget при этом правильно выделяются. Причем событие не отлавливается даже если явно указать treeWidget->installEventFilter(this). Чем можно объяснить такое поведение и как тогда правильно перехватывать события (другими словами, что делать и кто виноват)?
Спасибо сказали:
Аватара пользователя
Shura
Сообщения: 1537
Статус: Оказывается и без KDE есть жизнь
ОС: FreeBSD 8.0-RC2

Re: Обработка событий средствами Qt

Сообщение Shura »

Так лови события клика не на главной форме, а на самих элементах.
Rock'n'roll мертв © БГ
Спасибо сказали:
Аватара пользователя
Алан
Сообщения: 18
ОС: Debian

Re: Обработка событий средствами Qt

Сообщение Алан »

Сейчас я именно так и делаю, но хочется попробовать снаружи. Я код просто для примера привел, а в настоящем приложении снаружи было бы и логичнее и удобнее.
Спасибо сказали:
Аватара пользователя
Atragor
Сообщения: 681
Статус: ...

Re: Обработка событий средствами Qt

Сообщение Atragor »

Алан писал(а):
26.02.2008 22:14
В результате, при клике на QLabel координаты нормально выводятся в консоль (произошел перехват события), а если кликнуть на QTreeWidget в консоль ничего не сбрасывается - т.е. событие не перехватывается.

Перехватывается, но только при щелчке по самому краю QTreeWidget'a.


А вот так перехватывается везде, кроме полоски с заголовками колонок:

Код: Выделить всё

treeWidget->viewport()->installEventFilter(this);


И кстати, у меня почему-то при установке фильтра на hBoxLayout ни одна точка окна не реагирует на нажатия... Работает только если по отдельности на каждый виджет ставить.
If you were MEANT to understand it, we wouldn't have called it 'code' © bash.org
Спасибо сказали:
Аватара пользователя
Алан
Сообщения: 18
ОС: Debian

Re: Обработка событий средствами Qt

Сообщение Алан »

Спасибо, сам вчера докопался до этого viewport'а. :D

А по поводу hBoxLayout, я думаю, что события обрабатываются виджетами более низкого уровня (label и treeWidget соответственно), поэтому и не передаются родителю (hBoxLayout) вверх по цепочке.
Кстати в справке сказано, что можно установить фильтр событий для всего приложения, т.е. объекта QApplication, и это позволит перехватывать вообще все события для всех виджетов до того, как они попадут в соответствующие обработчики. А какому из виджетов отправлено событие узнавать по указателю target. Наверно, так даже проще - не надо по всему тексту вставлять installEventFiter'ы. Просто в одном месте определить какое событие какого объекта и как обрабатывать.

В общем, еще раз спасибо.
Спасибо сказали: