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

Stella981
• 阅读 817

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

 C++ Code 

1
2
3
4
5
6
7
8
9
10
11
12

 

// Create new QGraphicsScene and assign to graphicsView
scene =  new  QGraphicsScene( this );
ui->graphicsView->setScene(scene);

// Create widget and add to scene
MyWidget *widget =  new  MyWidget;
QGraphicsProxyWidget *proxy = scene->addWidget(widget);

// Make selectable
proxy->setFlag(QGraphicsItem::ItemIsSelectable,  true );
// Make movable
proxy->setFlag(QGraphicsItem::ItemIsMovable,  true );

于是,我尝试继承QGraphicsProxyWidget获得自己的ProxyWidget,并通过重写鼠标事件响应函数来实现,在具体的实现中我尝试过调用QGraphicsProxyWidget的鼠标事件函数,也尝试过调用QGraphicsItem的鼠标事件函数,但是仅仅能捕获鼠标按下事件(mousePressEvent),其它诸如移动和释放均无法响应。

紧接着,我去Stack Overflow上查找解决方案,倒是有一些方案,纯属tricks性的现在总结如下:

实例1:给代理widget设置一个比其大一点的父类QGraphicsWidget充当拖拽处理效果

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

 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

 

int  main( int  argc,  char  *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene scene;
    QGraphicsView  view(&scene);
    
    QGraphicsProxyWidget *proxy = scene.addWidget( new  QPushButton( "MOVE IT" ));
     // make parent widget larger that button
QGraphicsWidget* parentWidget = new  QGraphicsWidget();
    parentWidget->setMinimumSize(QSizeF(proxy->widget()->width(), proxy->widget()->height()));
    parentWidget->setFlags(QGraphicsItem::ItemIsMovable);
     //默认灰色,不设置则为背景色
//parentWidget->setAutoFillBackground(true);
scene.addItem(parentWidget); // put your wrapped button onto the parent graphics widget
proxy->setParentItem(parentWidget);

    view.setFixedSize(QSize( 600 ,  400 ));
    view.show();

     return  a.exec();
}

实例2:给代理widget设置一个比其大一点的QGraphicsRectItem充当窗口标题栏样式的拖拽处理效果

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

 C++ Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

 

int  main( int  argc,  char  *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene scene;
    QGraphicsView  view(&scene);

     auto  *item =  new  QGraphicsRectItem( 0 ,  0 ,  75 ,  40 );
     auto  *proxy =  new  QGraphicsProxyWidget(item);
     auto  *btn =  new  QPushButton(QObject::tr( "Click me" ));
    btn->setGeometry( 0 ,  0 ,  77 ,  26 );
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setBrush(Qt::darkYellow);
    proxy->setWidget(btn);
    proxy->setPos( 0 ,  15 );
    scene.addItem(item);

    view.setFixedSize(QSize( 600 ,  400 ));
    view.show();

     return  a.exec();
}

实例3:给代理widget设置一个比其大一点的QGraphicsRectItem充当边缘的拖拽处理效果

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

 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

 

int  main( int  argc,  char  *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene scene;
    QGraphicsView  view(&scene);

     auto  *dial=  new  QDial();                                             // The widget
auto  *handle =  new  QGraphicsRectItem(QRect( 0 ,  0 ,  120 ,  120 ));         // Created to move and select on scene
auto  *proxy2 =  new  QGraphicsProxyWidget(handle);                     // Adding the widget through the proxy
dial->setGeometry( 0 ,  0 ,  100 ,  100 );
    dial->move( 10 ,  10 );
    proxy2->setWidget(dial);
    handle->setPen(QPen(Qt::transparent));
    handle->setBrush(Qt::gray);
     //handle->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
scene.addItem(handle); // adding to scene
view.setFixedSize(QSize( 600 ,  400 ));
    view.show();

     return  a.exec();
}

勉勉强强可以实现拖拽的效果吧!

更直接的效果请期待后续博文深入研究!

点赞
收藏
评论区
推荐文章
隔壁老王 隔壁老王
3年前
Qt制作简单的无边框登陆窗口
使用qt做简单的登录窗口环境:win10Qt5创建项目:选择Widget类勾选ui界面因为我是用的默认类名所以类名是Widget以下是Widget.hcifndefWIDGETHdefineWIDGETHinclude<QWidgetnamespaceUiclassWidget;classWidget:publicQWidg
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Souleigh ✨ Souleigh ✨
3年前
前端性能优化 - 雅虎军规
无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?可以遵循雅虎的前端优化35条军规,这样对于优化有一个比较清晰的方向.35条军规1.尽量减少HTTP请求个数——须权衡2.使用CDN(内容分发网络)3.为文件头指定Expires或CacheControl,使内容具有缓存性。4.避免空的
Wesley13 Wesley13
3年前
QT 图形视图框架
https://blog.csdn.net/qq769651718/article/details/79357936使用QPushButton、QLabel、QCheckBox等构成GUI的控件或自定义图形时,开发应用程序会变得很简单。但是如果想在GUI中使用数十个或者数百个图形对象,向用户完美展示控制场景,则会受到很多的限制。   图形视图框
Stella981 Stella981
3年前
Qt的由来和发展
一、Qt是什么  1、Qt是一个1991年由奇趣科技开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。  2、Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(MetaObjectCompiler,moc))以及一些宏,易于扩展,允许组件编程。  3
Easter79 Easter79
3年前
Spring一些问题记录
1、在非springbean中注入bean        在项目中有时需要根据需要在自己new一个对象,或者在某些util方法或属性中获取SpringBean对象,从而完成某些工作,但是由于自己new的对象和util方法并不是受Spring所管理的,如果直接在所依赖的属性上使用@Autowired就会报无法注入的错误,或者是没报错,但是使用的时候会
Stella981 Stella981
3年前
Graphics View绘图架构(二)
GraphicsView结构的主要类包括:视图类QGraphicsView、场景类QGraphicsScene、和各种图形项类(基类都是QGraphicsItem)1\.QGraphicsView用于观察一个场景的物理窗口  场景小于视图,整个场景在视图中可见;当场景大于视图时,试图自动提供卷滚条  QGraphicsView的视口坐标等