QGraphicsScene添加Widget

QGraphicsScene添加WidgetQGraphicsScene添加Widget简要说明示例介绍开发环境示例代码效果演示简要说明使用QGraphicsScene的addWidget(QWidget*widget,Qt::WindowFlagswFlangs)可以在场景中添加任意一个继承自QWidget的对象,可以是QPushButton,也可以是自定义的Widget。在使用时是为要添加的Widget创建一个新的QGraphicsProxyWidget,并将其加入到场景中,返回一个指向这个QGraphicsProxyWidget的指

大家好,欢迎来到IT知识分享网。

简要说明

使用QGraphicsScene的addWidget(QWidget *widget, Qt::WindowFlags wFlangs)可以在场景中添加任意一个继承自QWidget的对象,可以是QPushButton,也可以是自定义的Widget。
在使用时是为要添加的Widget创建一个新的QGraphicsProxyWidget,并将其加入到场景中,返回一个指向这个QGraphicsProxyWidget的指针。此时可以将QGraphicsProxyWidget看做一个QGraphicsItem,可以setPos、setFlags等。

示例介绍

为更直观的展示QGraphicsScene的addWidget功能,附上一个简单示例。此示例的功能是实现一个自定义的Widget在场景的随鼠标拖拽而移动。

开发环境

Qt5.12.4 + VS2017 (64位)

示例代码

1、自定义ActorWidget

#ifndef ACTORWIDGET_H
#define ACTORWIDGET_H

#include <QWidget>

class ActorWidget : public QWidget
{ 
   
    Q_OBJECT
public:
    explicit ActorWidget(QWidget *parent = nullptr);

signals:

public slots:
};

#endif // ACTORWIDGET_H
#include "actorwidget.h"

ActorWidget::ActorWidget(QWidget *parent) : QWidget(parent)
{ 
   
    this->setStyleSheet("QWidget{background: lightblue;}");
    this->setMouseTracking(true);
}

2、自定义GraphicsScene

#ifndef CUSTOMGRAPHICSSCENE_H
#define CUSTOMGRAPHICSSCENE_H

#include <QGraphicsScene>

class CustomGraphicsScene : public QGraphicsScene
{ 
   
public:
    CustomGraphicsScene();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

private:
    QGraphicsItem *m_pItemSelected; //鼠标选中的QGraphicsItem
    QPointF m_Offset; //鼠标移动的偏移量
    QPointF m_Pressed; //鼠标按下的位置点
    QPointF m_ItemPos; //鼠标选中的QGraphicsItem在场景中的位置
    bool m_bPressed; //鼠标是否按下
};

#endif // CUSTOMGRAPHICSSCENE_H
#include "customgraphicsscene.h"

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>

CustomGraphicsScene::CustomGraphicsScene()
    : m_bPressed(false)
{ 
   
}

void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ 
   
    QGraphicsScene::mousePressEvent(event);

    if(event->button() == Qt::LeftButton)
    { 
   
        m_pItemSelected = nullptr;
        foreach(QGraphicsItem *item, items(event->scenePos()))//循环查找当前鼠标位置点下所有的Item
        { 
   
            if(item->type() == QGraphicsProxyWidget::Type)//判断此Item是否为添加的ActorWidget创建的QGraphicsProxyWidget
            { 
   
                m_bPressed = true;
                m_Pressed = event->scenePos(); //记录此时鼠标在场景中位置点
                m_pItemSelected = item; //选中的Item

                QGraphicsProxyWidget *pProxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget*>(item);
                m_ItemPos = pProxyWidget->scenePos(); //QGraphicsProxyWidget的位置点

                break;
            }
        }
    }
}

void CustomGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{ 
   
    QGraphicsScene::mouseMoveEvent(event);

    if(m_pItemSelected != nullptr)
    { 
   
        if(m_bPressed)
        { 
   
            m_Offset = event->scenePos() - m_Pressed; //鼠标移动的偏移量
            m_pItemSelected->setPos(m_ItemPos + m_Offset); //结合鼠标按下时Item的位置点,重新设置Item的位置点
        }
    }
}

void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ 
   
    QGraphicsScene::mouseReleaseEvent(event);

    m_bPressed = false;
    if(m_pItemSelected != nullptr)
    { 
   
        m_pItemSelected = nullptr; //鼠标释放时将选中的Item设为空
    }
}

3、主窗口MainWindow

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>

#include "actorwidget.h"
#include "customgraphicsscene.h"

namespace Ui { 
   
class MainWindow;
}

class MainWindow : public QMainWindow
{ 
   
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void InitUI();

private:
    Ui::MainWindow *ui;

private:
    CustomGraphicsScene *m_pGraphicsScene;
    ActorWidget *m_pActorWidget;
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QGraphicsProxyWidget>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{ 
   
    ui->setupUi(this);

    InitUI();
}

MainWindow::~MainWindow()
{ 
   
    delete ui;
}

void MainWindow::InitUI()
{ 
   
    this->resize(540,400);

    m_pGraphicsScene = new CustomGraphicsScene; //自定义的场景
    m_pGraphicsScene->setSceneRect(0,0, ui->graphicsView->width(), ui->graphicsView->height()); //设置场景大小,占据整个QGraphicsView窗口
    ui->graphicsView->setScene(m_pGraphicsScene); //为QGraphicsView设置场景

    m_pActorWidget = new ActorWidget; //自定义的ActorWidget
    m_pActorWidget->resize(400,300);

    QGraphicsProxyWidget *pWidget = m_pGraphicsScene->addWidget(m_pActorWidget); //在场景中添加自定义的ActorWidget,返回一个QGraphicsProxyWidget指针
    pWidget->setPos((ui->graphicsView->width()-m_pActorWidget->width())/2,
                    (ui->graphicsView->height()-m_pActorWidget->height())/2);  //通过QGraphicsProxyWidget指针设置其位置,居中显示
    pWidget->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); //通过QGraphicsProxyWidget指针设置其可选、可移动、可聚焦
}

效果演示

在这里插入图片描述

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/20689.html

(0)
上一篇 2024-02-01 20:00
下一篇 2024-02-06 16:15

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信