python调用Qt动态库(带界面)


#include <QApplication>
#include "testexe_dll.h"
#include "iostream"


#ifdef __cplusplus
extern "C" {
#endif
    TESTEXE_DLL_EXPORT int addFunc(int a, int b)
    {
        int result = a + b;
        std::cout<<"-----------";
        return result;
    }
    TESTEXE_DLL_EXPORT void show_dialog(TestExe_dll *dll)
    {
        dll->showDialog();
    }
    TESTEXE_DLL_EXPORT QWidget* get_dialog(TestExe_dll *dll)
    {
        return dll->getDialog();
    }
    TESTEXE_DLL_EXPORT void init(TestExe_dll *dll)
    {
        dll->initWin();
    }
#ifdef __cplusplus
}
#endif

QWidget* g_widget;
Form *dlgForm = NULL;

int argc;
char* argv[] = {};
QApplication a(argc, argv);


TestExe_dll::TestExe_dll()
{
}

int TestExe_dll::showDialog()
{
    dlgForm->show();
    return a.exec();
}

void TestExe_dll::initWin()
{
    dlgForm = new Form();
    g_widget = dlgForm;
    dlgForm->hide();
}

QWidget *TestExe_dll::getDialog()
{
    return g_widget;
}

除第三个方法以外,其他方法python可以调用成功。
问题:python如何接收QWidget指针类型?(python 零基础)
ps:QWidget是Qt中的窗口类,我将Qt窗口返回出去,供外部获取窗口内的控件。

以下是调用过程及报错信息:AttributeError: 'int' object has no attribute 'children'
Children()是Qt中QWidget中的方法,通过get_dialog()返回QWidget给widget,widget为int类型,故报错int中没有children属性,我需要一个QWidget来接收get_dialog(),但是我不知道在python中如何操作。

from PyQt6.QtWidgets import QApplication,QMainWindow,QWidget,QPushButton
from ctypes import *
import sys
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtWidgets import QApplication
if __name__ == "__main__":
    App = QApplication(sys.argv)    # 创建QApplication对象,作为GUI主程序入口

    dll_path = "E:\\testQtProject\\testExe_dll\\bin\\testExe_dll.dll"
    lib = cdll.LoadLibrary(dll_path) # 加载Qt动态库
    lib.init() # 库初始化

    widget = lib.get_dialog() # 获取窗口,返回值为QWidget*
    print(widget)

    listW = widget.children()
    print(listW)

    widget.show()
    sys.exit(App.exec())   # 循环中等待退出程序

报错信息:
Traceback (most recent call last):
File "C:\Users\dell\PycharmProjects\untitled\testQt.py", line 17, in
listW = widget.children()
AttributeError: 'int' object has no attribute 'children'

报错翻译
文件“C:\Users\dell\PycharmProjects\untitle\testQt.py”,第17行,位于
listW=widget.children()
AttributeError:“int”对象没有属性“children”

https://www.5axxw.com/questions/simple/dnmfom

python调用QT界面使用方法
可以参考下

调用了一个不存在的属性,导致的报错

AttributeError: 'int' object has no attribute 'children'这样的错误的意思是,这个widget是一个整数类似的变量,整数变量是没有children这个属性的。所以报错了,你检查下widget是否是一个QWidget实例。应该是这一行代码有问题:
widget = lib.get_dialog()
这里应该返回的这个widget是一个整数,而不是QWidget实例

访问了对象不存在的属性导致的

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在Python中,可以使用ctypes库调用C++动态库(DLL)。在你的代码中,你已经成功地调用了C++动态库,并且能够通过get_dialog()方法获取到一个QWidget指针。但是,在Python中,你需要将该指针转换为QWidget对象才能够调用其方法和属性。

以下是修改后的Python代码:

from PyQt6.QtWidgets import QApplication, QWidget
import sys
from ctypes import *

if __name__ == "__main__":
    App = QApplication(sys.argv)

    dll_path = "E:\\testQtProject\\testExe_dll\\bin\\testExe_dll.dll"
    lib = cdll.LoadLibrary(dll_path)
    lib.init()

    widget_ptr = lib.get_dialog()
    widget_int = cast(widget_ptr, c_void_p).value
    widget = QWidget()
    widget.__init__(widget_int)

    listW = widget.children()
    print(listW)

    widget.show()
    sys.exit(App.exec())

在修改后的Python代码中,使用cast()函数将QWidget指针转换为c_void_p类型,然后使用value属性获取指针的值。接下来,使用QWidget()构造函数创建一个QWidget对象,并将从指针中获取的值传递给该对象的构造函数__init__()。最后,可以通过调用children()方法来获取该QWidget对象的子控件列表。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

援引GPT回答:
在Python中,你可以使用ctypes库来调用C++的动态链接库。然而,由于QWidget是一个C++对象,它在Python中没有直接的对应类型。因此,你需要使用ctypes的POINTER来表示QWidget指针类型,并且在调用C++函数时进行适当的类型转换。

以下是修改后的代码示例:

from PyQt6.QtWidgets import QApplication, QWidget
from ctypes import *
import sys

# 定义QWidget指针类型
QWidgetPtr = POINTER(QWidget)

if __name__ == "__main__":
    App = QApplication(sys.argv)
 
    dll_path = "E:\\testQtProject\\testExe_dll\\bin\\testExe_dll.dll"
    lib = cdll.LoadLibrary(dll_path)
    lib.init()
 
    # 声明C++函数返回类型为QWidgetPtr
    lib.get_dialog.restype = QWidgetPtr
 
    # 调用C++函数并进行类型转换
    widget_ptr = lib.get_dialog()
    widget = QWidget(QWidgetPtr.from_address(widget_ptr))
    print(widget)
 
    # 使用QWidget对象的方法
    listW = widget.children()
    print(listW)
 
    widget.show()
    sys.exit(App.exec())

通过使用POINTER(QWidget)类型来声明QWidget指针类型,并使用QWidgetPtr.from_address(widget_ptr)进行类型转换,你可以在Python中使用QWidget对象,并调用其方法。

注意:由于QWidget对象在C++中创建并管理,因此在退出程序之前,确保正确地释放相关的资源。

参考newbing
在Python中,你可以使用PyQt或者PySide库来调用Qt动态库并操作窗口和控件。这些库提供了与Qt C++库相似的接口,使得你可以在Python中创建和管理Qt窗口和控件。

首先,你需要安装PyQt或PySide库。你可以使用pip来安装,例如:

pip install PyQt5

然后,你可以创建一个Qt窗口并返回出去。以下是一个示例代码:

from PyQt5.QtWidgets import QApplication, QWidget  
  
def get_dialog():  
    app = QApplication([])  
    widget = QWidget()  
    widget.setWindowTitle("My Window")  
    widget.show()  
    return widget  
  
# 使用get_dialog函数获取QWidget对象  
widget = get_dialog()

在这个示例中,get_dialog函数创建了一个QApplication对象和一个QWidget对象,并设置了窗口标题并显示它。然后,该函数返回了这个QWidget对象。

你可以使用children()方法来获取QWidget的子控件。例如:


for child in widget.children():  
    print(child)

这将输出widget的所有子控件。

需要注意的是,返回的widget是一个PyQt5的QWidget对象,而不是C++中的原始指针。在Python中,我们通常通过对象的方法和属性来操作它们,而不是直接操作指针。因此,你需要使用PyQt提供的接口来操作窗口和控件。