Qt 图形视图框架 #

框架概述 #

text
┌─────────────────────────────────────────────────────────────┐
│                    图形视图架构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────────────────────────────────────────────┐  │
│   │                  QGraphicsView                       │  │
│   │                    (视图)                            │  │
│   │  - 显示和交互                                        │  │
│   │  - 处理用户输入                                      │  │
│   │  - 视口和变换                                        │  │
│   └────────────────────────┬────────────────────────────┘  │
│                            │                               │
│                            ▼                               │
│   ┌─────────────────────────────────────────────────────┐  │
│   │                 QGraphicsScene                       │  │
│   │                    (场景)                            │  │
│   │  - 管理图元                                          │  │
│   │  - 处理碰撞检测                                      │  │
│   │  - 图元选择和焦点                                    │  │
│   └────────────────────────┬────────────────────────────┘  │
│                            │                               │
│                            ▼                               │
│   ┌─────────────────────────────────────────────────────┐  │
│   │                 QGraphicsItem                        │  │
│   │                    (图元)                            │  │
│   │  - 矩形、椭圆、多边形、文本等                        │  │
│   │  - 自定义图元                                        │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本使用 #

创建场景和视图 #

cpp
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>

// 创建场景
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setSceneRect(0, 0, 800, 600);

// 创建视图
QGraphicsView *view = new QGraphicsView(scene, this);
view->setRenderHint(QPainter::Antialiasing);
view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
view->setDragMode(QGraphicsView::RubberBandDrag);

// 添加图元
QGraphicsRectItem *rect = scene->addRect(10, 10, 100, 50, 
    QPen(Qt::blue), QBrush(Qt::green));

QGraphicsEllipseItem *ellipse = scene->addEllipse(150, 10, 80, 80,
    QPen(Qt::red), QBrush(Qt::yellow));

QGraphicsTextItem *text = scene->addText("Hello Qt");
text->setPos(250, 10);

QGraphicsLineItem *line = scene->addLine(10, 100, 200, 100, 
    QPen(Qt::black, 2));

QGraphicsPixmapItem *pixmap = scene->addPixmap(QPixmap(":/image.png"));
pixmap->setPos(300, 100);

QGraphicsScene 场景 #

场景管理 #

cpp
QGraphicsScene *scene = new QGraphicsScene(this);

// 设置场景大小
scene->setSceneRect(0, 0, 800, 600);

// 添加图元
QGraphicsItem *item = scene->addRect(0, 0, 100, 100);

// 移除图元
scene->removeItem(item);

// 清空场景
scene->clear();

// 获取所有图元
QList<QGraphicsItem*> items = scene->items();

// 获取指定位置的图元
QList<QGraphicsItem*> itemsAtPoint = scene->items(QPointF(50, 50));

// 获取场景边界
QRectF sceneRect = scene->sceneRect();

// 设置背景
scene->setBackgroundBrush(Qt::lightGray);
scene->setBackgroundBrush(QPixmap(":/background.png"));

// 设置前景
scene->setForegroundBrush(QColor(0, 0, 0, 50));

图元查找 #

cpp
// 按位置查找
QList<QGraphicsItem*> items = scene->items(QPointF(100, 100));

// 按矩形区域查找
QList<QGraphicsItem*> items = scene->items(QRectF(0, 0, 200, 200));

// 按类型查找
QList<QGraphicsItem*> rects = scene->items(scene->sceneRect(), 
    Qt::IntersectsItemShape, Qt::DescendingOrder, 
    QTransform(), QGraphicsRectItem::Type);

// 按名称查找(需要设置 data)
QGraphicsItem *item = scene->itemAt(100, 100, QTransform());

QGraphicsView 视图 #

视图设置 #

cpp
QGraphicsView *view = new QGraphicsView(scene, this);

// 渲染提示
view->setRenderHint(QPainter::Antialiasing);
view->setRenderHint(QPainter::SmoothPixmapTransform);

// 视口更新模式
view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
view->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
view->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);

// 拖拽模式
view->setDragMode(QGraphicsView::NoDrag);
view->setDragMode(QGraphicsView::ScrollHandDrag);     // 手型拖拽
view->setDragMode(QGraphicsView::RubberBandDrag);     // 框选

// 缓存模式
view->setCacheMode(QGraphicsView::CacheBackground);

// 对齐方式
view->setAlignment(Qt::AlignCenter);

// 视口边距
view->setViewportMargins(10, 10, 10, 10);

缩放和平移 #

cpp
// 缩放
view->scale(1.5, 1.5);   // 放大 1.5 倍
view->scale(0.5, 0.5);   // 缩小一半
view->resetTransform();  // 重置变换

// 设置缩放比例
view->setTransform(QTransform().scale(2, 2));

// 平移
view->translate(100, 100);

// 旋转
view->rotate(45);

// 居中显示
view->centerOn(item);
view->centerOn(QPointF(100, 100));

// 适应场景
view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);

