
使用 GTK+ 和 Glade 快速开发 Linux 图形界面
GTK+ 简介
基本概念
GTK+ 是一种用于创建图形界面的库 嗯, gnome 用的就是它, 不过并不是说只
有在 gnome 环境中才能用, 只要系统上装有 GTK 的库 (基本上有图形系统的个
人机都会有的啦) 就能运行基于 GTK 的程序 除了 UNIX-like 平台, 它还移植
到 windows 上, 还有面向嵌入设备的 framebuffer 版本等等
GTK 依赖两个重要的库 一个是 GLib, 这并不是一个图形库, 也和 glibc 不同
, 它大抵上提供了一些接口以屏蔽系统的不同, 比如 gint 在哪里都是 32bit
的, 等等; 另一个是 GDK, 它是一个设备无关的图形库, 支持基本的画点, 以及
与窗口管理器沟通等任务, 由于 GTK 被设计成能在各个平台, 而非仅仅在
XWindow 环境下使用, 所以这个库也是必要的 而在他们上面的 GTK 库, 就提
供了一些 widget --- 可以理解为控件啦, 不过窗口也是一个 widget 的说, 给
我们使用, 并提供了包装良好的事件响应机制
GTK+ 开发基础
要开发基于 GTK 的软件, 必须先安装 GTK+ 的开发包 检查是否正确安装的办
法是在安装后执行 ``pkg-config --cflags --libs gtk+-20'', 如果安装不正
确, 会提示找不到相应的包
GTK 本身是基于 C 的库, 当然也有 C++ 等语言的 wrap, 但它的整个体系是面
向对象的 其最基本的类是 GObject, GtkObject 继承了它, GtkObject 又派生
出我们最经常用到的 GtkWidget, 我们使用的所有窗体控件都派生于它 于是,
在 C 环境中我们就要手动处理这些类转换, GTK 和底层的 GLib 等提供了一种
统一的转换方法, 比如把类型为 GtkWidget 的 button 转换成 GtkButton 形,
写法是: GTK_BUTTON(button), 就酱子
我不打算在这里列一个 GTK 的 hello world 占页面, 这个程序随便 google 一
下就能找到 我们可以自己想一想一个图形界面应该如何建立
首先我们要进行初始化, GTK 提供了 gtk_init() 作为初始化, 它检查程序参数
中的一些特定部分, 进行自己的设置 调用方法如下:
gtk_init(&argc, &argv);
将 argc 和 argv 传指针的目的是 gtk_init 会对他们进行加工, 把 GTK 自己
用到的一些参数抽取出来
接着, 我们必须要创建这些控件吧, GTK 中, 创建一个控件会返回一个
GtkWidget 类型 (或它的派生类) 的指针, 所有创建控件的函数的格式是
gtk_控件类型_new(参数表) 比如创建一个窗口的写法是:
GtkWidget window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
然后, 我们要设定事件响应函数, GTK 中的事件叫做 signal GTK 的事件响应
函数接口应该是类似这样的
void
destroy(GtkWidget widget, gpointer data)
我们把它连入到一个控件中的方法是这样的
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
应该很好理解吧
我们创建的咚咚, 要说明他们的位置和包含关系, GTK 用 container 来解决这
个问题, 它可以保证在窗口缩放的时候控件的摆放依然合理, container 的具体
使用不详细说, 后面经常要跟 container 打交道, 但基本上不用管 C 代码, 嗯
不过其实我们的任何的可视控件都继承自 container, 比如 button 也是一个
container, 它很多时候装的是一个 GtkLabel, 也就是用来显示纯文本的控件,
于是我们就能见到一个文本按钮, 嗯 使用 container 的方法如下
gtk_container_add(GTK_CONTAINER(window), button);
这样 button 就会占满整个 window 的控件, 我们后面可以看到可以用
GtkVBox, GtkHBox 等 container 分隔窗体
好了, 我们可以准备启动程序了, 我们可以用 gtk_widget_show() 来显示各个
控件, 然后我们就应该进入到所谓的事件响应循环了, 这就要使用 gtk_main()
在程序运行过程中, 我们要 *** 纵控件, 比如说我们要在一个 entry 控件(文本框
) 中取出其中的文字, 这样的 *** 作使用 gtk_控件类型_动作(对象, 参数) 的形
式完成的, 比如刚才所说的任务, 做法是 gtk_entry_get_text(entry)
顺便讲讲 GTK 程序的退出, 关闭 GTK 的窗口 (即使是所有窗口) 也不代表程序
退出, 因为那说到底只是一个界面而已, 我们当然可以使用 exit() 的自爆法退
出, 但最好还是给 GTK 一个料理后事的机会, 在主窗口的 destroy 事件响应函
数上用 gtk_main_quit() 就好了
编译 GTK 程序的办法也很简单
gcc -o foo fooc `pkg-config --cflags --libs gtk+-20`
使用 Glade 快速定制用户界面
好了, 说了一堆有的没的, 如果我现在说我上面说的那一堆中的大部分我们都不
会用到, 是不是觉得偶很歉扁 前面的介绍只是给大家 GTK 这个库的一些基本
概念, 概念就好了, 我们倒真的不用拿这些来编程的 想想, 一个复杂一点的界
面, 十几个控件, 再加上各种各样的 container, 自己挂事件, 再加上超常的命
名, 想想都恐怖
这时候, Glade 横空出世了! 这是一个可视化的界面编辑器 --- 但它仅仅是一
个界面编辑器而已, 甚至连代码编辑框也没有给出 先不管了, 打开 glade (安
装省略, 饶了我把, 记得装 libglade-dev), 应该很好懂了, 指指点点就能弄好
一个界面, 然后在属性窗的信号一栏中选取需要的信号, 设定响应函数, 非常好
弄
玩了几分钟, 问题来了, 怎么把它变为程序啊 提供类似功能的 IDE 如
Borland C++ Builder, 在点击创建新控件的时候, 我们能即使在代码窗看到自
动生成的代码, Glade 也可以采用这种形式, 在设计好界面并保存后, 按一下主
窗口的 build 按钮, 它就自动生成了界面代码, 根本不用自己写的 打开代码
目录, callbacksc 里已经有自动创建的事件响应的空函数, 在里面填处理, 然
后 configure make 就行了
但是, 这样的开发方式还是有问题的 第一, 自动生成的代码非常复杂, 可是很
多时候我们还是不能完全不看它, 处理和界面是混在一起了, 理解他们变得困难
; 其二, 由于以上的原因, 修改界面变得非常痛苦; 其三, 它给你生成那堆有的
没的配置文件不一定是你想要的
因此 glade 提供了另一种方法, glade 编辑所得的 glade 文件是一个 XML 文
件, 其实它已经完整地描述了界面, 我们能否采用一种简单的方式直接载入, 配
置它呢 这样做, 我们的代码中就真真正正地去处了烦人的界面生成代码, 而专
注于处理部分了
libglade 正是由于这个而来, 它能很好地完成上面所说的工作 当我们用
glade 创建了一个 glade 界面后, 用这种方法我们就可以建立界面, 运行程序
了
#include <gtk/gtkh>
#include <glade/gladeh>
GladeXML GUI;
int
main(int argc, char argv)
{
gtk_init(&argc, &argv);
/ load the interface /
GUI = glade_xml_new("frameglade", NULL, NULL);
/ connect the signals in the interface /
glade_xml_signal_autoconnect(GUI);
/ start the event loop /
gtk_main();
return 0;
}
剩下的事情很简单, 如果你的 button 的 clicked 控件有一个响应函数
on_button_clicked, 你写
void
on_button_clicked(GtkWidget widget, gpointer data)
{
// balabalabala
}
就可以了 所以, 上面讲的一堆创建界面的方法, 其实大部分时候都用不着
由于用到了 libglade, 我们的编译方法变为
gcc -o foo fooc `pkg-config --cflags --libs libglade-20`
开发举例
一个很简单的程序, 密码学对称加密算法要用到的, 如果说是界面, 就是三个文
本框: 明文, 密码, 密文, 三个按钮, 加密, 解密, 清除, 完了 为了实验众多
的算法, 我们加了一个下拉窗口, 用来选择算法 我把它设计成一个 wrapper
和框架, 它不实现任何算法, 只是在界面中获取用户输入, 调用外部程序, 并把
结果显示出来而已 这样, 实际的算法实现可以用纯 C 写的文本界面程序完成,
移植起来很方便, 在 windows 随便做个一样的界面做前端就整个移植过去了
于是, 我们需要的窗体元素是 GtkEntry, GtkComboBoxEntry, GtkButton, 查查
手册, 我们用到的界面相关的函数只有以下几个:
- gtk_entry_get_text(), 用于获取文本框输入
- gtk_entry_set_text(), 用于在文本框中显示结果
- gtk_combo_box_get_active_text(), 用于在 ComboBoxEntry (派生自
ComboBox) 取出用户选中的算法
另一个问题是, 他们都需要相应的对象指针做参数, 这应该怎样获得呢 我们使
用 glade_xml_get_widget(GUI, "控件名") 就能取得控件了
import javaawtFlowLayout;
import javaawteventActionEvent;
import javaawteventActionListener;
import javaxswingJButton;
import javaxswingJFrame;
import javaxswingJLabel;
import javaxswingJTextField;
public class changeTitle extends JFrame implements ActionListener {
/
/
private static final long serialVersionUID = 1L;
public static final int width = 200;
public static final int height = 200;
JTextField text1;
JLabel la;
JButton jbn;
changeTitle(){
setTitle("hello");
setSize(width, height);
setLayout(new FlowLayout());
text1=new JTextField(15);
la=new JLabel("标题:");
jbn=new JButton("更改标题");
add(la);
add(text1);
add(jbn);
jbnaddActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(egetSource()==jbn){
setTitle(text1getText());
}
}
public static void main(String[] args ){
changeTitle changetitle=new changeTitle();
changetitlesetVisible(true);
changetitlesetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);
}
}
package heh;//我自己的包名
import javaawt;
import javaawtevent;
import javaxswingevent;
import javaxswing;
public class Jsq extends JFrame
{
Panel pan1=new Panel();
Panel pan2=new Panel();
Panel pan3=new Panel();
Panel pan4=new Panel();
Panel pan5=new Panel();
Label la1=new Label("欢迎使用计算器");
Button bt1=new Button(" ");
Button bt2=new Button("MC");
Button bt3=new Button("MR");
Button bt4=new Button("MS");
Button bt5=new Button("M+");
Button bt11=new Button("Backspace");
Button bt12=new Button("CE");
Button bt13=new Button("C");
Button but[]=new Button[20];
String buta[]={"7","8","9","/","sqrt","4","5","6","","%","1","2","3","-","1/x","0","-/+","","+","="};
JTextField t1=new JTextField("0");//swing组件,可以设置对齐方式
double a=0;//记录计算中的值或结果
String b="";//“+,-,,/”运算符号标记
int d=0; //是否刚刚按过运算符号标记
int x=0; //是否刚刚按过“=”号标记
int y=0; //屏幕刚刚出现过汉字的标记
public Jsq()
{
super("计算器");
add(pan1,BorderLayoutNORTH);
add(pan4,BorderLayoutCENTER);
add(pan3,BorderLayoutWEST);
pan3setLayout(new GridLayout(0,1,10,10));
pan3add(bt1);pan3add(bt2);pan3add(bt3);pan3add(bt4);pan3add(bt5);
pan4setLayout(new BorderLayout());
pan4add(pan5,BorderLayoutNORTH);
pan4add(pan2,BorderLayoutCENTER);
pan5setLayout(new GridLayout(1,3,5,5));
pan5add(bt11);pan5add(bt12);pan5add(bt13);
pan1setLayout(new GridLayout(3,1));
pan1add(la1);
pan1add(t1);
t1setEditable(false);//文本框设置为不可修改
t1setHorizontalAlignment(JTextFieldRIGHT);//设置文本框对齐方式
pan2setLayout(new GridLayout(4,5,10,10));
for(int i=0;i<20;i++)
{
but[i]=new Button(buta[i]);
pan2add(but[i]);
}
but[0]addActionListener(new A());
but[1]addActionListener(new A());
but[2]addActionListener(new A());
but[3]addActionListener(new A());
but[4]addActionListener(new A());
but[5]addActionListener(new A());
but[6]addActionListener(new A());
but[7]addActionListener(new A());
but[8]addActionListener(new A());
but[9]addActionListener(new A());
but[10]addActionListener(new A());
but[11]addActionListener(new A());
but[12]addActionListener(new A());
but[13]addActionListener(new A());
but[14]addActionListener(new A());
but[15]addActionListener(new A());
but[16]addActionListener(new A());
but[17]addActionListener(new A());
but[18]addActionListener(new A());
but[19]addActionListener(new A());
bt11addActionListener(new A());
bt12addActionListener(new A());
bt13addActionListener(new A());
bt1addActionListener(new A());
bt2addActionListener(new A());
bt3addActionListener(new A());
bt4addActionListener(new A());
bt5addActionListener(new A());
}
class A implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(egetSource()==but[0]) //"7"
{
if(x==1) //判断是否刚刚按过"="
{
t1setText("7");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{ //如果显示为"0"或"00"或者刚刚按过运算符号
t1setText("7"); //或者屏幕显示为汉字 那么显示为"7"
y=0;//将标记设置为0
}
else
t1setText(t1getText()+"7");//将显示的字符串后面加"7"
d=0;//将标记设置为0
if(t1getText()length()>40)//判断显示字符长度是否超过40
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[1]) //"8"
{
if(x==1)
{
t1setText("8");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("8");
y=0;
}
else
t1setText(t1getText()+"8");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[2]) //"9"
{
if(x==1)
{
t1setText("9");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("9");
y=0;
}
else
t1setText(t1getText()+"9");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[3]) //"/"
{
if(y==1) //判断显示的是否为汉字
{
t1setText("0");
y=0;
}
if(d==0) //判断是否刚刚按过运算符号 防止连续按运算符号产生错误
{
if(bequals("+"))//四则混合运算时 判断上次计算是否为"+"
{
a=a+DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("-"))//四则混合运算时 判断上次计算是否为"-"
{
a=a-DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals(""))//四则混合运算时 判断上次计算是否为""
{
a=aDoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("/"))//四则混合运算时 判断上次计算是否为"/"
{
double f=DoublevalueOf(t1getText())doubleValue();
if(f==0)//判断除数是否为0
{
t1setText("错误!请按“CE”清屏后继续计算");
y=1;
}
else
{
a=a/DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(bequals(""))//判断进行的是不是四则混合运算的第一次运算
{
a=DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(!t1getText()equals("错误!请按“CE”清屏后继续计算"))//是否出现了除数为零的错误
{
b="/";//运算符号标记设置为"/"
d=1; //标记已经按过运算符号
}
if(t1getText()length()>40)//判断显示字符长度是否超过40
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;//将记忆的数字抹去
b="";//运算符号标记 为未按过运算符号
d=0;//标记 刚刚没有按过运算符号
y=1;//标记 屏幕显示了汉字
}
}
if(egetSource()==but[4]) //"sqrt"
{
if(y==1)
{
t1setText("0");
y=0;
}
double f=DoublevalueOf(t1getText())doubleValue();
if(f<0) //判断被开放数是否小于零
{
t1setText("错误!被开方数小于0,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
else
{
f=Mathsqrt(f);
t1setText(""+(f));
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[5]) //"4"
{
if(x==1)
{
t1setText("4");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("4");
y=0;
}
else
t1setText(t1getText()+"4");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[6]) //"5"
{
if(x==1)
{
t1setText("5");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("5");
y=0;
}
else
t1setText(t1getText()+"5");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[7]) //"6"
{
if(x==1)
{
t1setText("6");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("6");
y=0;
}
else
t1setText(t1getText()+"6");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[8]) //""
{
if(y==1)
{
t1setText("0");
y=0;
}
if(d==0)
{
if(bequals("+"))
{
a=a+DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("-"))
{
a=a-DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals(""))
{
a=aDoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("/"))
{
double f=DoublevalueOf(t1getText())doubleValue();
if(f==0)
{
t1setText("错误!请按“CE”清屏后继续计算");
y=1;
}
else
{
a=a/DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(bequals(""))
{
a=DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(!t1getText()equals("错误!请按“CE”清屏后继续计算"))
{
b="";
d=1;
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[9]) //"%"
{
if(y==1)
{
t1setText("0");
y=0;
}
double f=DoublevalueOf(t1getText())doubleValue();
t1setText(""+(f/100));
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[10]) //"1"
{
if(x==1)
{
t1setText("1");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("1");
y=0;
}
else
t1setText(t1getText()+"1");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[11]) //"2"
{
if(x==1)
{
t1setText("2");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("2");
y=0;
}
else
t1setText(t1getText()+"2");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[12]) //"3"
{
if(x==1)
{
t1setText("3");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("3");
y=0;
}
else
t1setText(t1getText()+"3");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[13]) //"-"
{
if(y==1)
{
t1setText("0");
y=0;
}
if(d==0)
{
if(bequals("+"))
{
a=a+DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("-"))
{
a=a-DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals(""))
{
a=aDoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("/"))
{
double f=DoublevalueOf(t1getText())doubleValue();
if(f==0)
{
t1setText("错误!请按“CE”清屏后继续计算");
y=1;
}
else
{
a=a/DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(bequals(""))
{
a=DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(!t1getText()equals("错误!请按“CE”清屏后继续计算"))
{
b="-";
d=1;
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[14]) //"1/x"
{
if(y==1)
{
t1setText("0");
y=0;
}
else
{
double f=DoublevalueOf(t1getText())doubleValue();
t1setText(""+(1/f));
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
}
if(egetSource()==but[15]) //"0"
{
if(x==1)
{
t1setText("0");
x=0;
}
if(t1getText()equals("00")||t1getText()equals("0")||d==1||y==1)
{
t1setText("0");
y=0;
}
else
t1setText(t1getText()+"0");
d=0;
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[16]) //"-/+"
{
if(y==1)
{
t1setText("0");
y=0;
}
double f=DoublevalueOf(t1getText())doubleValue();
t1setText(""+(-f));
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[17]) //""
{
if(y==1)
{
t1setText("0");
y=0;
}
if(t1getText()indexOf("")==-1)//判断是否已经有""
{
t1setText(t1getText()+"");
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[18]) //"+"
{
if(y==1)
{
t1setText("0");
y=0;
}
if(d==0)
{
if(bequals("+"))
{
a=a+DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("-"))
{
a=a-DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals(""))
{
a=aDoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("/"))
{
double f=DoublevalueOf(t1getText())doubleValue();
if(f==0)
{
t1setText("错误!请按“CE”清屏后继续计算");
y=1;
}
else
{
a=a/DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(bequals(""))
{
a=DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(!t1getText()equals("错误!请按“CE”清屏后继续计算"))
{
b="+";
d=1;
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==but[19]) //"="
{
if(y==1)
{
t1setText("0");
y=0;
}
if(bequals("+"))
{
a=a+DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("-"))
{
a=a-DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals(""))
{
a=aDoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(bequals("/"))
{
double f=DoublevalueOf(t1getText())doubleValue();
if(f==0)
{
t1setText("错误!请按“CE”清屏后继续计算");
y=1;
}
else
{
a=a/DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
}
if(bequals(""))
{
a=DoublevalueOf(t1getText())doubleValue();
t1setText(""+a);
}
if(!t1getText()equals("错误!请按“CE”清屏后继续计算"))
{
b="";
d=1;
x=1;
}
if(t1getText()length()>40)
{
t1setText("错误!数字过长,请按“C”从新输入");
a=00;
b="";
d=0;
y=1;
}
}
if(egetSource()==bt11) //"Backspace"
{
if(y==1)
{
t1setText("0");
y=0;
}
else
{
String s1=t1getText();
if(s1length()==1)//如果将显示的数字全部退掉 则显示"0"
{
t1setText("0");
}
else
{
t1setText(s1substring(0,(s1length()-1)));//退格
}
}
}
if(egetSource()==bt12) //"CE"
{
t1setText("0");//清屏
}
if(egetSource()==bt13) //"C" 初始化
{
t1setText("0");
a=00;
b="";
d=0;
}
if(egetSource()==bt1) //""
{
}
if(egetSource()==bt2) //"MC"
{
}
if(egetSource()==bt3) //"MR"
{
}
if(egetSource()==bt4) //"MS"
{
}
if(egetSource()==bt5) //"M+"
{
}
}
}
public static void main(String args[])
{
Jsq a=new Jsq();
asetSize(300,250);
asetVisible(true);
}
}
这是最简单的界面程序 : // c++cpp : 定义应用程序的入口点。
//
#include "stdafxh"
#include "c++h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_C, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_C));
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msghwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msgwParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望
// 此代码与添加到 Windows 95 中的“RegisterClassEx”
// 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
// 这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcexcbSize = sizeof(WNDCLASSEX);
wcexstyle = CS_HREDRAW | CS_VREDRAW;
wcexlpfnWndProc = WndProc;
wcexcbClsExtra = 0;
wcexcbWndExtra = 0;
wcexhInstance = hInstance;
wcexhIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_C));
wcexhCursor = LoadCursor(NULL, IDC_ARROW);
wcexhbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcexlpszMenuName = MAKEINTRESOURCE(IDC_C);
wcexlpszClassName = szWindowClass;
wcexhIconSm = LoadIcon(wcexhInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
图形用户界面技术的特点体现在三方面:多视窗技术、菜单技术和联机帮助。我们从这三个方面来说明图形用户界面的方便所在,这一部分的内容几乎是所有图形用户界面软件共有的内容。
多视窗技术
在Windows环境中,计算机屏幕显示为一个工作台,用户的主工作区域就是桌面。工作台将你的工作显示在称为"窗口"的矩形区域内,你可以在窗口中对应用程序和文档进行 *** 作。所谓多窗口就是同时能在同一屏幕上打开多个窗口,也称多视窗技术,以下列出多视窗的几点优越性:
1、友好的 *** 作环境:窗口系统可以提供友好的、菜单驱动的、具有图形功能的用户界面。每个窗口都由标题、菜单、控制按钮、滚动条、边框等元素组成。用户可以方便地使用鼠标打开和关闭窗口,通过 *** 作窗口组成部件来实现窗口的移动、尺寸改变和多窗口的布局。用户通过窗口实施各种上机 *** 作,进行人机交互。由于所有窗口具有统一的风格和相似的 *** 作方式,用户只要领会一种系统的窗口 *** 作要领,便可触类旁通。
2、一屏多用:一个多窗口的屏幕,从功能上说,相当于多个独立的屏幕,所以能有效地增加屏幕在同一时间所显示的信息容量。
3、任务切换:窗口系统是用户可以同时运行多道程序的一个集成化环境。模拟人们日常工作中同时干几件事的情景,用户可以同时打开几个窗口以运行多个应用程序,并可实现在它们之间的快速转换。但是在同一时间只能有一个窗口是活动窗口,允许接受用户输入的数据或命令,其他窗口都是非活动窗口。活动窗口的醒目标志则是清晰的窗口标题栏及其任务名,而且它会摆放在其他窗口的最上面而不会被遮挡。
4、资源共享与信息共享: *** 作系统的资源是CPU、存储器、I/O设备等,窗口系统的资源还包括窗口、事件等,这些资源为各应用程序所共享。
是否可以解决您的问题?
以上就是关于如何在linux下用gtk开发图形界面应用程序全部的内容,包括:如何在linux下用gtk开发图形界面应用程序、java编写图形界面应用程序,其中包括一个文本框和一个按钮.用户单击按钮后,窗口的标题为文本框中的内容、用java 基于SWING的图形用户界面设计 编写一个应用程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)