2016-09-02 2 views
2

У меня есть dll, которые используют OpenGl для рисования на окне. Dll получить окно по HWMD.Передача qwidget.winid в DLL в Python

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_() 

печати (self.winId()) является

+0

'В: печать (self.winId()) Out: ' – den

+0

Ответ: 'INIT = e3d.Init init.argtypes = [ctypes.c_uint32] краска = E3D. Краска paint.argtypes = [ctypes.c_uint32] размер = e3d.Resize resize.argtypes = [ctypes.c_uint32, ctypes.c_int32, ctypes.c_int32] ' – den

ответ

0

Было бы легче проверить имея 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 метод, но в питоне вы ничего, что не делает:

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

Но перед созданием MyGLWidget вы не инициализируете свой движок как его аналог C++, вопрос в том, почему бы и нет?

+0

Я думал, что она инициализируется например ctypes.For для проекта по протоколу HTTPS : //github.com/ombschervister/ctypes_test эта работа для типов по умолчанию. Но когда я пытаюсь отправить HWND, я поймаю исключение 'ctypes.ArgumentError: argument 1: : Не знаю, как преобразовать параметр 1' – den

+0

Да, вы были правы. Я определил типы функций, и программа работает сейчас. HWND - ctypes.c_uint32. – den

+0

@den Btw, это довольно интересный подход, абстрагирующий весь движок игры на C++ и используя pyqt в качестве интерфейса. У вас есть какой-нибудь рабочий пример на github, чтобы взглянуть на него? – BPL

Смежные вопросы