// 坐标转换
QPointF scenePos = view->mapToScene(viewPos);
QPoint viewPos = view->mapFromScene(scenePos);

滚动条 #

cpp
// 设置滚动条策略
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

// 隐藏滚动条
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

// 滚动到指定位置
view->horizontalScrollBar()->setValue(100);
view->verticalScrollBar()->setValue(100);

QGraphicsItem 图元 #

基本图元类型 #

cpp
// 矩形
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 50);

// 椭圆
QGraphicsEllipseItem *ellipse = new QGraphicsEllipseItem(0, 0, 80, 60);

// 圆形
QGraphicsEllipseItem *circle = new QGraphicsEllipseItem(0, 0, 50, 50);

// 多边形
QPolygonF polygon;
polygon << QPointF(0, 0) << QPointF(100, 0) << QPointF(50, 100);
QGraphicsPolygonItem *polyItem = new QGraphicsPolygonItem(polygon);

// 线条
QGraphicsLineItem *line = new QGraphicsLineItem(0, 0, 100, 100);

// 文本
QGraphicsTextItem *text = new QGraphicsTextItem("Hello");
text->setFont(QFont("Arial", 16));

// 图片
QGraphicsPixmapItem *pixmap = new QGraphicsPixmapItem(QPixmap(":/image.png"));

// 路径
QPainterPath path;
path.moveTo(0, 0);
path.lineTo(100, 0);
path.lineTo(50, 100);
path.closeSubpath();
QGraphicsPathItem *pathItem = new QGraphicsPathItem(path);

// 添加到场景
scene->addItem(rect);

图元属性 #

cpp
QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 50);

// 位置
item->setPos(100, 100);
QPointF pos = item->pos();

// 大小(通过 setRect)
item->setRect(0, 0, 200, 100);

// 旋转
item->setRotation(45);
item->setTransformOriginPoint(50, 25);  // 旋转中心

// 缩放
item->setScale(1.5);

// Z 值(层叠顺序)
item->setZValue(10);

// 可见性
item->setVisible(true);
item->hide();
item->show();

// 启用
item->setEnabled(true);

// 可选中
item->setFlag(QGraphicsItem::ItemIsSelectable, true);

// 可移动
item->setFlag(QGraphicsItem::ItemIsMovable, true);

// 可获得焦点
item->setFlag(QGraphicsItem::ItemIsFocusable, true);

// 悬停事件
item->setAcceptHoverEvents(true);

// 画笔和画刷
item->setPen(QPen(Qt::blue, 2));
item->setBrush(QBrush(Qt::green));

// 工具提示
item->setToolTip("This is a rectangle");

// 用户数据
item->setData(0, QVariant::fromValue(myData));
QVariant data = item->data(0);

自定义图元 #

cpp
class CustomItem : public QGraphicsItem
{
public:
    CustomItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent)
    {
        setFlag(ItemIsMovable);
        setFlag(ItemIsSelectable);
    }
    
    QRectF boundingRect() const override
    {
        return QRectF(0, 0, 100, 100);
    }
    
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *,
               QWidget *) override
    {
        painter->setPen(QPen(Qt::blue, 2));
        painter->setBrush(QBrush(Qt::cyan));
        painter->drawRect(boundingRect());
        
        if (isSelected()) {
            painter->setPen(QPen(Qt::red, 2, Qt::DashLine));
            painter->setBrush(Qt::NoBrush);
            painter->drawRect(boundingRect().adjusted(-2, -2, 2, 2));
        }
    }
    
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override
    {
        qDebug() << "Item clicked";
        QGraphicsItem::mousePressEvent(event);
    }
    
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override
    {
        setCursor(Qt::PointingHandCursor);
        QGraphicsItem::hoverEnterEvent(event);
    }
    
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override
    {
        unsetCursor();
        QGraphicsItem::hoverLeaveEvent(event);
    }
};

图元分组 #

cpp
// 创建分组
QGraphicsItemGroup *group = new QGraphicsItemGroup;

// 添加图元到分组
group->addToGroup(rect);
group->addToGroup(ellipse);

// 从分组移除
group->removeFromGroup(rect);

// 添加分组到场景
scene->addItem(group);

// 分组可以作为一个整体移动、选择
group->setFlag(QGraphicsItem::ItemIsMovable);
group->setFlag(QGraphicsItem::ItemIsSelectable);

选择和交互 #

cpp
// 设置选择模式
scene->setSelectionArea(QPainterPath());  // 清除选择

// 获取选中的图元
QList<QGraphicsItem*> selected = scene->selectedItems();

// 设置选中
item->setSelected(true);

// 清除选择
scene->clearSelection();

// 选择所有图元
for (QGraphicsItem *item : scene->items()) {
    item->setSelected(true);
}

// 连接选择信号
connect(scene, &QGraphicsScene::selectionChanged, []() {
    qDebug() << "Selection changed";
});

下一步 #

现在你已经掌握了图形视图框架,接下来学习 网络编程,了解 Qt 的网络通信能力!

最后更新:2026-03-29