1

GTKの目的の場所にポップアップメニューを配置するのに問題があります(ボタンと同じy軸に沿っているため、ボタンからドロップダウンしているように見えます)。

私はwin32で同様のものをコーディングしていたときにそれを機能させましたが、私の人生の間、私はこのものを私が望む場所に描くことができません!

私は調査を行い、(私が思うに)何が機能するかを知っています。それがgtk_menu_popup()を呼び出すときです。

ポップアップを配置するためのメソッドへの関数ポインターでそれを渡す必要があります(メソッド仕様へのリンク-http://developer.gnome.org/gtk/2.24/GtkMenu.html#GtkMenuPositionFunc

しかし、私は関数ポインターで少しごちゃごちゃしています(私が話すとき、私はカーニハンとリッチーの本を横に持っています)が、私はそれを正しくやっていると確信しています。

これが私の試みです:

void set_position(GtkMenu *menu,gint *x,gint *y,gboolean push_in,gpointer user_data)
{
 printf("Help!\n";
 GtkWidget *originButton = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(menu),"button");
 gdk_window_get_position(originButton->window,x,y);
 //now I realise this will place it at the top of the widget but thats acceptable for now, I just want the method to be called!
}

私はこれを行うことによってボタンハンドラーからそれを呼び出します:

static gboolean handler (GtkWidget *widget,GdkEvent *event)
{
 GdkEventButton *bevent = (GdkEventButton *) event;
 gtk_menu_popup(GTK_MENU(widget),NULL,NULL,set_position,bevent->button,bevent->button,bevent->time);
}

しかし、これをコンパイルすると、GtkMenuPositionFuncではないと表示されるので、キャストするだけです(それが正しいかどうかはわかりません)。

問題は、ヘルプが出力されないため、メソッドが呼び出されているとは思わないことです:(さらに、クリックした場所でメニューが生成されます(おそらく、メソッドが呼び出されないため、またはメソッドが実行する必要があるため)。

どんな助け/アイデアも大いに受け取られるでしょう:)ありがとう:)

4

2 に答える 2

2

私は以前に同じ問題を抱えていました。次のコードを使用しました。

static void
set_position(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data)
{
  GtkWidget *button = GTK_BUTTON(user_data);

  gdk_window_get_origin(button->window, x, y);
  *x += button->allocation.x;
  *y += (button->allocation.y + (button->allocation.height));
}

static void
handler(GtkWidget *menu, GtkWidget *button)
{
  GtkRequisition requisition;

  gtk_widget_size_request(menu, &requisition);
  if (button->allocation.width > requisition.width)
    gtk_widget_set_size_request(menu, button->allocation.width, -1);

  gtk_menu_popup(GTK_MENU (menu),
                 NULL, NULL,
                 (GtkMenuPositionFunc) set_position, button,
                 0, gtk_get_current_event_time());
}
于 2012-08-01T11:32:39.810 に答える
2

さて、彼のサンプルコードを提供してくれたPfeifferに感謝します。コンパイラエラーが発生したため、いくつか変更を加える必要がありました(ただし、Werrorがオンになっています)。

set poisitionメソッドでは、GTK_BUTTONではなくGTK_WIDGETにキャストすることになりました。これは、それが期待していたためです。

したがって、私の新しいセット位置メソッドは次のようになりました。

static void set_position(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) {

  GtkWidget *button = GTK_WIDGET(user_data);

  gdk_window_get_origin(button->window, x, y);
  *x += button->allocation.x;
  *y += (button->allocation.y + (button->allocation.height));


}

そして、ファイファーが渡していた2つのウィジェットを接続して渡す方法がわからなかったので、現在これを持っています:

static gboolean handler(GtkWidget *widget, gpointer data) {

  gtk_menu_popup(GTK_MENU(data), NULL, NULL,(GtkMenuPositionFunc)set_position,widget,(guint)widget, gtk_get_current_event_time());

  return TRUE;

}

また、ウィジェットを(guint)にキャストする必要がありました。そうしないと、6番目のパラメーターに関するコンパイラエラーが発生しました:)

私はおそらくこの方法にもっと多くを入れることになるでしょうが、これは私がそれを機能させるために必要な最低限のものです。

これは通常のgtk_signal_connectメソッドを使用して接続されます

    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(handler), GTK_OBJECT(menu));

ここで、ボタンとメニューは、以前使用していたGtkButtonインスタンスとGtkMenuインスタンスです:)

完全なクレジットは答えのためにファイファーに行きます、私はちょうど私のために働いたものを示しています:)

ありがとう、そしてこれが誰かを助けることを願っています:)

于 2012-08-01T12:43:14.880 に答える