我在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>
任何帮助/想法都将受到极大的欢迎:)谢谢:)
答案 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的答案,我只是展示了对我有用的东西:)
谢谢并希望这有助于某人:)