1. 問題描述
用的是python 3.8.20, qt版本使用的是5.15.2, PySide的版本是5.15.2, pybind11的版本為2.13.6
網上說在python腳本中直接用PySide2自帶的QWinWidget,如from PySide2.QtWinExtras import QWinWidget,但我用的版本中說沒有QWinWidget,所以就網上找了QWinWidget的源碼,直接
在c++宿主程序中編譯,后使用pybind11導出到解釋器:
開始想到的是直接構造一個隱藏的QWidget,關聯的是MFC的主窗口句柄,然后將指針導出到解釋器,
PYBIND11_EMBEDDED_MODULE(TestApp, m)
{m.def("GetMainWidget", []() { static auto pWidget = new QWinWidget(AfxGetMainWnd()->m_hWnd);return pWidget; });
}
然后再Python腳本端
dlg = MyUIDialog( TestApp.GetMainWidget )
但執行時提示如下錯誤
TypeError: ‘PySide2.QtWidgets.QDialog’ called with wrong argument
types: PySide2.QtWidgets.QDialog(QWinWidget) Supported signatures:
PySide2.QtWidgets.QDialog(typing.Union[PySide2.QtWidgets.QWidget,
NoneType] = None, PySide2.QtCore.Qt.WindowFlags =
Default(Qt.WindowFlags))
以為是不識別基類,直接構造QWidget
PYBIND11_EMBEDDED_MODULE(TestApp, m)
{m.def("GetMainWidget", []() { static auto pWidget = new QWidget();return pWidget; });
}
但執行時提示如下錯誤
TypeError: ‘PySide2.QtWidgets.QDialog’ called with wrong argument types:
PySide2.QtWidgets.QDialog(QWidget)
Supported signatures:
PySide2.QtWidgets.QDialog(typing.Union[PySide2.QtWidgets.QWidget, NoneType] = None, PySide2.QtCore.Qt.WindowFlags = Default(Qt.WindowFlags))
看樣子,PySide2只認識PySide2.QtWidgets.QWidget,不任務QWidget呀。
2. 解決方案
后面查找資料得知,需要使用PySide2中的QtWidgets.QWidget.find,在腳本環境中重新獲得Widget指針才行,find在windows下接受的是個winId
PYBIND11_EMBEDDED_MODULE(TestApp, m)
{m.def("GetMainWidget", []() { static auto pWidget = new QWinWidget(AfxGetMainWnd()->m_hWnd);return pWidget->winId(); });
}
python腳本:
main_window = QtWidgets.QWidget.find(TestApp.GetMainWidget()) # 通過Qt API轉換指針
dlg = MyUIDialog( main_window )