第7章:QGraphicsView

1,QGraphicsView视图类显示

2,源码:

#include "mainwindow.h"
#include <QApplication>
#include "mapwidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();

    MapWidget mapWidget;
    mapWidget.show();

    return a.exec();
}
#include "mapwidget.h"

MapWidget::MapWidget(QWidget *parent) : QGraphicsView(parent)
{
    readMap();                                               //读取地图描述信息

    zoom = 50;

    int width  = map.width();
    int height = map.height();

    QGraphicsScene *scene = new QGraphicsScene(this);        //新建一个 QGraphicsScene对象为主串口连接一个场景
    scene->setSceneRect(-width/2, -height/2, width, height); //限定场景的显示区域为地图的大小,坐标原点在中心点
    setScene(scene);                                         //view设置场景
    setCacheMode(CacheBackground);

    //用于地图缩放的滑动条
    QSlider *slider = new QSlider;                            //新建一个QSlider对象作为地图缩放控制
    slider->setOrientation(Qt::Vertical);
    slider->setRange(1, 100);
    slider->setTickInterval(10);
    slider->setValue(50);
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int)));

    QLabel *zoominLabel = new QLabel;
    zoominLabel->setScaledContents(true);
    zoominLabel->setPixmap(QPixmap(":/image/zoomin.png"));

    QLabel *zoomoutLabel = new QLabel;
    zoomoutLabel->setScaledContents(true);
    zoomoutLabel->setPixmap(QPixmap(":/image/zoomout.png"));

    //坐标值显示区
    QLabel *label1 = new QLabel(tr("GraphicsView:"));
    label1->setAlignment(Qt::AlignRight);
    viewCoord = new QLabel;
    viewCoord->setAlignment(Qt::AlignLeft);

    QLabel *label2 = new QLabel(tr("GraphicsScene:"));
    label2->setAlignment(Qt::AlignRight);
    sceneCoord = new QLabel;
    sceneCoord->setAlignment(Qt::AlignLeft);

    QLabel *label3 = new QLabel(tr("map:"));
    label3->setAlignment(Qt::AlignRight);
    mapCoord       = new QLabel;
    mapCoord->setAlignment(Qt::AlignLeft);

    //坐标显示区布局
    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(label1, 0, 0);
    gridLayout->addWidget(viewCoord, 0, 1);
    gridLayout->addWidget(label2, 1, 0);
    gridLayout->addWidget(sceneCoord, 1, 1);
    gridLayout->addWidget(label3, 2, 0);
    gridLayout->addWidget(mapCoord, 2, 1);
    gridLayout->setSizeConstraint(QLayout::SetFixedSize);

    QFrame  *coorFrame = new QFrame;
    coorFrame->setLayout(gridLayout);

    //缩放控制子布局
    QVBoxLayout *zoomLayout = new QVBoxLayout;
    zoomLayout->addWidget(zoominLabel);
    zoomLayout->addWidget(slider);
    zoomLayout->addWidget(zoomoutLabel);

    //坐标显示区域布局
    QVBoxLayout *coorLayout = new QVBoxLayout;
    coorLayout->addWidget(coorFrame);
    coorLayout->addStretch();

    //主布局
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(zoomLayout);
    mainLayout->addLayout(coorLayout);
    mainLayout->addStretch();
    mainLayout->setMargin(30);
    mainLayout->setSpacing(10);

    setLayout(mainLayout);
    setWindowTitle("Map Widget");
    setMinimumSize(600, 400);
}




//读取地图信息
void MapWidget::readMap()
{
    QString mapName;

    QFile mapFile;
    mapFile.setFileName("maps.txt");                   //maps.txt是描述地图信息的文本文件
    int   ok = mapFile.open(QIODevice::ReadOnly);      //以只读方式打开文件
    if (ok)                                            //分别读取地图的名称和四个经纬度信息
    {
        QTextStream ts(&mapFile);

        if (!ts.atEnd())
        {
            ts >> mapName;
            ts >> x1 >> y1 >> x2 >> y2;
        }

        mapFile.close();
    }

    map.load(":/image/China.jpg");                                 //将地图读到map中
}


//根据缩放滑动条的当前值,确定缩放的比例
void MapWidget::slotZoom(int value)
{
    qreal s;

    if (value > zoom)                                   //放大
    {
        s = pow(1.01, (value-zoom));
    }
    else                                                //缩小
    {
        s = pow(1/1.01, (zoom-value));
    }

    scale(s, s);

    zoom = value;
}


//以地图图片重绘场景的北京来实现地图显示
void MapWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->drawPixmap(int(sceneRect().left()), int(sceneRect().top()), map);
}



//响应鼠标移动事件,完成某点在各层坐标中的映射及显示
void MapWidget::mouseMoveEvent(QMouseEvent *event)
{
    //QGraphicsView 坐标
    QPoint viewPoint = event->pos();
    viewCoord->setText(QString::number(viewPoint.x()) + "," + QString::number(viewPoint.y()));

    //QGraphicsScene坐标
    QPointF scenePoint = mapToScene(viewPoint);
    sceneCoord->setText(QString::number(scenePoint.x()) + "," + QString::number(scenePoint.y()));

    //地图坐标(经,纬度值)
    QPointF labLon = mapToMap(scenePoint);
    mapCoord->setText(QString::number(labLon.x()) + "," + QString::number(labLon.y()));
}


//完成场景坐标到地图坐标的转换
QPointF MapWidget::mapToMap(QPointF p)
{
    QPointF latLon;

    qreal w = sceneRect().width();
    qreal h = sceneRect().height();

    qreal lon = y1-((h/2+p.y())*abs(y1-y2)/h);
    qreal lat = x1+((w/2+p.x())*abs(x1-x2)/w);

    latLon.setX(lat);
    latLon.setY(lon);

    return latLon;
}

3,效果:
在这里插入图片描述