将小部件GTK下方的弹出菜单放置

时间:2012-08-01 09:53:18

标签: c button gtk popupmenu

我在GTK中将弹出菜单放在我想要的位置时遇到了一些问题(沿着与我的按钮相同的y轴,所以它似乎从按钮下拉)。

当我在win32中编写类似的东西时,我得到了它的工作但是对于我的生活,我不能把这个东西画到我想要的地方!

我完成了我的研究,我知道(我认为)应该起作用的,那就是我打电话的时候     gtk_menu_popup()

我应该将它传递给一个函数指针,该指针指向放置弹出窗口的方法(链接到方法规范 - http://developer.gnome.org/gtk/2.24/GtkMenu.html#GtkMenuPositionFunc

但是我对函数指针有点垃圾(我说话的时候我旁边有Kernighan和ritchie书)但是我很确定我做得对。

继承我对该方法的尝试:

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,所以我只是投了它(虽然不知道那是不是)。

问题是我不认为我的方法被调用,因为它从来没有打印出帮助:(加上它仍会在我点击的任何地方产生菜单(可能是因为它没有调用方法或它应该做的任何事情)。 / p>

任何帮助/想法都将受到极大的欢迎:)谢谢:)

2 个答案:

答案 0 :(得分: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());
}

答案 1 :(得分:2)

好的,非常感谢Pfeiffer的示例代码。我不得不对它进行一些更改,因为我遇到了编译错误(虽然我有Werror)。

在set poisition方法中,我最终投射到GTK_WIDGET而不是GTK_BUTTON因为它的预期

所以我的新设定位置方法如下:

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


}

由于我无法弄清楚如何连接和传递Pfeiffer传递的两个小部件,我现在有这个:

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;

}

还必须将widget转换为(guint)否则我得到关于第6个参数的编译错误:)

我可能会在这种方法中投入更多,但这是我需要的最低限度。

使用普通的gtk_signal_connect方法连接

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

其中按钮和菜单是我之前使用的GtkButton和GtkMenu实例:)

完全归功于Pfeiffer的答案,我只是展示了对我有用的东西:)

谢谢并希望这有助于某人:)