Python笔记:c++内嵌python,c++主窗口如何传递给脚本中的QDialog,使用的是pybind11
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 )