1

我在将弹出菜单放置在 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,所以我只是将它转换(虽然不知道这是否正确)。

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

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

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

}

还必须将小部件转换为(guint),否则我会收到关于第 6 个参数的编译器错误:)

我可能最终会在这种方法中投入更多,但这是我让它工作所需的最低限度。

使用普通的 gtk_signal_connect 方法连接

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

其中 button 和 menu 是我之前使用的 GtkButton 和 GtkMenu 实例 :)

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

谢谢,希望这对某人有帮助:)

于 2012-08-01T12:43:14.880 回答