关于C#:如何在外部库处理的设备的数据流上方显示QWidget

How to display QWidget above data stream from device handled by external library

我正在创建应用程序来分析来自设备的数据并将其显示在屏幕上。处理此设备的 SDK 具有通过设置窗口处理程序 (HWND) 在特定窗口中显示当前数据帧的功能。

在我的 Qt Gui 应用程序中,我尝试通过视频流显示我自己的小部件,该小部件显示在我的 QGLWidget 中(它由 winId 函数和 HWND 设置)。 MainWidget 是 QGLWidget 的父级,其中显示数据流,并且 QWidget(或某些图形标记,例如 Circle)应显示在来自 QGLWidget 的数据流上方。

一切都几乎完美,但我得到了闪烁效果(闪烁效果?) - 我的圆圈小部件正在隐藏并以人眼可以看到的频率显示,我尽量避免它。消除这个问题的唯一选择是将这个圆圈创建为小部件并为其设置 Qt::Popup 标志,因为它有很大的缺点 - 我无法访问界面的其余部分(我知道,这是 Popup 标志错误)。我尝试过其他选项,例如:

  • 设置 Qt::WindowStaysOnTopHint 和其他几个标志,
  • 创建父级为 QGLWidget 的布局对象,我在其中显示来自设备的数据,然后将圆形小部件设置为布局项,但此处黑色背景是阴影显示的数据(我什至关闭了背景,但我已经意识到Qt 无法知道我的小部件下有什么,因为它是由外部库处理的)。

在文档中,我发现我可以创建自己的 Directshow COM 对象(或接口,我对吗?)来处理视频流的信息,但我并不真正了解这些技术,我非常想避免使用此选项!

[编辑] 我发现我可以将当??前帧的数据作为 IPictureDisp 接口,但正如我之前所说,我并不真正了解 COM 技术。我试图找到一些关于如何使用 IPictureDisp 的东西,但我没有关于 COM 技术的基本知识。有人有什么好的教程吗?


试试这个小部件层次结构:

1
2
3
MainWindget
|-QGLWidget
|-MarkerWidet

MarkerWidet 应该是一个小的方形小部件。

通过调用 MarkerWidet::raise() 确保 MarkerWidet 高于 QGLWidget
但是在调用 MarkerWidet::raise() 之前先调用 MarkerWidet::lower()。 Qt有一个QWidget::raise()错误,这个错误通过调用lower(); raise();.

消除

在启动您的应用程序后检查实际的小部件层次结构,使用 Spy 来完成。 Spy 可以在 Visual Studio 安装中找到,或者在这里下载。

伪代码:

1
2
3
4
5
6
7
8
9
10
MainWindget* mainWidget = new MainWindget;
QGLWidget* glWidget = new QGLWidget(mainWidget);
device->setHwnd(glWidget->winId());
mainWidget->show();
...
MarkerWidet* marker = new MarkerWidet(mainWidget);
marker->resize(30, 30);
marker->move(10, 10);
marker->lower();
marker->raise();