上篇博文《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. java获取classpath以外的路径

    最近在使用以前写过的代码生成器(从表名可生成所有的代码)的时候,发现生成的文件都在classpath目录下,所有的文件都得自己拷到工程目录下,于是,想优化一下,取得classpath目录以外的路径,很 ...

  2. AT91SAM9260EK-38k产生原理

    9260内部有5个内部计数器,分别为TIMER_CLOCK1 --- TIMER_CLOCK5.通过这5个时钟可以为各种内部设备提供时钟基准. 其中,红外发射38K方波,是通过CLOCK1计数产生. ...

  3. MacBook如何用Parallels Desktop安装windows7/8

    虽然MacBook真的很好用,不过在天朝的国情下,有很多软件还是仅支持IE和windows系统下才有.所以有必要为自己的MacBook装一个windows版本的系统,之前试过用Boot Camp来建立 ...

  4. oozie 安装过程详解

    1.从apache的官网下载oozie3.3.2 2.编译oozie,以下命令用root来执行吧,它不做任何的测试的,因为一测试就会出错的 官网估计也知道,所以顺便也提供了一个跳过参数的命令... b ...

  5. jquery 中 $ 符的意义

    $()就是一个函数名,别把它想得这么神奇.$就是一个字符,比如function a(){};function $(){};是一样的.只是jquery中习惯用$函数来作为对象化的入口而已.你也可以把jq ...

  6. 微信小程序——星星评分

    先来个效果图镇楼: 实现原理: 1.循环需要评分的列表,判断它的分数 与 当前星星索引的大小: 2.点击,获取星星对应的分数,让星星高亮. 代码: star.wxml: <view class= ...

  7. jquery跨域访问解决方案

    客户端“跨域访问”一直是一个头疼的问题,好在有jQuery帮忙,从jQuery-1.2以后跨域问题便迎刃而解.由于自己在项目中遇到跨域问题,借此机会对跨域问题来刨根问底,查阅了相关资料和自己的实践,算 ...

  8. 工行金邦达USBKey 在Mac OS的 Parallels Desktop 的虚拟Win7出现“ PKCS11

    由于经常用到支付宝的工行付款,所以在我的mac os中安装了Parallels Desktop 7(Win7旗舰版),但随之而来的问题是,运行PD后,再插入工行的USBkey,运行工具箱后出现“PKC ...

  9. java不确定参数个数方法例子

    package test; public class myTest { // 根据输入的参数动态生成数组 public static int max(int... param) { int max = ...

  10. ADT安装

    Eclipse安装ADT很简单,直接把下载好的ADT文件解压,覆盖到eclipse目录下的features和plugins目录即可, MyEclipse配置就稍微麻烦了点,我刚开始配置了好几次都不成功 ...