将 qwidget.winid 交给 Python 中的 DLL

handing qwidget.winid to DLL in Python

我有一个 dll,它使用 OpenGl 在 window 上绘图。 Dll 通过 HWMD 获得 window。

DLL:

extern "C" __declspec(dllexport) int Init(HWND hWnd);
extern "C" __declspec(dllexport) void Resize(HWND hWnd, int w, int h);
extern "C" __declspec(dllexport) void Paint(HWND hWnd);

c++ qt 应用程序运行正常。

#include "windows.h"
#include <QApplication>
#include <QWidget>
#include <QGLWidget>
#include <QMessageBox>
#include <QSplitter>
#include <QLibrary>

typedef void (*InitPrototype)(HWND);
typedef void (*PaintPrototype)(HWND);
typedef void (*ResizePrototype)(HWND, int, int);

InitPrototype c_Init;
PaintPrototype c_Paint;
ResizePrototype c_Resize;

bool load_opengl_library(){
    QLibrary lib("engine3d");
    lib.load();
    c_Init = (InitPrototype)lib.resolve("Init");
    c_Paint = (PaintPrototype)lib.resolve("Paint");
    c_Resize = (ResizePrototype)lib.resolve("Resize");
    return true;
}

class MyGlWidget: public QGLWidget {
public:
    MyGlWidget(QWidget *parent = 0): QGLWidget(parent){}
    void showEvent(QShowEvent* event){
        c_Init((HWND)(this->winId()));
    }
    void paintEvent(QPaintEvent* event){
        c_Paint((HWND)this->winId());
    }
    void resizeEvent(QResizeEvent* event){
        c_Resize((HWND)this->winId(), this->width(), this->height());
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    load_opengl_library();
    MyGlWidget w;
    w.show();
    return a.exec();
}

但是在 python 中如何做同样的事情?我的程序在发送 widget.winId().

时崩溃了
# coding=utf-8
import ctypes
from PyQt5 import QtWidgets, QtOpenGL
app = QtWidgets.QApplication([])

e3d = ctypes.CDLL(r"engine3d.dll")
init = lambda hwnd: e3d.Init(hwnd)
paint = lambda hwnd: e3d.Paint(hwnd)
resize = lambda hwnd, w, h: e3d.Paint(hwnd, w, h)

class MyGLWidget(QtOpenGL.QGLWidget):
    def __init__(self):
        super().__init__()
    def showEvent(self, ev):
        init(self.winId())
    def paintEvent(self, ev):
        paint(self.winId())
    def resizeEvent(self, ev):
        resize(self.winId(), self.width(), self.height())

w = MyGLWidget()
w.show()
app.exec_()

print(self.winId()) 是

检查有dll会更容易,所以我会说出来。在你的 C++ 代码中,你得到了这个初始化代码:

bool load_opengl_library(){
    QLibrary lib("engine3d");
    lib.load();
    c_Init = (InitPrototype)lib.resolve("Init");
    c_Paint = (PaintPrototype)lib.resolve("Paint");
    c_Resize = (ResizePrototype)lib.resolve("Resize");
    return true;
}

...

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    load_opengl_library();
    MyGlWidget w;
    w.show();
    return a.exec();
}

在您创建引擎实例的地方lib并使用load方法,但在python中您没有做任何事情:

w = MyGLWidget()
w.show()
app.exec_()

但是在创建 MyGLWidget 之前,您没有将引擎初始化为它的 C++ 对应物,问题是,为什么不呢?