当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 6 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2009-08-11 0:28 

注册: 2009-08-10 23:38
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
Glade3不再能生成C或C++或其他什么代码了,现在改为使用libglade在程序运行时加载并解析glade文件中的XML文档来生成界面了,这种做法倒是更符合界面设计同程序设计分离的理念,事实上当界面稍复杂一点后,在面对Glade2生成的一大堆C代码时也是比较头痛的事情,个人认为Glade3的模式应该更合理一些。
不过目前Glade3似乎在C上有BUG,别的语言没试过(主要是除了C不懂别的了 :em04 ),在Glade3的属性面板里定义的信号处理函数无法接收到正确的参数,具体表现为:
如果在Glade3中定义了处理函数:
void on_button1_clicked (GtkButton *self, gpointer user_data)
则实际运行中self = NULL, user_data = self
对此我的解决是。。。。,还是看代码算了 :em06

void on_button1_clicked (GtkButton *self, gpointer user_data);

// 准备传递的user_data数据结构
static struct U_Data {
int mal;
char str[100];
} button1_user_data = {0, "应用程序数据在此"};

// 定义一个简短的调用缩写,使用一个信号连接可在一行内写完,以便构建表格式连接代码块!写成宏也可,但是用函数可使编译器能更准确的定位语法错误
// SGC这个名字可能有些欠考虑,感觉和某些系统中定义的常量相近但含义相远吧
inline void SGC(GladeXML *gxml, const char *widget_name, const char *signal, void *func, gpointer user_date) {
g_signal_connect(
GTK_OBJECT(glade_xml_get_widget(gxml, widget_name)),
signal,
GTK_SIGNAL_FUNC(func),
user_date);
}

GtkWidget* create_window (void) {
GtkWidget *window;
GladeXML *gxml;

gxml = glade_xml_new (GLADE_FILE, NULL, NULL);

/* This is important */
glade_xml_signal_autoconnect (gxml);
window = glade_xml_get_widget (gxml, "window");

// 连接需要使用self, user_data的函数,因为目前Glade无法正确处理他们
SGC(gxml, "button1", "clicked", on_button1_clicked, &button1_user_data);
/* 如果不用SGC宏(函数)则以上调用将不适合写在一行内(见下),写在一行会很长,不便阅读。当然一个窗口中要连接的这种信号较多时
简单的写法应该会更易阅读和对大量信号连接的集中维护。
gtk_signal_connect(
GTK_OBJECT(glade_xml_get_widget(gxml, "button1")),
"clicked",
GTK_SIGNAL_FUNC(on_button1_clicked),
&button1_user_data);
*/

return window;
}

int main (int argc, char *argv[]) {
GtkWidget *window;

puts(argv[0]);

#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
#endif

gtk_set_locale ();
gtk_init (&argc, &argv);

window = create_window ();
gtk_widget_show (window);

gtk_main ();
return 0;
}

void on_button1_clicked (GtkButton *self, gpointer user_data) {
struct U_Data* data = (struct U_Data *)user_data;
data->mal ++;
printf("Button click (%d),信息:%s\n", data->mal, data->str);
}
以上做法经试验可行,不过这属于穿Glade3这个新鞋走老路的干法。不知道大家在解决这个问题时有何更好的办法,欢迎共同探讨(砖头是丢出去了,大家给来点玉吧)。
至于不用Glade3而继续用Glade2这个办法就请不要说了 :em20,如果谁有解决Glade3中这个BUG的补丁就更好了,请发个上来大家共享下吧 :em02


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2009-08-11 5:41 
头像

注册: 2007-12-16 0:45
帖子: 275
送出感谢: 0 次
接收感谢: 0 次
我真没这个问题阿,glade3,2都是好的。难道运行时没抛出错误或警告?

你那个SGC没必要吧,在glade中将信号设置上,然后 glade_xml_signal_connect[_data] 这两个函数连接一下就可以了阿。而且我看你用了autoconnect的,那么只要函数名和信号一样都不用手动去连接了


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2009-08-11 9:25 

注册: 2009-08-10 23:38
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
qingshi163 写道:
我真没这个问题阿,glade3,2都是好的。难道运行时没抛出错误或警告?

