Ответ 1
QGraphicsView поддерживает встроенную поддержку мыши. Установите правильный DragMode, и он будет обрабатывать остальные. Для этого вам нужны полосы прокрутки включения.
В настоящее время я могу загрузить свое изображение в сцену grahpics, а затем снова в QGraphicsViewer.
Я могу реализовать функцию масштабирования, отредактировав QEvent:: Wheel, а затем вызвав функцию scaleViews scale().
Однако я не могу понять, как работать с функцией панорамирования. Я в основном хочу обнаружить, когда мышь нажала на изображение, а затем переместите изображение влево, вправо, вверх или вниз вместе с мышью.
В настоящее время у меня в основном есть класс MouseFilter, который обнаруживает события и выполняет разные действия в зависимости от типа события. Я подключил этот слушатель к объекту QGraphicsView
QGraphicsView поддерживает встроенную поддержку мыши. Установите правильный DragMode, и он будет обрабатывать остальные. Для этого вам нужны полосы прокрутки включения.
Если кто-то задается вопросом, как это сделать сам по себе, на самом деле это довольно просто. Здесь код из моего приложения:
class ImageView : public QGraphicsView
{
public:
ImageView(QWidget *parent);
~ImageView();
private:
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
bool _pan;
int _panStartX, _panStartY;
};
Вам нужно сохранить начальную позицию перетаскивания, например, так (я использовал правую кнопку):
void ImageView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
_pan = true;
_panStartX = event->x();
_panStartY = event->y();
setCursor(Qt::ClosedHandCursor);
event->accept();
return;
}
event->ignore();
}
Кроме того, вам нужно очистить флаг и восстановить курсор после отпускания кнопки:
void ImageView::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton)
{
_pan = false;
setCursor(Qt::ArrowCursor);
event->accept();
return;
}
event->ignore();
}
Чтобы фактически управлять перетаскиванием, вам необходимо переопределить событие перемещения мыши. QGraphicsView наследует QAbstractScrollArea, и его полосы прокрутки легко доступны. Вам также необходимо обновить положение панорамирования:
void ImageView::mouseMoveEvent(QMouseEvent *event)
{
if (_pan)
{
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - (event->x() - _panStartX));
verticalScrollBar()->setValue(verticalScrollBar()->value() - (event->y() - _panStartY));
_panStartX = event->x();
_panStartY = event->y();
event->accept();
return;
}
event->ignore();
}
Решение neuviemeporte требует подкласса QGraphicsView.
Другая работающая реализация перетаскивания может быть получена без подклассификации представления с помощью eventFilter. Если вам не нужно настраивать другие поведения QGraphicsView, этот метод сэкономит вам некоторую работу.
Предположим, что ваша логика GUI поддерживается подклассом QMainWindow, а QGraphicsView и QGraphicsScene объявлены как частные члены этого подкласса. Вам нужно будет реализовать функцию eventFilter следующим образом:
bool MyMainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == scene && event->type() == Event::GraphicsSceneMouseMove)
{
QGraphicsSceneMouseEvent *m = static_cast<QGraphicsSceneMouseEvent*>(event);
if (m->buttons() & Qt::MiddleButton)
{
QPointF delta = m->lastScreenPos() - m->screenPos();
int newX = view->horizontalScrollBar()->value() + delta.x();
int newY = view->verticalScrollBar()->value() + delta.y();
view->horizontalScrollBar()->setValue(newX);
view->verticalScrollBar()->setValue(newY);
return true;
}
}
return QMainWindow::eventFilter(obj, event);
}
Чтобы фильтровать события из QGraphicsScene, вам необходимо установить MyMainWindow как eventFilter сцены. Возможно, вы можете сделать это в той же функции, где вы настраиваете свой графический интерфейс.
void MyMainWindow::setupGUI()
{
// along with other GUI stuff...
scene->installEventFilter(this);
}
Вы можете расширить эту идею, чтобы заменить курсор мышью "рука", как показано ранее.