[Linux可视化编程系列三] 体验Glade的可视化界面设计

C、C++和Java语言
头像
tipfoo
帖子: 303
注册时间: 2007-07-12 16:30
来自: 桂林
送出感谢: 0
接收感谢: 2 次

[Linux可视化编程系列三] 体验Glade的可视化界面设计

#1

帖子 tipfoo » 2007-11-22 16:53

09年三月,Qt 4.5 采用 LGPL 授权了,几乎没有理由再用 Gtkmm :em06

───────────────────────────────────────────
[Linux可视化编程系列快速导航]
一、用 Anjuta 轻松搭建 Gtkmm+libglademm 开发环境
二、掀起 Gtkmm + libglademm 的盖头来
三、体验Glade的可视化界面设计
───────────────────────────────────────────

前面的两篇文章:《用 Anjuta 轻松搭建 Gtkmm+libglademm 开发环境》《掀起 Gtkmm + libglademm 的盖头来》,已经为我们能够做出一个有用的gtkmm程序作好了铺垫。

接下来,我们马上就要编写这样的一个程序,它能接收输入的用户名字,然后显示适当的问候语。对它稍作修改就能用于IP物理地址的查询界面。


用Glade进行可视化窗体设计
────────────────────────────────────
首先,让我们编辑Glade文件。请参照 anjuta_using_glade.htm 这个视频进行操作,它将整个操作过程演示了一遍。与演示视频中稍有不同,在依次将Layout、Lable、Entry和Button这几个控件添加到主窗口(main_window)之后,请照这个样子设置后面三个控件的名称,它们分别为“lable_msg”、“entry_name”和“button_sayhello”。
注:视频末尾所留的 MSN 已停止使用,请不要再通过它联系我!
。。。Hotmail 网页接口太慢,对 Firefox 太不友善。


保存Glade文件后,视频中所用到的源码在下面,或从附件中下载。


让程序和用户进行互动
────────────────────────────────────
为了响应用户的操作,需要添加一些必要的程序代码。请用下面的代码将上一篇中的代码替换掉。介于“//v2++++++”和“//v2------”之间的代码就是新加入的。我们照例还是在源码中间穿插注释的方式,对它们进行分析理解。

文件“main.cc”

代码: 全选

#include "hello-app.hpp"

int
main (int argc, char *argv[])
{
   HelloApp app(argc, argv);
   
   app.show_window();
   
   return 0;
}

文件“hello-app.hpp”

代码: 全选

#ifndef _HELLO_APP_HPP_
#define _HELLO_APP_HPP_

#include <gtkmm.h>
#include <libglademm/xml.h>
//v2+++++++++++++++
#include <libglademm/variablesmap.h>   /* 连接控件与变量 */
#include <sigc++/functors/slot.h>         /* 信号槽 */
//v2---------------


class HelloApp: public Gtk::Main
{
public:
   HelloApp(int argc, char *argv[]);
   ~HelloApp();
   
   void show_window();
   
protected:
   Glib::RefPtr<Gnome::Glade::Xml> ref_xml;
   
   Gtk::Window* main_window;
//v2+++++++++++++++
   Gtk::Button* button_sayhello;               /* 按钮控件指针 */
   Gtk::Label* label_msg;                           /* 显示问候的标签控件指针 */
   
   /*
   由于VariablesMap无法被定义成Glib智能指针,于是我们就
   定义一个VariablesMap的标准库的智能指针(下面这句相当于
   “Gnome::Glade::VariablesMap* var_map”,只是不用再
   “delete var_map;”来释放内存了,它会自动释放)。
   
   通过它,我们能连接控件与变量,进行数据的交换。
   */
   std::auto_ptr<Gnome::Glade::VariablesMap> var_map;
   
   Glib::ustring str_name;                        /* 获取输入的变量 */
   
   void on_button_sayhello_clicked();   /* 响应按钮点击事件的处理函数 */
//v2---------------
};

#endif // _HELLO_APP_HPP_

文件“hello-app.cpp”

代码: 全选

/* tipfoo<tipfoo@gmail#com> 原创作品,版权所有,出处: http://blog.csdn.net/tipfoo/  */ 
#include "hello-app.hpp"

#include <iostream>
#include <assert.h>

using namespace Gnome::Glade;