你那个SGC没必要吧,在glade中将信号设置上,然后 glade_xml_signal_connect[_data] 这两个函数连接一下就可以了阿。而且我看你用了autoconnect的,那么只要函数名和信号一样都不用手动去连接了


在glade中设置信号,同时设置了用户数据后,运行时self和user_data就是不正常,运行也没有出现错误或警告,实际上如果不在信号处理中用断点停下来观察的话,后面使用user_data的代码将会出现段错误导致程序终止,因为这时user_data实际上的值是self的值,而self=NULL,也就是说autoconnect虽然建立了处理函数的连接,即在运行时确能根据信号去调用设定的处理函数,但是在参数的传递上确有问题,是不是我在glade中设置的方式不对呢?在glade的属性面板中设置要传给函数的数据如上面的代码中的button1_user_data时应该如果填写请再帮看看.使用手动连接实为无奈之举,如果在glade中能解决我认为不应该在程序中再用手动连接,除非是有些处理需根据程序运行来动态改变处理函数的情况。
用SGC宏的主要是为了简化一点代码的长度,毕竟手动连接的话要连接的函数会较多,能把每个连接都写的一行内还是有些好处的(实际上也可不用,这只是个各人代码风格的问题),只是上面SGC的内部用的是g_signal_connect的确不如用glade_xml_signal_connect_data好。
能不能发一下你在glade设置了user_data后能正常接收user_data的glade文件中的相应代码片段和程序中的对应片段,以便我对比一下和我的glade文件中的差别,现在看来我的glade中的设置可能是有问题的,毕竟glade的中文文档目前好象没有,我的英文相当于现在的小学水平 :em06 ,无奈。


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2009-12-07 23:42 

注册: 2008-05-03 16:43
帖子: 141
送出感谢: 0 次
接收感谢: 0 次
schun 写道:
qingshi163 写道:
我真没这个问题阿,glade3,2都是好的。难道运行时没抛出错误或警告?

你那个SGC没必要吧,在glade中将信号设置上,然后 glade_xml_signal_connect[_data] 这两个函数连接一下就可以了阿。而且我看你用了autoconnect的,那么只要函数名和信号一样都不用手动去连接了


在glade中设置信号,同时设置了用户数据后,运行时self和user_data就是不正常,运行也没有出现错误或警告,实际上如果不在信号处理中用断点停下来观察的话,后面使用user_data的代码将会出现段错误导致程序终止,因为这时user_data实际上的值是self的值,而self=NULL,也就是说autoconnect虽然建立了处理函数的连接,即在运行时确能根据信号去调用设定的处理函数,但是在参数的传递上确有问题,是不是我在glade中设置的方式不对呢?在glade的属性面板中设置要传给函数的数据如上面的代码中的button1_user_data时应该如果填写请再帮看看.使用手动连接实为无奈之举,如果在glade中能解决我认为不应该在程序中再用手动连接,除非是有些处理需根据程序运行来动态改变处理函数的情况。
用SGC宏的主要是为了简化一点代码的长度,毕竟手动连接的话要连接的函数会较多,能把每个连接都写的一行内还是有些好处的(实际上也可不用,这只是个各人代码风格的问题),只是上面SGC的内部用的是g_signal_connect的确不如用glade_xml_signal_connect_data好。
能不能发一下你在glade设置了user_data后能正常接收user_data的glade文件中的相应代码片段和程序中的对应片段,以便我对比一下和我的glade文件中的差别,现在看来我的glade中的设置可能是有问题的,毕竟glade的中文文档目前好象没有,我的英文相当于现在的小学水平 :em06 ,无奈。

这个问题确实存在,我使用gtk_builder来解析的Glade生成的xml,选择的格式就是默认的GtkBuilder而不是libGlade。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2010-03-25 9:58 

注册: 2009-03-27 14:34
帖子: 48
送出感谢: 0 次
接收感谢: 0 次
因为gtkbuilder一旦在xml里指定用户数据,就会使用g_signal_connect_swap()的方式来连接,所以交换了参数的顺序!


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 和大家探讨一下Glade3生成的界面在C里无法正确使用user_data问题的解决方法
帖子发表于 : 2012-02-22 22:19 

注册: 2011-12-10 18:11
帖子: 7
送出感谢: 0 次
接收感谢: 0 次
how to build a c code?


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 6 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 3 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译