2015-10-08 7 views
0

У меня странная проблема, что я не смог определить причину. В принципе, я создал 2D-представление с функциями панорамирования и масштабирования и сцену с элементами, которые могут перемещаться с привязкой сетки. Чтобы переместить элемент в сцену, я продлил Scene::mousePressEvent, чтобы получить указатель на этот элемент, и Scene::mouseMoveEvent, чтобы сохранить элемент, отслеживаемый курсором. Чтобы удалить элемент, я снова использовал Scene::mousePressEvent. Чтобы кастрюлю, я продлил View::mousePressEvent, View::mouseReleaseEvent и View::mouseMoveEvent и увеличил масштаб. Я увеличил View::wheelEvent.QGraphicsScene mouseMoveEvent не работает до тех пор, пока QGraphicsView wheelEvent

Теперь симптомы:

я запустить приложение с элементом в сцене. Если я нажимаю и удерживаю, то переместите мышь, элемент движется по назначению. Как только я отпущу кнопку мыши, элемент перестанет двигаться. Я могу нажать, чтобы отбросить, и элемент помещается в соответствии с кодом возврата в Scene::mousePressEvent. Повторите попытку и все еще элемент перемещается только при нажатии кнопки мыши.

Затем приходит странная часть: Если я использую колесо мыши, чтобы увеличить изображение, все будет выполняться так, как ожидается после этого события. Щелчок мышью, чтобы выбрать элемент, он перемещается, когда я перемещаю мышь и падает, когда я нажимаю снова.

Так очевидное решение:

wheelEvent(new QWheelEvent(QPointF(0,0),0,Qt::NoButton,Qt::NoModifier)); 

вызывается при создании View и все работает отлично. Он вызывает расширенный View::wheelEvent без каких-либо изменений в представлении и до того, как сцена создана даже, но потом программы ведут себя так, как ожидалось.

Так что я здесь, чтобы узнать, может ли кто-нибудь из замечательных экспертов Qt объяснить это странное поведение. Любые комментарии или направление приветствуются.

В случае, если это помогает, вот код переопределения View::wheelEvent. tform - это QTransform, с которым я поддерживаю масштабирование. Кроме того, я пробовал использовать и без вызова базового метода, но никаких изменений в поведении нет.

void SchematicView::wheelEvent(QWheelEvent* event) 
{ 
    // Scale the view/do the zoom 
    double scaleFactor = 1.1; 

    if(event->delta() > 0 && tform.m11() < max_zoom) { 
     tform.scale(scaleFactor,scaleFactor); 
    } else if (event->delta() < 0 && tform.m11() > min_zoom){ 
     tform.scale(1.0/scaleFactor,1.0/scaleFactor); 
    } 

    setTransformationAnchor(QGraphicsView::AnchorUnderMouse); 
    setTransform(tform); 

    QGraphicsView::wheelEvent(event); 

} 
+0

Обратите внимание, что ваше очевидное решение утечки объекта QWheelEvent ... вам лучше разместить объект QWheelEvent в стеке или, по крайней мере, удалить его после возврата wheelEvent(). –

ответ

2

Без SSCCE смотреть и тест с, это трудно сказать наверняка, но то, что вы описываете, звучит много, как ваш mouseMoveEvent() обратного вызова только получение вызывается, когда мышь во время перемещения удерживается кнопка. Это, в свою очередь, звучит очень похоже на ожидаемое поведение для mouseMoveEvent(), как описано в QWidget::mouseMoveEvent():

Если отслеживание мыши выключено, события перемещения мыши происходят только если кнопка мыши нажата в то время как мыши перемещается. Если мышь включена, события перемещения мыши происходят, даже если не нажата кнопка мыши .

Если это действительно проблема, тогда звонок в setMouseTracking(true) может привести к поведению, которое вы ищете.

На более широком уровне обратите внимание, что есть более простые способы получения поведения, которое вы пытаетесь реализовать, например, чтобы позволить пользователю перетаскивать элементы в QGraphicsScene, все, что вам действительно нужно сделать, - это позвонить setFlags (QGraphicsItem :: ItemIsMovable) на любых QGraphicsItems, которые вы хотите, чтобы пользователь мог перемещаться. Никакое ручное кодирование обработчиков событий не требуется, если вы не пытаетесь получить некоторые нестандартные поведения.

+0

Я думаю, что вы на что-то с setMouseTracking (правда). Я попробую это завтра. Что касается кодировки сцены, мне нужно привязать к сетке, поэтому мне нужно обработать прессу. Я ценю предложение ItemIsMovable, но я создал свои собственные классы Item, которые представляют разные формы и pixmaps, и поскольку мне пришлось переопределить событие виртуальной краски, я не заметил, что флаги ничего не делают. Если у вас есть предложения по использованию пользовательского класса элемента с подвижным поведением по умолчанию, которое я могу привязать к сетке, я был бы очень рад его услышать. Нет причин изобретать велосипед. Каламбур не предназначен. – Johnny

+0

Я считаю, что стандартная функция перемещения элементов может быть использована для работы с пользовательскими подклассами QGraphicsItem (я сам не пробовал, но был бы удивлен, если бы это было невозможно). Что касается snap-to-grid, я думаю, что способ реализовать это было бы переопределить метод itemChange (GraphicsItemChange change, const QVariant & value) в вашем подклассе QGraphicsItem, а в случае, когда (изменение) равно ItemPositionChange, возвращает привязку -to-grid для элемента. (см. примечание здесь: http://doc.qt.io/qt-4.8/qgraphicsitem.html#GraphicsItemChange-enum) –

+0

Благодарим вас за решение проблемы с отслеживанием мыши. Я чувствую себя глупым, потому что спросил, потому что я искал документы перед тем, как приехать сюда, и не понял, как wheelEvent был связан с mouseMove. – Johnny

 Смежные вопросы

  • Нет связанных вопросов^_^