Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с wheelEvent у QGraphicsView и QGraphicsScene.
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Система рисования. Печать
dartan
Есть свой класс сцены и свой просмотрщик - наследуемые класы от QGraphicsScene и QGraphicsView.
Задача такая: нужно колесиком мыши (без зажатых клавиш) менять масштаб, а не скроллить. Событие колеса ловлю в своем просмотрщике. Проблема в том, что если в своем обработчике колеса делать только масштабирование и не вызывать обработчик базового класса QGraphicsView::wheelEvent(), то это событие не дойдет до сцены и, соответственно, не дойдет до виджетов на ней. А там у меня лежат, к примеру, спинбоксы, которым это событие нужно. Если же вызвать базовый обработчик QGraphicsView::wheelEvent(), то событие доходит до сцены, но при этом сцена каким-то образом вызывает еще и скроллинг у просмотрщика, а мне это не нужно. Как запретить такой скроллинг? Естественно, полосы прокрутки должны остаться, чтоб пользователь сам мог скроллить.
Trisch
А можно примерный код показать?
dartan
Сейчас сделано примерно вот так.
h
class DiagramScene : public QGraphicsScene
{
};

class DiagramView : public QGraphicsView
{
public:
    void wheelEvent(QWheelEvent* event);
};

cpp
void DiagramView::wheelEvent(QWheelEvent* event)
{
    // здесь делается масштабирование
    if(event->delta() > 0)
    {
        // ...
    }

    // QGraphicsView::wheelEvent(event);
}


Так работает масштабирование, но не работает изменение значения на спинбоксе. Если последнюю строчку раскомментировать, то работает и масштабирование, и изменение значения, но еще прокручивается вертикальный слайдер.
Trisch
А вы пробовали переопределить wheelEvent() самой сцены?
dartan
Цитата(Trisch @ 14.9.2013, 17:57) *
А вы пробовали переопределить wheelEvent() самой сцены?

Да, пробовал, получается следующее:
class DiagramScene : public QGraphicsScene
{
public:
    void wheelEvent(QGraphicsSceneWheelEvent * event);
};


void DiagramScene::wheelEvent(QGraphicsSceneWheelEvent* event)
{
    QGraphicsScene::wheelEvent(event);
    bool accepted = event->isAccepted();
}


Первым вызывается обработчик из QGraphicsView, затем вызывается обработчик QGraphicsScene. Если крутануть колесо на свободном месте, то после строчки QGraphicsScene::wheelEvent(event) срабатывает скроллинг и accepted == false. Если крутануть на спинбоксе, то меняется его значение и accepted == true. То есть все равно я не могу добраться до того места, откуда сцена заставляет выполнять скроллинг.
З.Ы. Qt 4.8.4.
Trisch
А при переопределении QGraphicsView::wheelEvent(event), масштабирование, изменение значений и скролинг одновременно срабатывают или их срабатывание зависит от места нахождения курсора мыши?

Если второе то попробуйте настроить режим работы QGraphicsView::wheelEvent(event) в зависимости от места нахождения курсора мыши.
dartan
Цитата(Trisch @ 14.9.2013, 22:47) *
А при переопределении QGraphicsView::wheelEvent(event), масштабирование, изменение значений и скролинг одновременно срабатывают или их срабатывание зависит от места нахождения курсора мыши?

Если второе то попробуйте настроить режим работы QGraphicsView::wheelEvent(event) в зависимости от места нахождения курсора мыши.

Не совсем понял мысль... Масштабирование и скроллинг всегда срабатывают, даже если курсор над спинбоксом. Ну и сам спинбокс меняет значение, если курсор над ним.
Вы имеете ввиду, что нужно проверять, есть ли под курсором объект, и в зависимости от этого в DiagramView::wheelEvent(QWheelEvent* event) либо масштабировать, либо просто вызывать QGraphicsView::wheelEvent(event)?
ViGOur
Глянь пример: 40000 Chips, кажется там есть то, что тебе нужно...
Trisch
Цитата(dartan @ 16.9.2013, 11:18) *
Вы имеете ввиду, что нужно проверять, есть ли под курсором объект, и в зависимости от этого в DiagramView::wheelEvent(QWheelEvent* event) либо масштабировать, либо просто вызывать QGraphicsView::wheelEvent(event)?


Да, именно это я имел в виду.
dartan
Цитата(Trisch @ 16.9.2013, 14:44) *
Цитата(dartan @ 16.9.2013, 11:18) *
Вы имеете ввиду, что нужно проверять, есть ли под курсором объект, и в зависимости от этого в DiagramView::wheelEvent(QWheelEvent* event) либо масштабировать, либо просто вызывать QGraphicsView::wheelEvent(event)?


Да, именно это я имел в виду.

Это вариант, но будет недостаточно просто проверить наличие объекта под курсором. Есть такие объекты на сцене, которые не активны для пользователя, поэтому ему покажется странным, если не будет работать масштабирование :) Придется проверять конкретный тип объектов, типа если ты спинбокс, тогда мы не масштабируем...
Мне непонятно, как вообще событие от сцены доходит до вертикального скроллбара. Ненужный мне скроллинг делается после строчки QGraphicsScene::wheelEvent(event); но я глянул в исходнике qgraphicsscene.cpp и не увидел, когда же оно отправляется просмотрщику QGraphicsView.
Цитата(ViGOur)
Глянь пример: 40000 Chips, кажется там есть то, что тебе нужно...

Посмотрел, но там вроде всё просто, масштабирование полосами прокрутки сделано.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.