上篇博文《QT QGraphicsProxyWidget对象可选择或移动的一些tricks》介绍了实现QT QGraphicsProxyWidget对象可选择或移动的一些小的第三方技巧,但是在实际的项目中一般不那么做。

之前自己学习QGraphicsView研究的还不是很深入,在scene中加入大量的item后,scene框架提供了注入items()、itemAt()等遍历管理其中item的一些操作。

思路:通过对scene中进行鼠标点选获取选择的item(本文主要说的是QGraphicsProxyWidget对象),然后跟随鼠标拖动事件设置其在scene中的位置,终于开阔了思路!

先看一下效果图:

一个QGraphicsProxyWidget嵌入了一个QPushButton;另一个QGraphicsProxyWidget嵌入了一个QCombobox

相关代码如下:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
class GraphicsScene : public QGraphicsScene
{
    Q_OBJECT
public:
    GraphicsScene();

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

private:
    QGraphicsItem   *m_pItemSelected;                   // 鼠标单选item
    QPoint          m_shiftOrg;                         // 鼠标点选item中位置相对于item原点的偏移量

};

// 鼠标按下获取当前单选中的QGraphicsProxyWidget图元对象
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "scene mouse press";
    QGraphicsScene::mousePressEvent(event);

if (event->button() == Qt::LeftButton)
    {
        // 检测光标下是否有 item
        m_pItemSelected = nullptr;
        foreach (QGraphicsItem *item, items(event->scenePos()))
        {
            if (item->type() == QGraphicsProxyWidget::Type)   // 代理Widget
            {
                QGraphicsProxyWidget *proxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget *>(item);
                QPointF point = proxyWidget->mapToScene(QPointF());
                // 图元左上角在scene中的位置
                qDebug() << point.x();
                qDebug() << point.y();
                // 当前点击图元点在scene中的位置
                qDebug() << event->scenePos().x();
                qDebug() << event->scenePos().y();
                m_shiftOrg.setX(event->scenePos().x() - point.x());
                m_shiftOrg.setY(event->scenePos().y() - point.y());
                m_pItemSelected = item;
                break;
            }
        }
    }

}
// 鼠标移动过程中跟随位置改变
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "scene mouse move";
    QGraphicsScene::mouseMoveEvent(event);
    if(m_pItemSelected != nullptr)
    {
        m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y());
    }
}
// 鼠标释放后作为最后的位置
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "scene mouse release";
    QGraphicsScene::mouseReleaseEvent(event);

if(m_pItemSelected != nullptr)
    {
        m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y());
        m_pItemSelected = nullptr;
    }
}

QT 实现QGraphicsProxyWidget对象可选择或移动(item管理实现)的更多相关文章

  1. QT QGraphicsProxyWidget对象可选择或移动的一些tricks

    我在QT图形视图框架中使用QGraphicsProxyWidget嵌入widget,但是无法使其和其它的QGraphicsItem一样可以选择或移动,使用如下语句无效:  C++ Code  1234 ...

  2. 哪一个不是EL定义的隐式对象?(选择1项)

    哪一个不是EL定义的隐式对象?(选择1项) A cookie B.pageContext C.attributes D initParam 解答:C 1)pageContext:JSP 页的上下文.它 ...

  3. Qt笔记——元对象系统

    Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...

  4. Qt 打开安卓相冊选择图片并获取图片的本地路径

    Qt 打开安卓相冊选择图片并获取图片的本地路径 过程例如以下: 通过 Intent 打开安卓的系统相冊. 推荐使用 QAndroidJniObject::getStaticObjectField 获取 ...

  5. 【Qt】仿QQ表情选择控件

         表情选择控件在聊天应用中常常要用到,做起来尽管不复杂可是非常繁琐.特别是有些图标须要按顺序排列.每次重做必定是非常费时.所以我将聊天表情选择控件封装成一个独立的类QFaceSelectWid ...

  6. Java代码质量改进之:同步对象的选择

    在Java中,让线程同步的一种方式是使用synchronized关键字,它可以被用来修饰一段代码块,如下: synchronized(被锁的同步对象) { // 代码块:业务代码 } 当synchro ...

  7. qt 中的对象树

    本节内容讲解了什么是对象树以及其所带来的 GUI 编程好处.最后说明了在对象树中析构顺序问题并举了个特殊的例子,来说明平时编程中需要注意的一个点. 什么是对象树? 我们常常听到 QObject 会用对 ...

  8. QT工程文件的条件编译选择与额外的编译参数配置

    QTCreator打开.pro工程文件后,依据不同的构建套件创建项目组.在项目组中,点开构建步骤的“详情”,增加一个自己的宏定义,比如: DEFINES+=IMX_287 然后,我们在.pro文件中添 ...

  9. qt study 元对象,属性和反射编程

    所谓反射,就是指对象成员的自我检查,使用反射编程(reflective programming),就可以编写出通用的操作,可以对具有不同结构的类进行操作. QMetaObject 元对象模式,描述一个 ...

随机推荐

  1. eclipse多个项目保存到gitee上一个仓库中

    自己练习创建到多个项目,想同步到gitee上一个仓库中. 1. 首先在gitee上创建项目springtest 2. 在eclipse默认项目存放到地方创建文件夹springtest,用来同步gite ...

  2. [算法]最小的K个数和数据流中的中位数

    1. 最小的K个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 思路 Java 中的PriorityQueue是 ...

  3. RavenDb学习(七) 异步工作以及维度查询

    .异步执行 var entity = new Company {Name = "Async Company #2", Id = "companies/2"}; ...

  4. 测试word发表博客

    哈哈哈 我测试一下 <ul class="clearfix"> <li> <div><img src="{IMG_PATH}qr ...

  5. webpack5--css 打包

    1.在 src 文件夹下面新建 css 文件夹,创建 common.css body{ background-color: #f2f2f2; } a{ color: #188eee; text-dec ...

  6. android开发 系统时间与定时器之间有关系嘛?

    如题: android开发 系统时间与定时器之间有关系嘛? 答案:有. 看定时器源码: /* * Schedule a task. */ private void scheduleImpl(Timer ...

  7. ASP.NET中使用JavaScript实现图片自动水平滚动效果

    参照网上的资料,在ASP.NET中使用JavaScript实现图片自动水平滚动效果. 1.页面前台代码: <%@ Page Language="C#" AutoEventWi ...

  8. 《Qt数据类型》--QByteArray,QString,int,hex之间的转化

    对于QString和QByteArray,他们都有一个toInt的静态函数,QString::toInt()是根据string的字面值转化为int类型,比如string:"123" ...

  9. 远程操作与端口转发 SSH原理与运用

    SSH不仅可以用于远程主机登录,还可以直接在远程主机上执行操作. 上一节的操作,就是一个例子: $ ssh user@host 'mkdir -p .ssh && cat >&g ...

  10. Airtest 网易 UI 自动化工具 Airtest 浅用记录

    一 使用目的 该工具主要是面向游戏UI测试基于图像识别,如游戏框架unity,Cocos-js以及网易内部的游戏框架同时也支持原生Android App 的基于元素识别的UI自动化测试.本文主要使用目 ...