GTKSharp中的自定义信号

时间:2017-09-18 17:50:51

标签: c# signals gtk3 glib gtk#

上下文

我正在将C / GTK + GUI应用程序转换为C#。我在VS2017中使用了GTKSharp绑定版本3.22.0。

应用程序声明了几个信号,如

g_signal_new ("SIG_NAME", params...);

并通过g_signal_emit_by_name(... "SIG_NAME"...)发出。

问题

我无法找到将该行为转换为GTK#的方法。

我查看了GTK#的源代码,看看如何定义和处理自定义信号,如here,但我无法模仿那里实现的行为。

方法

  1. 方法#1
  2. 我尝试过定义这样的自定义对象:

    using System;
    using Gtk;
    
    public class MyApp
    {
        public class MyCustomObj : GLib.Object
        {
            public delegate void MyDelegateSignalHandler(int arg0, int arg1);
            public delegate void MyDelegate(int arg0, int arg1);
            public class MyDelegateArgs : GLib.SignalArgs
            {
                public int a { get; set; }
            }
            public MyCustomObj() : base()
            {}
            [GLib.Signal("MyEvent")]
            public event MyDelegate MyDelegateEvent
            {
                add
                {
                    GLib.Object.GetObject(Handle).AddSignalHandler("MyEvent", value, new MyDelegateSignalHandler((a, b) => { }));
                }
                remove
                {
                    GLib.Object.GetObject(Handle).RemoveSignalHandler("MyEvent", value);
                }
            }
        }
    
        public static void Main(string[] args)
        {
            MyCustomObj newObj = new MyCustomObj();
            newObj.MyDelegateEvent += new MyCustomObj.MyDelegate((a, b) => { });
            GLib.Signal.Emit(newObj, "MyEvent", 1, 2);
        }
    }
    

    那是:

    1. 声明了自定义GLib对象类型MyCustomObj
    2. 声明MyDelegate事件
    3. 创建MyCustomObj的实例,并将回调附加到其新事件
    4. 发出MyEvent信号。
    5. 然而,当调用AddSignalHandler()时,GTK对此不太满意:

      (CustomSignal.exe:9276): GLib-GObject-[1;33mWARNING[0m **: ../../glib-2.50.2/gobject/gsignal.c:2423: signal 'MyEvent' is invalid for instance '05cc4000' of type '__gtksharp_0_MyApp+2bMyCustomObj'
      

      因此GLib.Signal.Emit报告

      Invalid signal name: MyEvent
      
      1. 方法#2
      2. 但是,GObject的定义以这种方式使用AddSignalHandler

        public void AddNotification (string property, NotifyHandler handler)
        {
            AddSignalHandler ("notify::" + property, handler, typeof(NotifyArgs));
        }
        

        所以看起来名为notify::<whatever>的信号处理得很好。我们试试这个:

        public class MyCustomObj : GLib.Object
        {
            public MyCustomObj() : base()
            {}
            [GLib.Signal("notify::abc")]
            public event GLib.NotifyHandler MyDelegateEvent
            {
                add
                {
                    GLib.Object.GetObject(Handle).AddSignalHandler("notify::abc", value, typeof(GLib.NotifyArgs));
                }
                remove
                {
                    GLib.Object.GetObject(Handle).RemoveSignalHandler("notify::acb", value);
                }
            }
        }
        
        public static void Main(string[] args)
        {
            MyCustomObj newObj = new MyCustomObj();
            newObj.MyDelegateEvent += new GLib.NotifyHandler((o, e) => { Console.WriteLine("Signal received"); });
            GLib.Signal.Emit(newObj, "notify::abc");
            Console.ReadLine();
        }
        

        这实际上有效。此外,[GLib.Signal("notify::abc")]是不必要的,因为信号被正确地登记和处理。 将信号名称重命名为非notify::... 的任何内容,但会导致应用程序发出通常的警告:

        (CustomSignal.exe:9276): GLib-GObject-[1;33mWARNING[0m **: ../../glib-2.50.2/gobject/gsignal.c:2423: signal '...' is invalid for instance '05cc4000' of type '__gtksharp_0_MyApp+2bMyCustomObj'
        

        我可以用一只手,因为我没有想法。

0 个答案:

没有答案