QT 实现QGraphicsProxyWidget对象可选择或移动(item管理实现)

上篇博文《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(

0
.
0

0
.
0
));
                

// 图元左上角在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;
    }
}

相关文章