Найти - Пользователи
Полная версия: объединение wxPython и CBuilder
Начало » GUI » объединение wxPython и CBuilder
1
DonVulture
Здравствуйте.
Возник вопрос:
Как из wxPython вызывать не модальные формы CBuilder, поскольку при создании таких форм проблемой оказалось их закрытие.
Я реализовал код, хотелось бы выслушать конструктивную критику- возможно, что-то сделано неправильно. Код реализован для создания нескольких не модальных формы С, вызываемых из DLL.

Приведу код формы CBuilder

UNITFORM.h
//---------------------------------------------------------------------------

#ifndef UnitFormH
#define UnitFormH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
typedef void (*fvoid)(char*);
typedef void (*fvint)(void* form_id, int);
class TForm3 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TButton *Button3;
void __fastcall Button3Click(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
public: // User declarations
__fastcall TForm3(TComponent* Owner);
fvoid getfun; // callback для получения данных из формы
fvint closefun; // callback для получения сигнала закрытия формы
};
//---------------------------------------------------------------------------
extern PACKAGE TForm3 *Form3;
//---------------------------------------------------------------------------
#endif
UNITFORM.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UnitForm.h"


using namespace std;
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm3::Button3Click(TObject *Sender)
{
// передать данные из формы Builder в wxPython
if (getfun!=NULL)
{
// используем callback функцию
getfun( Edit1->Text.t_str() );
}
}

//---------------------------------------------------------------------------

void __fastcall TForm3::FormClose(TObject *Sender, TCloseAction &Action)
{
// передать сигнал закрытия формы
if ( closefun!=NULL)
{
int isClose=1;
void* form_id=static_cast<void *>(this);
// используем callback функцию
closefun( form_id, isClose );
}
}
//---------------------------------------------------------------------------
Приведу код формы C++ DLL
UNITDLL.h
//---------------------------------------------------------------------------

#ifndef UnitDLLH
#define UnitDLLH

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <Dialogs.hpp>
#include <ComCtrls.hpp>

#include <ExtCtrls.hpp>
#include <ExtDlgs.hpp>


using namespace std;

typedef void (*fvoid)(char*); // callback для получения данных из формы
typedef void (*fvint)(void* form_id, int); // callback для получения сигнала закрытия формы
extern "C"
{
// создать и показать окно формы
void __declspec(dllexport) ShowForm(void*& form_id);
// передать данные в поле формы
void __declspec(dllexport) SetStr(void * &form_id,char* str);
// забрать данные из поля формы
void __declspec(dllexport) GetStr(void* &form_id, fvoid getfun);
// получить сигнал закрытия формы
void __declspec(dllexport) IsCloseSignal(void* &form_id, fvint closefun);
// уничтожить форму
void __declspec(dllexport) CloseForm(void* &form_id);

}
//---------------------------------------------------------------------------
#endif
UNITDLL.cpp
//---------------------------------------------------------------------------


#pragma hdrstop

#include "UnitDLL.h"
#include "UnitForm.h"
void ShowForm(void*& form_id)
{
// создаем форму
Application-> CreateForm(__classid(TForm3), &Form3);
// показываем форму
Form3->Show();
// возвращаем указатель на форму, чтобы потом была возможность к ней обратиться
form_id = static_cast<void *>(Form3);
}
//---------------------------------------------------------------------------

void __declspec(dllexport) SetStr(void * &form_id,char* str)
{
if (form_id!=NULL)
{
// устанавливаем указатель на нужную форму
TForm3 * oldForm=static_cast<TForm3 *>(form_id) ;
// передаем в нее нобходимый текст из wxPython
oldForm->Edit1->Text = str;
}
}

//---------------------------------------------------------------------------
void __declspec(dllexport) GetStr(void* &form_id, fvoid getfun)
{
if (form_id!=NULL)
{
// устанавливаем указатель на нужную форму
TForm3 * oldForm=static_cast<TForm3 *>(form_id) ;
// передаем текст из формы в wxPython
// используем callback функцию
oldForm->getfun=getfun;
}
}

//---------------------------------------------------------------------------
void __declspec(dllexport) IsCloseSignal(void* &form_id, fvint closefun)
{
if (form_id!=NULL)
{
// устанавливаем указатель на нужную форму
TForm3 * oldForm=static_cast<TForm3 *>(form_id) ;
// передаем сигнал о закрытии формы
// используем callback функцию
oldForm->closefun=closefun;
}
}

//---------------------------------------------------------------------------
void __declspec(dllexport) CloseForm(void* &form_id)
{
if (form_id!=NULL)
{
// устанавливаем указатель на нужную форму
TForm3 * oldForm=static_cast<TForm3 *>(form_id) ;
// уничтожаем форму
oldForm->Free();
}
}

