• 481阅读
  • 3回复

让QWindow支持拖放的方法 [复制链接]

上一主题 下一主题
离线yyzq
 

只看楼主 倒序阅读 楼主  发表于: 2018-12-25
这个需求可能并不是太常见,希望给有需要的人抛砖引玉吧

其实并不是真的让QWindow支持拖放,文档里没这接口,我也尝试了native的方法,没用。。。


可能是我对windows系统API不熟吧,反正最后没搞起来,

因为项目里有个需求要使用实时视频,底层库需要个窗口WIND来给它渲染,

这个地方历经三次改版,前后一年左右。。。

现在总算有了还不错的解决方案


解决方案一:

使用QWidget,然后给其加属性

    setAttribute(Qt::WA_NativeWindow);

    setAttribute(Qt::WA_DontCreateNativeAncestors);

然后main函数里还要给QApplication加

    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);

这样就可以用起来,当然里面还有一些小细节,就不一 一赘述了。。。

总结:这种解决方案,可以有较多的控制,因为是QWidget,所以可以做很多操作和效果。

此前很长时间里都是使用这种解决方案,但是在做一机三屏的过程中,


发现整个视频调度窗口被移到另外一个屏幕后,渲染就一直只在那个位置渲染了,切回主屏的时候没画面。

而且会造成Qt5Gui库崩溃,没有任何提示,一脸懵逼。。。

最后定位到是加了Qt::WA_DontCreateNativeAncestors这个属性导致的,但是至于是为什么,没有去看源码。。。

我想升级到VS2015 + Qt5.9.7尝试是否能够解决,但是底层库还没准备好,现在还没试,所以就有了解决方案二


解决方案二:


使用QWindow,然后通过QWidget封装QWindow进行操作,这样就不需要设置各种属性了,使用起来方便许多,示例代码如下

    mSurfaceWindow = new BTSurfaceWindow();

    QWidget* windowContainer = createWindowContainer(mSurfaceWindow, this);

我们直接在以QWidget为基础的程序里嵌入windowContainer就可以了

本来以为到此完美解决问题,最后发现QWindow不支持拖放,因为我们的需求里要拖动调换窗口位置。。。。。。

最后经过两天的折腾,尝试各种解决方法,还好没有随便放弃,最后灵光乍现,既然拿到了windowContainer ,


为什么不安装事件过滤器试试,还真行,哈哈。。。

    windowContainer->setAcceptDrops(true);

    windowContainer->installEventFilter(this);

这样事情总算有个圆满解决了,其实中间还有一些小细节,就不一 一赘述了。。。

总结:这种方案解决了一机三屏问题,效果也不错,是我目前使用的方案。


但是需要注意性能问题和使用上的注意事项,在QWidget::createWindowContainer文档里已有详细描述,比如


Using many window container instances in a QWidget-based application can greatly hurt the overall performance of the application.


综上所述可以根据自己项目的实际情况选择合适的方案,也欢迎大家批评指正,提供更好的解决方案。














离线yyzq

只看该作者 1楼 发表于: 2018-12-25
排版没搞对,心累。。。
离线笑颜

只看该作者 2楼 发表于: 2018-12-25
你可能没弄明白QWindow和QWidget的关系。
首先,QWindow应该是可以处理拖拽事件的,只是这个类没有处理拖拽的事件函数而已,但是你应该可以通过重写event,在这个函数里面能拿到拖拽事件。
其次,QWidget如果是native的,应该会一一对应于一个QWidgetWindow,而QWidgetWindow是继承于QWindow的,而在QWidgetWindow的事件处理函数里面增加了拖拽事件函数而已。

所以,结论是QWindow应该是可以处理拖拽的。当然,我没试,结果的话你可以去尝试一下,另外要学好Qt,源码是必须看的。

QWindow是Qt提供的接收事件的最小单元,它对应于各个操作系统窗口的封装。



离线yyzq

只看该作者 3楼 发表于: 2018-12-29
回 笑颜 的帖子
笑颜:你可能没弄明白QWindow和QWidget的关系。
首先,QWindow应该是可以处理拖拽事件的,只是这个类没有处理拖拽的事件函数而已,但是你应该可以通过重写event,在这个函数里面能拿到拖拽事件。
其次,QWidget如果是native的,应该会一一对应于一个QWidgetWindow,而QWidgetWindow是继 .. (2018-12-25 14:21) 

快速回复
限100 字节
 
上一个 下一个