我目前可以将图像加载到图形场景中,然后再加载到QGraphicsViewer中。
我可以通过检测QEvent :: Wheel事件并调用graphicsView的scale()函数来实现缩放功能。
但是,我似乎无法弄清楚如何使平移功能工作。 我基本上想要检测鼠标是否在图像上单击,然后随着鼠标而将图像向左、右、上或下移动。
截至目前,我基本上有一个MouseFilter类来检测事件,并根据事件类型执行不同的操作。我将该侦听器附加到了QGraphicsView对象上。
我目前可以将图像加载到图形场景中,然后再加载到QGraphicsViewer中。
我可以通过检测QEvent :: Wheel事件并调用graphicsView的scale()函数来实现缩放功能。
但是,我似乎无法弄清楚如何使平移功能工作。 我基本上想要检测鼠标是否在图像上单击,然后随着鼠标而将图像向左、右、上或下移动。
截至目前,我基本上有一个MouseFilter类来检测事件,并根据事件类型执行不同的操作。我将该侦听器附加到了QGraphicsView对象上。
如果有人想知道如何自己完成,实际上非常简单。这是我应用程序的代码:
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();
}
QGraphicsView内置了鼠标平移支持。设置正确的DragMode,其余操作会被自动处理。但你需要启用滚动条才能使其生效。
neuviemeporte解决方案需要对QGraphicsView进行子类化。
如果不需要自定义QGraphicsView的其他行为,可以使用eventFilter而无需对视图进行子类化来实现拖动。这种技术可以节省一些工作量。
假设您的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安装为场景的事件过滤器。也许您可以在设置GUI的同一函数中完成此操作。
void MyMainWindow::setupGUI()
{
// along with other GUI stuff...
scene->installEventFilter(this);
}
QGraphicsView
的人来说 :) - Maxime Franchot