Qt 之QGraphicsView类、QGraphicsScene类、QGraphicsItem类、QDataWidgetMapper类的用法示例

本文提供了一个使用Qt的QGraphicsView、QGraphicsScene、QGraphicsItem和QDataWidgetMapper的示例。通过QSqlRelationalTableModel创建数据模型,并将数据绑定到label、comboBox和textEdit上。详细介绍了如何建立图像项目类、信息窗体类和视图类,以及如何处理鼠标事件和图形更新。项目包含图像放大、信息显示和数据交互功能。
摘要由CSDN通过智能技术生成

示例概述

  • 本示例用到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
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值