HelloApp::HelloApp(int argc, char *argv[]):
   Gtk::Main(argc,argv),
   main_window(0)
{
   try
   {
      ref_xml = Xml::create("helloapp.glade");
   }
   catch(const XmlError& ex)
   {
      std::cerr << ex.what() << std::endl;
      return;
   }
   
   ref_xml->get_widget("main_window", main_window);
   assert(main_window);
   
//v2+++++++++++++++
   /* 取得标签控件的指针,后面用它来设置输出信息 */
   ref_xml->get_widget("lable_msg", label_msg);
   assert(label_msg);
   
   /*
   将响应"button_sayhello"按钮的点击事件的处理函数连接到
   “HelloApp::on_button_sayhello_clicked”函数。
   
   connect_clicked() 函数的第二参数需要一个信号槽;而
   sigc::mem_fun()在运行时、动态地返回一个信号槽。其中:
   第一个参数是信号槽要操作的类对象实例,在此就是本类的实例;
   第二个参数是响应函数的指针,要用全局限定符。
   
   参考(需要安装libsigc++-2.0-doc包):
   浏览器打开“   /usr/share/doc/libsigc++-2.0-doc/docs/index.html”
   点击“Groups”下的“Functors”。
   */
   ref_xml->connect_clicked("button_sayhello",
         sigc::mem_fun(*this, &HelloApp::on_button_sayhello_clicked));
   
   /*
   通过ref_xml构建一个VariablesMap实例,并保存其指针于var_map。
   然后,我们通过var_map,连接控件与变量,之后就能进行数据的交换了。
   */
   var_map = std::auto_ptr<VariablesMap> (new VariablesMap(ref_xml));
   var_map->connect_widget("entry_name", str_name);
//v2---------------
}


HelloApp::~HelloApp()
{
}


void HelloApp::show_window()
{
   if (main_window) {
      run( *main_window );
   }
}


//v2+++++++++++++++
/* 按钮"button_sayhello"的点击事件的处理函数 */
void HelloApp::on_button_sayhello_clicked()
{
   /*
   进行数据的交换,将所有控件的数据传入变量中。
   这时输入到文本框中的内容就存入“str_name”变量中了。
   */
   var_map->transfer_widgets_to_variables();
   /* 支持Unicode的字符串对象 */
   Glib::ustring msg = "Hello, " + str_name + "!";
   /* 设置输出信息 */
   label_msg->set_text(msg);
}
//v2---------------


