2016-09-02 2 views
2

J'ai une DLL, qui utilise OpenGl pour dessiner sur la fenêtre. Dll obtenir une fenêtre par HWMD.la transmission de qwidget.winid à DLL en 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); 

Le C++ qt est l'application fonctionnent correctement.

#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(); 
} 

Mais comment faire la même chose en python? Mon programme écrase l'envoi de 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_() 

impression (self.winId()) est

+0

'Dans: print (self.winId()) Out: ' – den

+0

Réponse: 'init = e3d.Init init.argtypes = [ctypes.c_uint32] peinture = E3D. Peinture paint.argtypes = [ctypes.c_uint32] = redimensionner e3d.Resize resize.argtypes = [ctypes.c_uint32, ctypes.c_int32, ctypes.c_int32] ' – den

Répondre

0

Il serait plus facile de vérifier avec la dll, donc je vais parler le bleu. Dans votre code C++ vous avez obtenu ce code d'initialisation:

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(); 
} 

Lorsque vous créez votre moteur par exemple lib et en utilisant la méthode load mais en python que vous ne faites rien de cela:

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

Mais avant de créer le MyGLWidget vous n'initialisez pas votre moteur comme son homologue C++, la question est, pourquoi pas?

+0

je pensais qu'il initialisé par ctypes.For exemple pour le projet https : //github.com/ombschervister/ctypes_test ce travail pour les types par défaut. Mais quand j'essaye d'envoyer HWND j'attrape l'exception 'ctypes.ArgumentError: argument 1: : Je ne sais pas comment convertir le paramètre 1' – den

+0

Oui, vous aviez raison. J'ai défini les types de fonctions et le programme fonctionne maintenant. HWND est ctypes.c_uint32. – den

+0

@den Btw, c'est une approche assez intéressante qui résume l'ensemble du moteur de jeu en C++ et qui utilise pyqt en tant que frontend. Avez-vous un exemple de travail sur github pour le voir? – BPL