[英]Embed Qt inside native window (Windows)
我想在 Windows 中嵌入一個 Qt 應用程序(不是相反,因為已經回答了許多其他問題)。 為了澄清我有一個 win32 應用程序,我啟動了一個 qt python 進程; 這個 qt python 進程必須嵌入到 win32 應用程序中。 如何才能做到這一點? 在QWindow::fromWinId
的 API 中,它明確指出:
“創建由另一個進程或使用 Qt 下的本機庫創建的窗口的本地表示......”
“...這可以在支持它的平台上使用,在本機窗口中嵌入 QWindow ,或在 QWindow 中嵌入本機窗口。”
其次QWidget::createWindowContainer
似乎只適用於在 Qt 中嵌入本機窗口(不是我想要的方式)。
我不確定如何在QWindow
創建QWidget
。 從這個問題,看來方法是創建一個QQuickView
與QWindow::fromWinId
; 但是,我似乎無法找到如何將 QWidget 綁定到 QQuickView。
目前我實際上是用::SetParent
設置父級,但有一些奇怪的消息協議需要處理,所以我想嘗試用 Qt 的方法重構它。
到目前為止編寫的一些基本代碼(PySide2,但 C++ 或任何其他帶有 Qt 綁定的語言都可以):
app = QApplication(sys.argv)
hwnd = int(sys.argv[1], 16)
nativeParentWindow = QWindow.fromWinId(hwnd)
quickview = QQuickView(nativeParentWindow)
# this part is incorrect (tries to embed native window into qt)
# I want this application to run embedded inside hwnd
wrongWidget = QWidget.createWindowContainer(quickview)
wrongWidget.show()
sys.exit(app.exec_())
首先,您需要從 HWND 創建一個 QWindow 以便 Qt 可以處理它:
// C++
QWindow *nativeWindow = QWindow::fromWinId(hwnd);
// Python
nativeWindow = QWindow.fromWinId(hwnd);
然后你創建你的 Qt Widget 界面:
// C++
QLabel *label = new QLabel("Hello from Qt");
label->show();
// Python
label = QLabel("Hello from Qt");
label.show();
然后將 Qt Widget 界面的頂部窗口作為本機窗口的父級:
// C++
label->windowHandle()->setParent(nativeWindow);
// Python
label.windowHandle().setParent(nativeWindow);
但是,您不能使用 Qt 來偵聽 HWND 窗口中的更改。 引用Qt 文檔:
注意:生成的 QWindow 不應用於操作底層原生窗口(除了重新父級),或觀察原生窗口的狀態變化。 對此類操作的任何支持都是偶然的,高度依賴於平台且未經測試。
實際上,信號QWindow::widthChanged()
和QWindow::heightChanged()
不會發出。
如果您想監聽來自 HWND 的事件,您必須使用SetWindowsHookEx()
或SetWinEventHook()
以本機 Win32 方式進行。
如果您對調整大小事件感興趣,您可以使用 C 或 C++ 進行:
targetHwnd = hwnd; // defined on global scope
DWORD processId;
DWORD threadId= GetWindowThreadProcessId(hwnd, &processId);
HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, 0, &Wineventproc, processId, threadId, WINEVENT_OUTOFCONTEXT);
使用以下Wineventproc
:
void WINAPI Wineventproc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD idEventThread,
DWORD dwmsEventTime
)
{
if(targetHwnd == hwnd) { // Filter events that are not for our window
qDebug() << "event" << event;
RECT rect;
GetWindowRect(hwnd, &rect);
qDebug() << "Height:" << rect.bottom - rect.top;
qDebug() << "Width:" << rect.right - rect.left;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.