一叶知秋 发表于 2018-12-25 10:57:37

让QWindow支持拖放的方法

本帖最后由 一叶知秋 于 2018-12-25 11:10 编辑

这个需求可能并不是太常见,希望给有需要的人抛砖引玉吧

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

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

因为项目里有个需求要使用实时视频,底层库需要个窗口WIND来给它渲染,这个地方历经三次改版,前后一年左右。。。

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


解决方案一:

使用QWidget,然后给其加属性

    setAttribute(Qt::WA_NativeWindow);

    setAttribute(Qt::WA_DontCreateNativeAncestors);

然后main函数里还要给QApplication加

    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);

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

总结:这种解决方案,可以有较多的控制,因为是QWidget,所以可以做很多操作和效果。此前很长时间里都是使用这种解决方案,

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

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

最后定位到是加了 setAttribute(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.

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


一叶知秋 发表于 2018-12-29 11:46:25

重新实现QWindow的event函数自己处理也是可以的。。。

chifandeyu 发表于 2019-1-9 18:26:10



头文件加几句代码搞定
protected:
        void mousePressEvent(QMouseEvent *event) {
                windowPos = this->pos();
                mousePos = event->globalPos();
                dPos = mousePos - windowPos;
        }
        void mouseMoveEvent(QMouseEvent *event) {
                this->move(event->globalPos() - this->dPos);
        }
        QPoint windowPos;
        QPoint mousePos;
        QPoint dPos;

一叶知秋 发表于 2019-1-10 09:18:00

chifandeyu 发表于 2019-1-9 18:26
头文件加几句代码搞定
protected:
        void mousePressEvent(QMouseEvent *event) {


是拖放不是拖动,drag & drop;P

chifandeyu 发表于 2019-1-10 16:05:18

本帖最后由 chifandeyu 于 2019-1-10 16:10 编辑

一叶知秋 发表于 2019-1-10 09:18
是拖放不是拖动,drag & drop
好吧 大佬 佩服你了 你这方法多多, 说到拖放窗口,我之前用的是重写notify函数实现啵
页: [1]
查看完整版本: 让QWindow支持拖放的方法