希望实现的结果: 一个可以拖动,可以缩放的窗口,标题栏自定义,而不是用windows 自带标题栏(大家都觉得系统的标题栏很丑,但我自己觉得也还好),大华的摄像头SDK启动摄像头播放时,通过 回调函数获取视频数据,通过大华的 playsdk 丢入该窗口进行播放。
简单记录,待详细补充
方案1:
在隐藏系统标题栏之前,窗口是可以拖放和改变大小的;
通过 setWindowFlags( Qt::CustomizeWindowHint); 隐藏系统标题栏,隐藏后窗口保留了拖放和改变大小的功能。看起来很完美,但是仔细看发现在窗口顶部留下了一条白边儿,该白边儿不知道如何修改样式,不知道如何隐藏。
因此放弃了该方案。
方案2:
继承 QDIalog 或 QWidget 自定义了一个窗口类,
在该窗口类构造函数中 执行 setWindowFlags(Qt::FramelessWindowHint) 隐藏了系统标题栏,隐藏后鼠标拖放和改变大小的功能失效了,因此需要重定义鼠标事件,自己实现。
鼠标拖放功能比较容易实现,改变大小的功能希望实现的效果为 当鼠标经过窗口边缘时,鼠标改变形状,此时按下鼠标左键,然后移动鼠标即可调整窗口大小。
在默认情况下,窗口只有在鼠标按下时才能捕捉鼠标事件,如果要在鼠标不按下时也能触发,则需要 调用
setMouseTracking(true);
调用该接口后,可以模拟原效果失效鼠标拖放窗口和改变窗口大小的功能。
当为主窗口添加子控件覆盖住窗口后,主窗口无法触发鼠标事件,此时为子窗口执行 setAttribute(Qt::WA_TransparentForMouseEvents); 主窗口又可以穿透子窗口获取鼠标事件了。
于是接下来考虑调用 大华的 PLAYSDK,在该窗口中播放视频数据。大华的 PlaySdk 需要一个窗口句柄,Qt 中科通过 winId() 函数获取,于是我通过该函数获取自定义窗口类中的子窗口的 句柄;
这时又出现了一个让人头疼的问题,为自定义窗口中的任何一个子控件调用 winId 后发现,外层窗口通过setMouseTracking(true);实现的在不按下鼠标左键时,捕捉鼠标移动事件的功能失效了,无论怎么调试都不行。
查阅资料发现一个 接口 grabMouse(); 该函数结合 setMouseTracking(true); ,可恢复因调用 winId() 失效的功能。
示例代码实现方法为
void ClassicDialog::enterEvent(QEvent *event)
{
grabMouse();
}
void ClassicDialog::leaveEvent(QEvent *event)
{
releaseMouse();
}