Gtk + 용 OCaml 바인딩 인 lablgtk2 용 새 위젯 제품군을 작성 중입니다. 이러한 위젯 중 일부는 상당히 복잡한 정보를 편집하거나 표시 할 수 있으므로 GTree
모듈 에서 찾을 수있는 것과 유사한 모델보기 컨트롤러 또는 주제 관찰자를 사용하는 데 관심이 있습니다 .
이 모듈은 각각 연결될 수있는 신호가 있는 GTree.model
및 GTree.view
클래스를 정의하고 GTree.model
하나 이상의에 연결할 수 있습니다 GTree.view
.
라이브러리에서 사용할 수있는 코드는 C 라이브러리의 바인딩이기 때문에 순수 OCaml에서이 구성을 모방하는 것은 그리 간단하지 않습니다. 다음 단계를 수행해야합니다.
1과 2를 통과 할 수 있지만 3과 4를 수행하는 방법을 잘 모르겠습니다. 이러한 작업을 올바르게 수행하는 방법은 무엇입니까?
새로운 위젯 자체의 정의는 문제가되지 않습니다. 새 위젯은 일반적으로 Gnome 캔버스 또는 컴포지트의 특수 버전입니다. 전자의 경우 새 위젯은 Gnome 캔버스에서 GObj.widget으로 상속 할 수 있으며 후자의 경우 컴포지트를 보관하는 데 사용되는 컨테이너에서 제공하는 GObj.widget을 사용할 수 있습니다. 이것은 일반적으로 다음과 같습니다.
class view () =
let vbox = GPack.vbox () in
…
object(self)
inherit GObj.widget vbox#as_widget
…
end
바인딩은 새 신호를 정의하는 코드에 대한 많은 예제를 제공하므로 매개 변수가없는 신호의 간단한 경우를 고려하여 다음 스 니펫에 설명 된대로 위젯에 대한 새 신호를 정의 할 수 있습니다.
open GtkSignal
module Event =
struct
let plop : ([>`widget], unit -> unit) t = {
name = "plop_event";
classe = `widget;
marshaller = marshal_unit;
}
let fizz : ([>`widget], unit -> unit) t = {
name = "fizz_event";
classe = `widget;
marshaller = marshal_unit;
}
end
class pill_signals obj =
object (self)
inherit ['a] GObj.gobject_signals (obj :> Gtk.widget Gobject.obj)
method plop = self#connect Event.plop
method fizz = self#connect Event.fizz
end
이러한 정의를 통해 view
위젯은 적절한 connect
메서드 를 정의하여 이러한 신호를 노출 할 수 있습니다 .
method connect =
new pill_signals obj
이 함수 GtkSignal.emit
는 객체에 신호를 내보내 등록 된 콜백을 트리거하는 목적으로 사용되는 것 같습니다 . 이것은 다음 서명으로 작동합니다.
val emit :
'a Gobject.obj ->
sgn:('a, 'b) GtkSignal.t ->
emitter:(cont:('c Gobject.data_set array -> 'd) -> 'b) ->
conv:(Gobject.g_value -> 'd) -> 'b
처음 두 매개 변수는 자명하지만, 나머지 두 매개 변수가 무엇인지는 명확하지 않습니다. 불행히도 lablgtk 소스 코드에는 코드의 C 측에서 신호가 방출되기 때문에 사용 예제가 없습니다. 이 두 가지 주장은 a로 구체화 된 신호의 인수 준비 'c Gobject.data_set array
및 레이블이 붙은 인수로 산출 된 값의 검색과 관련된 것으로 보입니다 ~conv
. 그럼에도 불구하고 ~cont
이미 터 에서 -argument 의 역할은 여전히 지워 져야합니다.
모델 정의에서 까다로운 부분 GObj.object
은 수신 신호를 보낼 수 있으려면 상속해야한다는 것 입니다. 불행히도 최소한의 Gtk + 객체를 직접 정의 할 수있는 함수는 없습니다. 내가이 방향으로 가장 멀리 갔던 것은
module Model =
struct
let create () =
GtkObject.make ~classe:"GObject" []
end
let model () =
new model (Model.create ())
함수 model
를 호출하여 해당 객체를 인스턴스화하면 다음 메시지가 생성됩니다.
Gtk-CRITICAL ** : IA__gtk_object_sink : 'GTK_IS_OBJECT (object)'어설 션 실패
분명히 여기에 뭔가 수상한 것이 있습니다. 아마도 매개 변수 목록 (위 스 니펫의 빈 목록)이 너무 작았을 것입니다.
LablGTK는 Gtk 시그널링 메커니즘에 대한 멋진 인터페이스를 제공하므로 GtkSignal
함수 를 조정 하거나 마샬링 하지 않고도 사용할 수 있습니다. 이 인터페이스는에서 제공하며 GUtil
깔끔하게 문서화되어 있습니다.
LablGTK 객체에 ML 신호를 추가하려면 :
{[
class mywidget_signals obj ~mysignal1 ~mysignal2 = object
inherit somewidget_signals obj
inherit add_ml_signals obj [mysignal1#disconnect; mysignal2#disconnect]
method mysignal1 = mysignal1#connect ~after
method mysignal2 = mysignal2#connect ~after
end
class mywidget obj = object (self)
inherit somewidget obj
val mysignal1 = new signal obj
val mysignal2 = new signal obj
method connect = new mywidget_signals obj ~mysignal1 ~mysignal2
method call1 = mysignal1#call
method call2 = mysignal2#call
end
]}
임의의 객체에 ML 신호를 추가 할 수도 있습니다. ml_signals
대신 widget_signals
및 에서 상속 add_ml_signals
합니다.
{[
class mysignals ~mysignal1 ~mysignal2 = object
inherit ml_signals [mysignal1#disconnect; mysignal2#disconnect]
method mysignal1 = mysignal1#connect ~after
method mysignal2 = mysignal2#connect ~after
end
]}
이제 위의 1, 2, 3, 4 점을 쉽게 해결할 수 있습니다.
GUtil
대신 새 신호를 정의하는 데 사용 합니다.GtkSignal
call
방법은 ['a] GUtil.signal
.GtkSignal
더 이상 사용하지 않기 때문에 실제로 문제 없습니다.이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다