1

環境

ウィジェットを使用してユーザーからのテキスト コマンドを処理する単純なアプリケーションを作成した後、GtkEntryいくつかの設計変更を行いたいと考えています。

現在、キープレスでシグナルフックを使用しています。キーが指定された値の場合、コマンド ラインを表示し、entryウィジェットでさまざまなアクションを処理します。例のように

  • Ctrl+ a: カーソルを入力の先頭に移動します。
  • Ctrl+ u: カーソルの前のテキストを削除します。
  • ...

コマンドの解析と履歴の保存/読み込みだけでなく。

これがどのように縫い合わされているかに満足していません。コマンドの解析は、次のサブセットになります。

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

私が見たように、1 つの良いアプローチは、GtkEntry をベースとして使用して新しいウィジェットを作成し、コマンド enterでシグナルを送信することです。Ctrl+... などのすべての内部と、新しいウィジェットによって処理される履歴。

新しいウィジェットから発信されるシグナルは次のとおりです。

  • 「コマンドライン中止」
  • 「cmdline-cmd」
  • ...

状態

これのベースを書きましたが、複数の引数でシグナルを発行することになると、私は立ち往生しています。

私は持っている:

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)
{

1 つの引数で、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
);

そして、私が見ているように、2つの引数の場合、次のように変更する必要があります:

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プログラミング全般にかなり慣れていません。


サイドポイント

コードに影響を与える可能性があるかどうかも疑問に思う/避けるべきいくつかの廃止予定があります:

  • GtkSignalMarshaller、これは のステータスについて何かを示していますGSignalCMarshallerか?
  • GtkCallbackMarshal、これは一般的なマーシャラーの使用について何かを示していますか?
4

1 に答える 1

2

この警告は、コードだけでなく、一部のシグナル マーシャリング コードで (-pedantic を使用して) 表示されます。私が見る限り、あなたは何も悪いことをしていません - 使用を除いてgtk_signal_emit()(私が知る限り存在しない gtk_emit_signal() ではなく、それを意味していると思います): gtk_signal プレフィックスコードを使用しないでください:そのようなものはすべて非推奨です。詳細はリファレンスを参照してください。代わりにGObjectを使用してください:g_signal_emit()またはg_signal_emit_by_name()あなたのために働くはずです。

あなたが言及したシグナルマーシャラーの非推奨は、これと同じことです.GObjectは、これに関連するすべてを現在処理しています(そして、すでに長い間処理しています)。

実用的なアドバイスとして: シグナル署名に何かを追加することはしばしば問題に値しません。これはあなたにも当てはまるかもしれません: あなたのシグナルはコマンド文字列をまったく必要とせず、シグナルハンドラーは your_object_get_command( )?

実用的なアドバイス #2: 新しいコードには GTK+ 3 の使用を検討してください。誰もが混乱するような廃止されたものをすべて持たないことは、ただ素敵なことです.

于 2013-11-12T21:19:49.950 に答える