Reputation: 21
I'm searching a way to draw any QT widget overlay on QVulkanWindow. I cannot find solution. Child/parent hierarchy and QT flags don't bring expected behaviour. Is it possible to draw QT widgets on the top of QVulkanWindow?
I've tried the following
1) attempt to create QWidget and Vulkan window from one parent QWidget
auto widget = new QWidget;
widget->resize(m_default_width, m_default_height);
widget->show();
m_label = new QLabel("text.", widget);
m_label->show();
m_vulkan_window = std::make_shared<WSQVulkanWindow>(this);
m_vulkan_window->setVulkanInstance(&m_qt_vk_instance);
m_vulkan_window->show();
auto wrapper = QWidget::createWindowContainer(m_vulkan_window.get(), widget);
wrapper->resize(m_default_width, m_default_height);
wrapper->show();
2) Added the following flags
m_label->setAttribute(Qt::WA_NoSystemBackground);
m_label->setAttribute(Qt::WA_TranslucentBackground);
m_label->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::CoverWindow);
Label is shown on top of vulkan window but it doesn't follow vulkan window position
3) Attempt to add QWidget::createWindowContainer of VulkanWindow and QLabel widget to one parent widget with QGridLayout or QVBoxLayout.
It has no effect
4) Create QVulkanWindow with parent newwidget->windowHandle() with following creation QLabel widget on newwidget parent
5) Create new QWindow with parent QVulkanWindow. After that create widget from QWindow and create child QLabel for mentioned widget.
winapi creates button on top of vulkan window. But it is impossible to create semi-transparent widgets
m_hwndButton = CreateWindowExW(
0L,
L"BUTTON", // Predefined class; Unicode assumed
L"VR", // Button text
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Styles
10, // x position
10, // y position
50, // Button width
50, // Button height
(HWND)m_vulkan_window->winId(), // Parent window
NULL, // No menu.
(HINSTANCE)GetWindowLong((HWND)m_vulkan_window->winId(), -6), //instance
NULL); // Pointer not needed.
ShowWindow(m_hwndButton, SW_SHOW);
UpdateWindow(m_hwndButton);
Upvotes: 0
Views: 1699
Reputation: 29240
Child/parent hierarchy and QT flags don't bring expected behaviour.
Once a surface is being managed by the GPU/Vulkan, you can't really expect to be able to draw native controls in it with something else.
Qt Widgets aren't really suited to rendering on a Vulkan surface. Widgets are typically native controls, so to display them on a Vulkan surface, you'd have to capture the widgets to an image, transfer that image to the GPU and then render the image.
If what you want to do is get UI inside Vulkan rendering, your best bets are either Imgui or QML. QML can be rendered to an OpenGL surface using QQuickRenderControl
, and that GL surface can be shared with a Vulkan image using VK_KHR_external_memory
. Imgui on the other hand is designed to be able to be rendered directly in a variety of GPU APIs, of which Vulkan is one. In both cases you will be responsible for capturing Qt events and passing them to the Imgui or QML layer.
Upvotes: 0