示例概述
- 本示例用到model\view模型:model类是用QSqlRelationalTableModel,view相当于由三个小部件组成,分别是label、comboBox、texEdit,把数据模型中的数据通过QDataWidgetMapper类绑定到上面三个小部件上。
- 本示例还用到图形视图类QGraphicsView,图形场景场QGraphicsScene、图形项目类QGraphicsItem之间的关系及用法,场景类QGraphicsScene对象必须设置到QGraphicsView对象里面,而往QGraphicsScene对象里面添加QGraphicsPixmapItem对象或者以下类对象
QGraphicsItem包括它的派生类:
-
QAbstractGraphicsShapeItem
QGraphicsEllipseItem,
QGraphicsPathItem,
QGraphicsPolygonItem
QGraphicsRectItem
QGraphicsSimpleTextItem -
QGraphicsItemGroup
-
QGraphicsLineItem
-
QGraphicsObject
QGraphicsSvgItem,
QGraphicsTextItem,
QGraphicsWidget -
QGraphicsPixmapItem
示例
-
项目运行的截图,鼠标悬停上面,项目会放大
-
点击一个项目后,显示信息窗体
开始项目
- 打开Qt Creator,选择一个模板:其它项目,中间选择:Empty qmake Project,建立一个空的qmake项目,点击【Choose…】之后,名称:GraphicView,选择项目地址
点击【下一步】,【下一步】直到完成。
建立三个类
一个继承自QGraphicsView的视图类,一个继承自QGraphicsItem的图形项目类,一个是继承自QDialog的窗体类
一、建立imageitem图形项目类
-
首先,建立imageitem图形项目类,继承自QObject和QGraphicsPixmapItem,根据数据库的记录增加相应的图形项目,从QObject继承,主要是继承它的connect()函数,右击GraphicView,选择Add New,文件和类选择“C++”,中间选择“C++ Class”,选择【Choose…】,Class name:ImageItem,Base class:QObject, public QGraphicsPixmapItem,点击【下一步】,直到【完成】。
-
imageitem.h头文件中增加
#include <QGraphicsPixmapItem>
- 最终 imageitem.h头文件如下
#ifndef IMAGEITEM_H
#define IMAGEITEM_H
#include <QGraphicsPixmapItem>
// QTimeLine需要导入<QtCore>
#include <QtCore>
class ImageItem :public QObject, public QGraphicsPixmapItem
{
public:
ImageItem();
//类的枚举类型
enum {
Type = UserType + 1 };
//类的构造函数,参数接受items数据表的id及QPixmap对象,作为图形项目对象的id号及要显示的图像
ImageItem(int id, const QPixmap &pixmap, QGraphicsItem *parent = nullptr);
// 返回对象的类型
int type() const override {
return Type; }
//把图形项目缩放到120*120px
void adjust();
// 返回图形项目的id值,等于数据库记录id
int id() const;
protected:
//当鼠标进入悬停到图形项目上的事件函数重载
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
//当鼠标离开图形项目后的事件函数重载
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
private slots:
// 槽函数:时间轴变化期间运行的函数
void setFrame(int frame);
// 槽函数:更新x 、y 、z坐标系的z轴的值
void updateItemPosition();
private:
//时间轴对象
QTimeLine timeLine;
// 保存数据库记录的id值
int recordId;
// x 、y 、z坐标系的z轴的值
double z;
};
#endif // IMAGEITEM_H
- imageitem.cpp文件如下
#include "imageitem.h"
ImageItem::ImageItem()
{
}
ImageItem::ImageItem(int id, const QPixmap &pixmap, QGraphicsItem *parent)
: QGraphicsPixmapItem(pixmap, parent)
{
//保存数据模型ID号
recordId = id;
//接受鼠标悬念事件,默认不接受
setAcceptHoverEvents(true);
//设置时间线持续时间150ms(毫秒)
timeLine.setDuration(150);
//设置帖的范围0至150帖
timeLine.setFrameRange(0, 150);
//当时间线的帖变化时调用一次setFrame()函数一次
connect(&timeLine, &QTimeLine::frameChanged, this, &ImageItem::setFrame);
//当时间线结束后,调用updateItemPosition设置z轴的值
connect(&timeLine, &QTimeLine::finished, this, &ImageItem::updateItemPosition);
// 不管图像宽高是多少,都缩放成120*120px的图片
adjust();
}
void ImageItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
{
//设置时间轴“朝前”
timeLine.setDirection(QTimeLine::Forward);
if (this->z != 1.0) {
this->z = 1.0;
//修改ZValue
updateItemPosition();
}
//启动时间轴
if (timeLine.state() == QTimeLine::NotRunning)
timeLine.start();
}
// 当鼠标离开项目上方的时候调用本函数
void ImageItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
{
//设置时间轴“退后”
timeLine.setDirection(QTimeLine::Backward);
if (this->z != 0.0)
this->z = 0.0;
if (timeLine.state() == QTimeLine::NotRunning)
timeLine.start();
}
// 槽函数,在时间轴播放期间被调用,150ms被调用四次,逐渐放大图片
void ImageItem::setFrame(int frame)
{
adjust();
//保存imageitem项的中心坐标
QPointF center = boundingRect().center();
//把坐标转换到当前项的中心
setTransform(QTransform::fromTranslate(center.x(), center.y()), true);
//根据帧的值缩放当前项
setTransform(QTransform::fromScale(1 + frame / 330.0, 1 + frame / 330.0), true);
//把坐标再转换回当前项的左上角
setTransform(QTransform::fromTranslate(-center.x(), -center.y()), true);
}
// 不管图像宽高是多少,都缩放成120*120px的图片
void ImageItem::adjust()
{
setTransform(QTransform::fromScale(120 / boundingRect().width(),
120 / boundingRect().height()));
}
int ImageItem::id() const
{
return recordId;
}
// 当时间轴播放完成后(放大或者缩小),调用此函数,设置z的值
vo