В helloworld. c он пишет
Widget_BindEvent(btn, "click", OnBtnClick, NULL, NULL);
И я обнаружил, что прототип Widget_BindEvent
определен в widget_event.h как
LCUI_API int Widget_BindEventById(LCUI_Widget widget, int event_id,
LCUI_WidgetEventFunc func, void *data,
void(*destroy_data)(void*));
, где LCUI_WidgetEventFunc
определено в widget_event.h как
typedef void(*LCUI_WidgetEventFunc)(LCUI_Widget, LCUI_WidgetEvent, void*);
Поэтому я перевожу код в
class LCUI_WidgetEventRec_ (ctypes.Structure): pass
LCUI_WidgetEvent = ctypes.POINTER(LCUI_WidgetEventRec_)
LCUI_WidgetEventFunc = ctypes.CFUNCTYPE(ctypes.c_void_p, LCUI_Widget, LCUI_WidgetEvent, ctypes.c_void_p)
_Widget_BindEvent = dll.Widget_BindEvent
_Widget_BindEvent.argtypes = LCUI_Widget, ctypes.c_char_p, LCUI_WidgetEventFunc, ctypes.c_void_p, ctypes.c_void_p
def Widget_BindEvent( widget, event_name, func, data=None, destroy_data=None ):
event_name = event_name.encode('utf8')
func = LCUI_WidgetEventFunc(func)
data = ctypes.cast(data, ctypes.c_void_p),
destroy_data = ctypes.cast(destroy_data, ctypes.c_void_p)
return _Widget_BindEvent( widget, event_name, func, data, destroy_data )
Затем Я называю это
Widget_BindEvent(btn, "click", OnBtnClick, None, None);
Но я получаю
File "helloworld.py", line 24, in main
Widget_BindEvent(btn, "click", OnBtnClick, None, None);
File "r:\LC-Finder\app\LCUI.py", line 82, in Widget_BindEvent
destroy_data
ctypes.ArgumentError: argument 4: <class 'TypeError'>: wrong type
Очевидно, что часть функции обратного вызова неверна. Любая помощь? Спасибо
ps 1, LCUI.dll
можно найти в LC-Finder.zip
из https://github.com/lc-soft/LC-Finder/releases
. который предназначен только для windows. Но говорят, что версию linux можно легко скомпилировать.
ps 2, полный код
# helloworld.py
from LCUI import *
def OnBtnClick(self: LCUI_Widget, e: LCUI_WidgetEvent, arg):
str = ctypes.c_wchar*256
edit = LCUIWidget_GetById("edit");
txt = LCUIWidget_GetById("text-hello");
TextEdit_GetTextW(edit, 0, 255, str);
TextView_SetTextW(txt, str);
def main():
LCUI_Init();
root = LCUIWidget_GetRoot();
pack = LCUIBuilder_LoadFile("helloworld.xml".encode('utf8'));
if (not pack):
return -1;
Widget_Append( root, pack,);
Widget_Unwrap(pack);
btn = LCUIWidget_GetById("btn");
Widget_BindEvent(btn, "click", OnBtnClick, None, None);
return LCUI_Main();
if __name__ == '__main__':
main()
и
# LCUI.py
import ctypes
NULL = 0
dll = ctypes.CDLL('lcui.dll')
class LCUI_WidgetRec_ (ctypes.Structure): pass
LCUI_Widget =ctypes.POINTER(LCUI_WidgetRec_)
LCUI_Init = dll.LCUI_Init
LCUIWidget_GetRoot = dll.LCUIWidget_GetRoot
LCUIWidget_GetRoot.restype = LCUI_Widget
LCUIBuilder_LoadFile = dll.LCUIBuilder_LoadFile
LCUIBuilder_LoadFile.restype = LCUI_Widget
Widget_Append = dll.Widget_Append
Widget_Append.argtypes = LCUI_Widget, LCUI_Widget
Widget_Append.restype = ctypes.c_int
Widget_Unwrap = dll.Widget_Unwrap
LCUIWidget_GetById = dll.LCUIWidget_GetById
LCUIWidget_GetById.restype = LCUI_Widget
class LCUI_WidgetEventRec_ (ctypes.Structure): pass
LCUI_WidgetEvent = ctypes.POINTER(LCUI_WidgetEventRec_)
LCUI_WidgetEventFunc = ctypes.CFUNCTYPE(ctypes.c_void_p, LCUI_Widget, LCUI_WidgetEvent, ctypes.c_void_p)
_Widget_BindEvent = dll.Widget_BindEvent
_Widget_BindEvent.argtypes = LCUI_Widget, ctypes.c_char_p, LCUI_WidgetEventFunc, ctypes.c_void_p, ctypes.c_void_p
def Widget_BindEvent(widget, event_name, func, data=None, destroy_data=None):
event_name = event_name.encode('utf8')
func = LCUI_WidgetEventFunc(func)
data = ctypes.cast(data, ctypes.c_void_p),
destroy_data = ctypes.cast(destroy_data, ctypes.c_void_p)
return _Widget_BindEvent( widget, event_name, func, data, destroy_data )
LCUI_Main = dll.LCUI_Main