Layout issue with QWidget converted form win32 window
-
I have to create a win32 window to render video stream, so I try to convert this win32 window to a QWidget control, Also I want to show some buttons on this win32 window. but the win32 window is always on the top no matter how I configure the layout.
HINSTANCE hInstance = GetModuleHandle(NULL); WNDCLASSEXW wcex = { sizeof(WNDCLASSEX) }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszClassName = L"RenderWindow"; static ATOM wnd_class_ = RegisterClassExW(&wcex); HWND hwnd = ::CreateWindowExW(WS_CHILDWINDOW, L"RenderWindow", L"Engineer", WS_CHILDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); QWindow *native_wnd = QWindow::fromWinId((WId)hwnd); QWidget *a = QWidget::createWindowContainer(native_wnd); a->setParent(this); a->setGeometry(QRect(0, 0, 800, 400)); QPushButton* btn = new QPushButton(this); btn->setGeometry(QRect(780, 380, 100, 50)); btn->raise();
-
@gaojinhsu said in Layout issue with QWidget converted form win32 window:
QWidget::createWindowContainer
https://doc.qt.io/qt-6/qwidget.html#createWindowContainer
The window container has a number of known limitations:
Stacking order; The embedded window will stack on top of the widget hierarchy as an opaque box. The stacking order of multiple overlapping window container instances is undefined.
BTW https://forum.qt.io/topic/89472/qwidget-createwindowcontainer-how-to-put-this-widget-createdby-this-api-to-stackunder-another-qwidget asked the same question, but was never answered.
You might try adding
Qt::WindowStaysOnTopHint
to theQPushButton
, but I don't know whether it will make any difference. -
@gaojinhsu Don't use hard-coded geometry stuff but use a layout and add your widgers in there.
-
@Christian-Ehrlicher it's just a demo to show how this happens, using layout can't fix it.
-
@gaojinhsu said in Layout issue with QWidget converted form win32 window:
it's just a demo to show how this happens, using layout can't fix it.
So how should we help when you don't post your original code? Your code you show is missing a layout so it won't work.
-
@gaojinhsu said in Layout issue with QWidget converted form win32 window:
QWidget::createWindowContainer
https://doc.qt.io/qt-6/qwidget.html#createWindowContainer
The window container has a number of known limitations:
Stacking order; The embedded window will stack on top of the widget hierarchy as an opaque box. The stacking order of multiple overlapping window container instances is undefined.
BTW https://forum.qt.io/topic/89472/qwidget-createwindowcontainer-how-to-put-this-widget-createdby-this-api-to-stackunder-another-qwidget asked the same question, but was never answered.
You might try adding
Qt::WindowStaysOnTopHint
to theQPushButton
, but I don't know whether it will make any difference. -
@Christian-Ehrlicher Thanks for trying to help, original code is not necessary ,this demo can reproduce this issue, you can create a blank new Qt Widgets Application project,here is the complete code.
#include "MainWidget.h" #include <QHBoxlayout> #include <Windows.h> #include <qwindow.h> #include <qpushbutton.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { ui.setupUi(this); HINSTANCE hInstance = GetModuleHandle(NULL); WNDCLASSEXW wcex = { sizeof(WNDCLASSEX) }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszMenuName = L"MyMenu"; wcex.lpszClassName = L"RenderWindow"; static ATOM wnd_class_ = RegisterClassExW(&wcex); qDebug() << "RegisterClassExW failed with " << GetLastError(); HWND hwnd = ::CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, L"RenderWindow", L"render", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); QWindow* render_wnd = QWindow::fromWinId((WId)hwnd); QWidget* renderWidget = QWidget::createWindowContainer(render_wnd); QHBoxLayout* mainLayout = new QHBoxLayout(this); mainLayout->setMargin(0); mainLayout->addWidget(renderWidget); this->setLayout(mainLayout); QPushButton* btn = new QPushButton(this); QHBoxLayout* renderLayout = new QHBoxLayout(this); renderLayout->setMargin(0); renderLayout->addWidget(btn); renderWidget->setLayout(renderLayout); } MainWidget::~MainWidget(){ }
-