保存更改后,按SHIFT+F11编译并生成执行文件,再按F3就能运行了。
(tipfoo 原创作品,转载请注明出处: http://blog.csdn.net/tipfoo/ ,商业用途请联系作者<tipfoo@gmail#com>,未经授权,不得使用。)

Glade 插件问题
────────────────────────────────────
问题1:我们看到演示中窗口标题改成了“Hello Gtkmm!”但显示的还是“Hello World!”。
解决:这是Glade插件的Bug,改完标题后,要将鼠标点击其它地方(就是使输入焦点离开标题内容框),然后再保存Glade文件。记得刷新。

问题2:双击Glade 文件不显示窗口控件,而是一片空白。
如果一个 Glade 文件已打开的话,在文件管理器(或工程管理器)中,双击这个 Glade 文件再次打开它;然后,双击“Widgets”管理器中的主窗体部件(通常是“main_window”)却看不到窗体,在Designer中将显示空白。

这种情况也经常发生在重新打开工程时。由于在关闭工程时,Glade 文件通常是保持打开的。重新打开工程时,Glade 文件将自动被打开。但在Designer中不显示窗体,而是空白,要双击“Widgets”管理器中的主窗体组件(通常是“main_window”)才能看到。此时,很容易误认为,glade 文件没有打开,而出现上面的情况。

解决:重复点击菜单“Glad”→“关闭”,直到看不到“Glad”菜单项;在左侧面板的文件管理器中,双击 Glade 文件打开它(就是 helloapp/src/helloapp.glade 文件);再双击“Widgets”管理器中的主窗体部件(名为 main_window)即可。点这里到6楼查看图解


一点技巧
────────────────────────────────────
如何移动控件或更改控件大小
在Glade设计器中,移动控件或更改控件大小需要同时按住SHIFT键。

直观准确地设置窗口的大小
由于Label或Image控件是透明的,用它们来测量出主窗口需要的尺寸就比较直观。
步骤:
1. 在左侧Palette面板中选择Label,在设计(Designer)视图的窗口中单击放置它;
2. 按住SHIFT键、并用鼠标拖动这个Label控件到窗口的左上角,使其水平和垂直坐标均为0(这个可在Properties的“打包”选项页中确认它的值);
3. 之后按住SHIFT键、并用鼠标拖动这个Label控件的右下角,调整到主窗口所需的大小;
4. 在Properties的“公共”选项页中,“宽度请求”和“高度请求”就是我们所要的数值。
5. 设置主窗口的“常规”选项页中的“默认宽度”值为上面的“宽度请求”,“默认高度”值为上面的“高度请求”。
附件
f1ip-dict.png
基于本例的IP物理地址查询工具,使用纯真数据库新版(ipwry.dat)。从win的dll移植而来。
f1ip-dict.png (10.13 KiB) 查看 11732 次
hello.gtkmm.src.tar.gz
源码和Glade文件
(2.47 KiB) 下载 389 次
上次由 tipfoo 在 2009-05-29 21:16,总共编辑 6 次。
头像
wptskybzy
帖子: 108
注册时间: 2007-10-24 15:32
来自: 四川省南充市
送出感谢: 1 次
接收感谢: 0
联系:

#2

帖子 wptskybzy » 2007-11-24 20:37

大哥……一定要继续发下去啊!!这种好的教程真的很少有哦!!加油!!
头像
wptskybzy
帖子: 108
注册时间: 2007-10-24 15:32
来自: 四川省南充市
送出感谢: 1 次
接收感谢: 0
联系:

#3

帖子 wptskybzy » 2007-11-24 20:43

这种好贴居然没有人顶……我沙发~
yangjiajiang
帖子: 10
注册时间: 2005-12-30 14:41
送出感谢: 0
接收感谢: 0
联系:

#4

帖子 yangjiajiang » 2007-11-24 21:23

是学gtk+ 还是gtkmm好呢?

楼主出这么好的教程,那我就先学gtkmm吧。

:lol: :P :evil: :twisted:
头像
blackiron
帖子: 887
注册时间: 2007-05-25 16:47
来自: 上海
送出感谢: 0
接收感谢: 0

#5

帖子 blackiron » 2007-11-25 0:12

你老兄的帖子,一定要顶
头像
tipfoo
帖子: 303
注册时间: 2007-07-12 16:30
来自: 桂林
送出感谢: 0
接收感谢: 2 次

#6

帖子 tipfoo » 2007-11-25 9:42

感动啊,多谢各位支持!!!

在这补个图。。。

图解:解决Glade插件显示空白页的问题
附件
g5.jpg
图g5
g4.jpg
图g4
g3.jpg
图g3
g2.jpg
图g2
g1.jpg
图g1
上次由 tipfoo 在 2007-11-27 21:23,总共编辑 2 次。
头像
wptskybzy
帖子: 108
注册时间: 2007-10-24 15:32
来自: 四川省南充市
送出感谢: 1 次
接收感谢: 0
联系:

#7

帖子 wptskybzy » 2007-11-25 10:19

大哥,我的anjuta一打开*.glade文件就自动关闭,而且创建glade工程也自动关闭,这是怎么回事啊?我用的是ubuntu 7.10 amd64,从源里面安装的anjuta 2.20
头像
tipfoo
帖子: 303
注册时间: 2007-07-12 16:30
来自: 桂林
送出感谢: 0
接收感谢: 2 次

#8

帖子 tipfoo » 2007-11-25 12:46

都说 ubuntu 7.10 不稳定啊!
我还是用的 7.04。
头像
windwiny
帖子: 2254
注册时间: 2007-03-13 17:26
送出感谢: 0
接收感谢: 1 次

#9

帖子 windwiny » 2007-11-25 13:52

支持
头像
tipfoo
帖子: 303
注册时间: 2007-07-12 16:30
来自: 桂林
送出感谢: 0
接收感谢: 2 次

#10

帖子 tipfoo » 2007-11-26 15:15

基于这个例子,今天做出了一个“IP物理地址查询工具”,使用纯真数据库新版,数据文件ipwry.dat大小是3.9MB,原来的QQwry.dat是6.4MB。

IP查询部分是从win的dll移植而来,感谢原作者cnss!
图片
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

#11

帖子 eexpress » 2007-11-26 16:01

嗯。专门登记irc胡说的杂毛U字辈。竟然敢来bs gtkmm。上面这ip列入黑名单。
● 鸣学
头像
sevk
帖子: 2059
注册时间: 2007-05-08 16:26
系统: arch
来自: 火星内核某分子内某原子核内
送出感谢: 20 次
接收感谢: 6 次
联系:

#12

帖子 sevk » 2007-11-26 16:02

对,支持!
笔记本 :
F208S : gentoo
A460P i3G D6 : UBUNTU + WIN7
UN43D1 : UBUNTU + WIN7
1000人超级QQ群 LINUX + WIN : 31465544 或 18210387
头像
wptskybzy
帖子: 108
注册时间: 2007-10-24 15:32
来自: 四川省南充市
送出感谢: 1 次
接收感谢: 0
联系:

#13

帖子 wptskybzy » 2007-11-30 22:41

其实……这个教程对我们来说真的是不可多得的。我真心的希望楼主能够把这一系列继续下去。
头像
sevk
帖子: 2059
注册时间: 2007-05-08 16:26
系统: arch
来自: 火星内核某分子内某原子核内
送出感谢: 20 次
接收感谢: 6 次
联系:

#14

帖子 sevk » 2007-12-05 20:35

wptskybzy,你的图片能不能ZONE-OUT一下?
笔记本 :
F208S : gentoo
A460P i3G D6 : UBUNTU + WIN7
UN43D1 : UBUNTU + WIN7
1000人超级QQ群 LINUX + WIN : 31465544 或 18210387
头像
wptskybzy
帖子: 108
注册时间: 2007-10-24 15:32
来自: 四川省南充市
送出感谢: 1 次
接收感谢: 0
联系:

#15

帖子 wptskybzy » 2007-12-07 14:29

那个……啥叫ZONE-OUT?
回复

回到 “C/C++/Java”