GtkWidgetの配列に格納されているラベルのフォント色を変更するコールバックを作成する必要があります。GtkWidgetの配列の要素をコールバックで変更する方法
GtkWidget *cells[CELLS];
for (int i=0; i<CELLS; i++) {
cells[i] = gtk_label_new("██");
}
ボタンに
接続されたコールバック:
g_signal_connect(
G_OBJECT(button),
"clicked",
G_CALLBACK(encode),
make_data(plaintext, key, cells)
);
make_data()
コードでは、現在の状態は、私の配列は、次のようになりますインターフェイスを初期化する関数では、ここでhttps://github.com/dustynine/colta-gtk/blob/struct/src/main.c
ありますコールバックの引数を持つ構造体を返す関数です:
struct passed_widgets {
GtkWidget *plaintext;
GtkWidget *key;
GtkWidget **cls;
};
gpointer make_data(GtkWidget *text, GtkWidget *key, GtkWidget *cells[CELLS]) {
static struct passed_widgets pw;
pw.plaintext = text;
pw.key = key;
pw.cls = cells;
return (gpointer) &pw;
}
そして0コールバック自体の内部I持っているこの:
static void encode(GtkButton *button, gpointer *data) {
struct passed_widgets *pw;
GdkColor color;
pw = (struct passed_widgets *) data;
gdk_color_parse("#07d9d9", &color);
gtk_widget_modify_fg(GTK_WIDGET(pw -> cls[0]), GTK_STATE_NORMAL, &color);
}
コンパイラが、私は実際にボタンを押すとGtkのは、この報告(色関連のものが推奨されていません警告は別として)文句はありません。
(colta-gtk:3993): GLib-GObject-WARNING **: invalid uninstantiatable type 'GInterface' in cast to 'GtkWidget'
(colta-gtk:3993): Gtk-CRITICAL **: gtk_widget_modify_fg: assertion 'GTK_IS_WIDGET (widget)' failed
Iは少しのためにGDBの中を拾い、explore pw -> cls[0]
に従って:
'pw -> cls[0]' is a pointer to a value of type 'GtkWidget'
この作業を意図どおりに行うにはどうすればよいですか?私は間違って構造体に配列を割り当てるか(これはプログラムが働く唯一の方法です)、またはコールバックの終わりにそれを変更しようとしているときに間違ってアクセスしている疑いがあります。
EDIT: liberforceが示唆したように、私はプログラムを書き直しました。
struct template {
GtkWidget *window;
...
GtkWidget *plaintext;
GtkWidget *cells[CELLS];
};
今、私はちょうど私がコールバックするgui
としてインスタンスこの構造体の渡し:
g_signal_connect(
G_OBJECT(gui.button),
"clicked",
G_CALLBACK(encode),
&gui
);
をしかし、私はエンコード()関数内で動作するように何かを得ることができない私のGUIのための構造体を作成しましたもう一度:
static void encode(GtkButton *button, gpointer data) {
gchar *plaintext;
struct template *pw;
pw = (struct template *) data;
plaintext = gtk_entry_get_text(GTK_ENTRY(pw -> plaintext));
printf(" plaintext contents: %s\n", plaintext);
もう一度私は何が間違っているのか分かりません。コンパイラは型が一致GDBによると、何の警告を与えていないが、私はプログラムを実行して、コールバックを使用する場合には、その私を与える:次のように
(colta-gtk:21589): Gtk-CRITICAL **: gtk_entry_get_buffer: assertion 'GTK_IS_ENTRY (entry)' failed
(colta-gtk:21589): Gtk-CRITICAL **: gtk_entry_buffer_get_text: assertion 'GTK_IS_ENTRY_BUFFER (buffer)' failed
アドレスは次のとおりです。
gui.plaintext address: 0x55babcfc6290
gui address: 0x7ffd13fe8a88
&gui address: 0x7ffd13fe8910
data address: 0x7ffd13fe8910
pw address: 0x7ffd13fe8910
*pw address: 0x7ffd13fe8a88
pw -> plaintext address: (nil)
*pw -> plaintext
セグメンテーションエラーが発生する
あなたがGtkApplicationを使っていたことはわかりませんでした。 'activate'シグナルに接続するときにスタックの割り当ては、あなたの構造体のアドレスを' user_data'として渡すと、メインで動作します。あるいは、静的と宣言することもできますが、コールバックハンドラでは行いません。ファイルの一番上で行います。ファイルにグローバルなオブジェクトが表示されるようにします。 'g_new'でヒープ上に構造体を作成することもできます。重要なことは、あなたのgui構造体はアプリケーションと同じ寿命を持たなければならないということです。 – liberforce
これは、コールバック内のスタックに構造体を宣言すると、コールバックを終了するときに構造体が破棄されることを意味します。 – liberforce
ところで、実際のビルドシステムに切り替えることもしよう。たとえば、ビルドスクリプトは私のためにはうまくいきませんでした。なぜなら私は 'bash'を持っているが' sh'は持っていないからです。 Mesonビルドシステムは、GTK/GNOMEプロジェクト用に推奨されるビルドシステムです:http://mesonbuild.com/。例えば、Mesonは '-Wall'を有効にして、合理的な警告セットを有効にしました(そして、それを常に最低限使用しなければなりません)。現代のGTK +/Cアプリケーションを書く上でベストプラクティスに追いつこうとしているhttps://github.com/liberforce/metrognomeで私のレポを見たいかもしれません。 – liberforce