#pragma package(smart_init)
Приведу код приложения на wxPython
#!/usr/bin/env python
# -*- coding: cp1251 -*-


import wx
import threading

from ctypes import *
import ctypes

class MainFormApp(wx.App):
def OnInit(self):
self.frame = MainFormFrame(None,
title="MainForm")
self.frame.Show()
return True

class MainFormFrame(wx.Frame):
"""Main application window"""
def __init__(self, *args, **kwargs):
super(MainFormFrame, self).__init__(*args, **kwargs)

# Attributes
self.panel = MainFormPanel(self)


# Layout
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel, 1, wx.EXPAND)
self.SetSizer(sizer)
self.SetInitialSize()



class MainFormPanel(wx.Panel):
def __init__(self, parent):
super(MainFormPanel, self).__init__(parent)

# Attributes
self.output = wx.TextCtrl(self)
self.b_newDllForm = wx.Button(self, label="Родить DLL")
self.b_textToDll = wx.Button(self, label="Текст в DLL")

# Event Handlers
self.Bind(wx.EVT_BUTTON, self.OnButton)

# Layout
self.__DoLayout()

# лист указателей CBuilder Form запущенных
self.listForms=[]

# загрузка библиотеки
self.cv = cdll.LoadLibrary(r"Debug\project3.dll")

# создаем callback функцию для передачи данных с CBuilder Form в wxPython
CRETFUN = CFUNCTYPE(c_void_p,c_char_p)
self.return_func = CRETFUN(self.SetTextMethod)

# создаем callback функцию для передачи сигнала закрытия с CBuilder Form в wxPython
CENDFUN = CFUNCTYPE(c_void_p,c_void_p, c_int)
self.end_func = CENDFUN(self.GetDLLCloseSignal)


def __DoLayout(self):
vsizer = wx.BoxSizer(wx.VERTICAL)
hsizer = wx.BoxSizer(wx.HORIZONTAL)
gridsz = wx.GridSizer(2, 2, 5, 5)

# Layout controls
gridsz.Add(wx.StaticText(self, label="Текст:"))
gridsz.Add(self.output, 0, wx.EXPAND)
vsizer.Add(gridsz, 0, wx.EXPAND|wx.ALL, 10)
hsizer.Add(self.b_newDllForm, 0, wx.ALL, 5)
hsizer.Add(self.b_textToDll, 0, wx.ALL, 5)
vsizer.Add(hsizer, 0, wx.ALIGN_CENTER_HORIZONTAL)

self.SetSizer(vsizer)

def GetDLLCloseSignal(self,form_id,closeFlag):
"""функция для callback - получения из DLL сигнала закрытия формы"""
print "all form_id: %s"% self.listForms
print "closeFormID: %s"%form_id
form_id_aft=c_void_p(form_id)
print "closeFormID_after: %s" %form_id_aft
print "closeFlag: %s"%closeFlag
# если сигнал закрытия получен, можно уничтожить форму
if closeFlag == 1:
# уничтожаем фомру
self.cv._CloseForm(ctypes.byref(form_id_aft))
# сбрасываем указатель на форму
pos_form_id=[el.value for el in self.listForms].index(form_id)
del self.listForms[pos_form_id]


def SetTextMethod(self,text):
"""функция для callback - получения текста из DLL"""
self.output.SetValue(text)


def OnButton(self, event):
if event.GetEventObject() == self.b_newDllForm:
# создаем указатель на будующую CBuilder Form
form_id=c_void_p(0)
# создаем и показываем форму
self.cv._ShowForm(ctypes.byref(form_id))
# выводим значения указателя на CBuilder Form
print "form id: %s"%form_id
self.listForms.append(form_id)
# связываем callback для получения текста из CBuilder Form
self.cv._GetStr(ctypes.byref(form_id),self.return_func)
# связываем callback для поулчения сигнала закрытия CBuilder Form
self.cv._IsCloseSignal(ctypes.byref(form_id),self.end_func)

if event.GetEventObject() == self.b_textToDll:
output = self.output.GetValue()
# передаем данные из wxPython в CBuilder Form
if len(self.listForms)!=0 :
form_id=self.listForms[0]
# в случае если форма уже сущесвтует
if form_id !=c_void_p(0) :
self.cv._SetStr(ctypes.byref(form_id),str(output))



if __name__ == '__main__':
app = MainFormApp(False)
app.MainLoop()

def main():
pass

if __name__ == '__main__':
main()
Андрей Светлов
Месье знает толк в извращениях!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB