1

语境

在使用小部件编写一个简单的应用程序GtkEntry来处理来自用户的文本命令之后,我想做一些设计更改。

截至目前,我在按键上使用信号挂钩。如果键是指定值,则显示命令行并处理entry小部件上的各种操作。像例如

  • Ctrl+ a:将光标移动到输入的开头。
  • Ctrl+ u:删除光标前的文本。
  • ...

以及解析命令和保存/加载历史记录。

我不满意这是如何缝合在一起的。命令解析成为以下内容的子集:

main_window -> mode_check -> command_line_act -> parse_cmd+execute

正如我所看到的,一种好的方法是使用 GtkEntry 作为基础编写一个新的小部件 - 并在命令 enter上发送信号。所有内部结构,如 Ctrl+... 和新小部件处理的历史记录。

从新小部件发出的信号例如:

  • “命令行中止”
  • “命令行命令”
  • ...

地位

已经为此编写了基础,但是在发出不止一个参数的信号时,我很纠结。

我有:

gtk_signal_emit(obj, sig, 0, command)
                                 |
                                 +---- string.

但想,(至少现在,很可能更多/其他。):

gtk_signal_emit(obj, sig, 0, command, length)

gtk_emit_signal错字已修复。感谢jku。. 另外,现在使用g_signal_


在小部件代码中:

static void
cmdline_class_init(CmdlineClass *klass)
{

有一个论点,我使用g_signal_new()作为:

cmdline_signals[CMDLINE_CMD] = g_signal_new(
                "cmdline-cmd",
                G_TYPE_FROM_CLASS(klass),
                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                G_STRUCT_OFFSET(CmdlineClass, cmdline),
                NULL,
                NULL,
                g_cclosure_marshal_VOID__VOID,
                G_TYPE_NONE,
                1,
                G_TYPE_STRING
);

正如我所看到的,对于两个论点,应该将其更改为:

cmdline_signals[CMDLINE_CMD] = g_signal_new(
                "cmdline-cmd",
                G_TYPE_FROM_CLASS(klass),
                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                G_STRUCT_OFFSET(CmdlineClass, cmdline),
                NULL,
                NULL,
                g_cclosure_user_marshal_VOID__STRING_INT,
                G_TYPE_NONE,
                2,
                G_TYPE_STRING,
                G_TYPE_INT
);

花园里的麻烦

使用glib-genmarshal生成带有 marshal.list 的编组:

VOID:STRING,INT

这有效,但在编译时给了我一个警告:

警告:ISO C 禁止将对象指针转换为函数指针类型

由 glib-genmarshal 生成的这段代码引起的:

  typedef void (*GMarshalFunc_VOID__STRING_INT) (gpointer     data1,
                                                 gpointer     arg_1,
                                                 gint         arg_2,
                                                 gpointer     data2);

  register GMarshalFunc_VOID__STRING_INT callback;

  /* GCC Warnig: conversion of object pointer to function => */
  callback = (GMarshalFunc_VOID__STRING_INT) ( 
                    marshal_data ? 
                    marshal_data : 
                    cc->callback
  );

问题

这是错误的方法吗?有没有办法修复转换错误?等等。

注意:我对 Gtk 和一般的 Gui 编程相当陌生。


侧点

有一些弃用我也想知道是否会影响代码/应该避免:

4

1 回答 1

2

This warning does appear (with -pedantic) on some signal marshalling code, and not just in your code. As far as I can see you are not doing anything wrong though -- except for using gtk_signal_emit() (I assume you meant that and not gtk_emit_signal() which does not exist as far as I know): you should not use any gtk_signal-prefixed code: that stuff is all deprecated. See the reference for details. Use GObject instead: g_signal_emit() or g_signal_emit_by_name() should work for you.

The signal marshaller deprecations you mention are about this same thing: GObject handles everything related to this now (and has for a long time already).

作为实用的建议:通常在信号签名中添加东西是不值得的,这可能也是你的情况:也许你的信号根本不需要命令字符串,信号处理程序可以用 your_object_get_command( )?

实用建议 #2:考虑将 GTK+ 3 用于新代码。没有所有过时的东西让每个人都感到困惑,这真是太可爱了。

于 2013-11-12T21:19:49.950 回答