簡體   English   中英

在本機窗口中嵌入 Qt (Windows)

[英]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 從這個問題,看來方法是創建一個QQuickViewQWindow::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM