因为要实现一个功能是,拖动view所在的窗口,可以显示scene中所有的信息,在网上找了很多资料,都是在缩放后通过scrollView进行拖动的,但是这个拖动是有问题的,只是拖动对应的scrollView中的数据,这不是我要进行拖动可以看到出来viewport中的数据,还包括很多无法显示的scene的其他部分
代码如下:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include
#include
#include
#include
#include
#include class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
MainWindow(QWidget *parent = 0);
~MainWindow();
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private:
QGraphicsScene *scene;
QGraphicsView *view;
QWidget* sceneWidget;
QGraphicsPixmapItem* m_bkPixmapItem;
QPointF m_lastPointF;
qreal m_scale = 1;
};
#endif // MAINWINDOW_H
.cpp
#include "mainwindow.h"
#include MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(1200,800);
sceneWidget = new QWidget(this);
sceneWidget->setStyleSheet("border:none;
background:blue;
");
sceneWidget->setFixedSize(800,600);
view = new QGraphicsView(sceneWidget);
view->setStyleSheet("border:none;
background:lightgray;
");
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scene = new QGraphicsScene(sceneWidget);
//scene->setSceneRect(0,0,800,600);
view->setScene(scene);
//view->setSceneRect(0,0,800,600);
m_bkPixmapItem = new QGraphicsPixmapItem();
m_bkPixmapItem->setPixmap(QPixmap(":/3.bmp").scaled(1280,960,Qt::KeepAspectRatioByExpanding));
scene->addItem(m_bkPixmapItem);
view->resize(800,600);
view->scene()->setSceneRect(0,0,800,600);
this->setCentralWidget(sceneWidget);
}MainWindow::~MainWindow()
{}void MainWindow::wheelEvent(QWheelEvent *event)
{
view->scale(1/m_scale, 1/m_scale);
if(event->delta() > 0){
if(m_scale < 10){
m_scale += 0.2;
}else{
m_scale = 10;
}
}else{
if(m_scale > 0.2){
m_scale -= 0.2;
}else{
m_scale = 0.2;
}
}
view->scale(m_scale, m_scale);
qDebug()<pos();
}void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
QPointF disPointF = event->pos() - m_lastPointF;
m_lastPointF = event->pos();
view->scene()->setSceneRect(view->scene()->sceneRect().x()+disPointF.x(),view->scene()->sceneRect().y()+disPointF.y(),
view->scene()->sceneRect().width(),view->scene()->sceneRect().height());
view->scene()->update();
}void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{QGraphicsPixmapItem *m_bkPixmapItem1 = new QGraphicsPixmapItem();
m_bkPixmapItem1->setPixmap(QPixmap(":/3.bmp").scaled(1280,960,Qt::KeepAspectRatioByExpanding));
m_bkPixmapItem1->setPos(2000,0);
scene->addItem(m_bkPixmapItem1);
}
关键是在于,注释的两行(scene->setSceneRect(0,0,800,600); view->setSceneRect(0,0,800,600); )、添加的 (view->scene()->setSceneRect(0,0,800,600); )以及mouseMoveEvent()函数中的拖动的实现。
其实发现,整个拖动都是在对view的scene进行操作的,每次调用scene的setSceneRect()动态的设置场景的范围,就是类似在一直在调整scene通过view显示的部分,达到通过拖动事件,动态的显示整个scene的部分(scene是无限大)
程序运行示意图:
【QGraphicsView的缩放和拖动,以及缩放围绕鼠标所在点进行缩放】
补充:关于缩放的特殊要求,缩放以鼠标所在点进行缩放,即放大缩小的时候,鼠标的点的位置是不变的
修改wheelEvent()函数:(所记录的缩放是脱离了view的scroll,所以网上的实现相同功能是利用了scroll来处理的,但是原理是一致的)在整个缩放的过程中,view的坐标是不变的,所以我们可以采用鼠标所在位置的前后scene坐标的值的差值来计算需要偏移的数量。代码如下:
// 获取当前的鼠标所在的view坐标;
QPoint prev_viewPos = event->pos();
// 获取当前鼠标相对于scene的位置;
QPointF prev_scenePos = this->mapToScene(prev_viewPos);
//....计算缩放比例
scale(scaleTemp, scaleTemp);
//缩放
this->scene()->setSceneRect(this->mapToScene(this->rect()).boundingRect());
//调整scene,使得scene和view一直,主要是为了排除掉scroll//获取缩放后的scene坐标
QPointF scenePos = this->mapToScene(prev_viewPos);
//获取缩放前后的坐标差值,即为需要进行move的位移
QPointF disPointF = scenePos - prev_scenePos;
//qDebug()<scene()->sceneRect();
//调整位置
this->scene()->setSceneRect(this->scene()->sceneRect().x()-disPointF.x(),this->scene()->sceneRect().y()-disPointF.y(),
this->scene()->sceneRect().width(),this->scene()->sceneRect().height());
//emit signal_wheel(m_scale);
this->scene()->update();
备注:
//QWheelEvent是不存在delta()函数的。QGraphicsSceneWheelEvent的才是delta()函数;
QWheelEvent中的是angleDelta()函数。两个函数是一致的
推荐阅读
- Qt|Qt常用UI控件读取、写入方法
- Qt|Qt For Android 之启动页
- QT|QT面试
- QT安装
- qt|qt for android实现app内通过按键后台运行程序
- qt|qt for android程序保活 程序后台一直运行不被清理掉(未完)
- QWidget实现手机ipad屏幕滑屏效果
- Qt|Qt官方示例-QML Axes
- 在QT/QML中使用FontAwesome做图标显示
- QT|QtCreator2.7.0桌面快捷方式创建过程