LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: Smalltalk

gtkmm 的翻译计划

[复制链接]
发表于 2004-4-1 15:15:30 | 显示全部楼层
你可以看一下前面翻译完的 gtkmm FAQ
那里有一些说明
glade 在 gtkmm 的编程中没有什么直接的使用方法
但还是有一点帮助的
发表于 2004-4-1 15:55:18 | 显示全部楼层
sandbank 兄弟翻译的第十四章:

第十四章 可绘图控件

可绘图控件类似于一个空的X Window,它能让你自由地创建你所想要的任何图形。伴随这种自由的是你需要处理发生在这个控件上的事件。当这个控件首次出现时,或是被覆盖之后又显现,它需要重画它自己。许多控件有相应的代码做这个工作,但可绘图控件没有,它让你编写一个发生的事件的消息处理机,以决定控件的哪一个部分被重画。

有很多方法可以帮助你在这个控件上绘制各种对象,例如像素,直线,矩形,椭圆,多边形,图像,和文本。我们将会按顺序介绍每个对象,并给出它使用的例子。

图形上下文(Graphics Contexts)
在实际的绘制之前,需要创建有关图形上下文的背景信息。图形上下文是一个服务器端的资源。他们包含用来描述应该如何绘制的信息。这提供给绘图方法更少的参数,减少了服务器和客户端的交流。下面的例子展示了如何安装一个绘图前景色为红色的图形上下文。

Gdk::GC some_gc;
some_gc.create(get_window());
Gdk::Color some_color;
Gdk::Colormap some_colormap(Gdk::Colormap::get_system());
some_color.set_red(65535);
some_color.set_green(0);
some_color.set_blue(0);
some_colormap.alloc(some_color);
some_gc.set_foreground(some_color);
   
前两行创建了图形上下文,并分配给了相应的控件。方法get_window() 是类Gtk::Widget 的一部分,所以如果你把这个代码放入一个原有的实体,你可以就这样调用它,否则你要使用some_widget.get_window()。

下两行创建Gdk::Color 和 Gdk::Colormap。在设定了颜色值之后,你需要对颜色进行分配。系统指出在这种情况下应该做什么。colormap 包含颜色应如何在你的屏幕上显示的信息,以能分配需要的颜色。例如,在一个只有256色的显示器上,精确的颜色的要求可能达不到,所以与所要求的颜色最相近的会用来代替。最后一行把颜色设为前景色。

有很多属性可用来设置图形上下文。如前景色和背景色。当画线时,你可以用set_line_width()设置线宽。用set_line_style()可设置是要画实线还是虚线。虚线中点的比例可用set_dashes设置。两条线合并时,是圆角连接,或点连接,或斜角连接,可用set_join_style()设置。其他的如字体样式,多边形的点填充和图案填充,也能够通过图形上下文设置。


画像素

你能够使用Gdk:rawable::draw_point() 和 Gdk:rawable::draw_points()这两个方法画分离的像素。每个绘图方法都使用一个 Gdk::GC 作为他们的第一个参数,除了特别说明的之外。draw_point() 的另两个参数是x坐标(相对控件左边界的水平偏移,以0开始),和y坐标(相对控件顶部的垂直偏移,以0开始)。draw_points() 有两个参数,Gdk::GC 和 一个 Gdk:oints 的集合。第二个参数可以为任何标准的容器类型,例如一个std::vector<Gdk:oint>。所以说 draw_point() 能够像这样使用:

get_window()->draw_point(some_gc, 20, 20);

但是 draw_points() 有点复杂,可能像这样:

std::vector<Gdk:oint> points_array;
points_array.push_back(Gdk:oint(10, 10));
points_array.push_back(Gdk:oint(20, 20));
draw_points(some_gc, points_array);
//One way to draw the two points.
//画两点的一种方法


画线

画线比画点要更有趣,这里是一个完整的程序:
图14.1

源代码

这个程序含有两个类。第一个是 Gtk:rawingArea 的一个子类,包含 on_expose_event 成员函数。无论什么时候,当绘图区需要重画时,这个方法就被调用。draw_line() 的四个增加的参数(除了图形上下文作为第一个)是线段开始和结束的端点坐标。

TestWindow 类含有一个绘图区。当它被创建时,它建立了一个50×50的绘图区。当窗体改变大小时,这个区域保持在大的窗体的左上角。这个绘图区以缺省的灰色背景创建。


画矩形和多边形

方法 draw_rectangle() 用来画矩形和正方形。第二个参数用来决定矩形是否被填充。非零值为填充矩形。第三和第四个参数分别指定矩形左上角的x和y坐标。最后两个参数指定矩形的宽和高(用像素表示)。

因为X Windows处理绘图的方式,一个矩形框比一个矩形块要高和宽各一个像素。如果你想让矩形的边界是一种颜色,填充的又是另一种颜色,那你需要先画矩形块。否则,矩形块会将矩形框的上边界和左边界弄模糊。你可能需要从矩形框的宽和高上减去一个像素,以得到你期望的大小。

方法 draw_polygon() 使用了a Glib::ArrayHandle<Gdk:oint>,这是另一种声明Gdk:oint的标准容器的途径,就像在上面的 draw_points() 中看到的那样。第一个参数是 Gdk::GC ,第二个参数决定多边形是被填充还是只有边框,类似于 draw_rectangle() 。多边形的形状是这样产生的,先从第一个点画线到第二个点,依次到最后一个点,最后用一条线连回第一个点。这也就暗示了你不需要把第一个点再次设为最后一个点。

画椭圆和弧

draw_arc() 有很多参数。第二个同样是选择填充弧还是不填充。下面两个参数是圆弧左上角的x和y坐标。想像有个矩形包围着这个圆弧,上、下、边界都是恰好接触。这个矩形的左上角就由这个x和y坐标所指定。矩形的宽和高是接下来的两个参数。一个较大的矩形将产生一个更大的椭圆形。

如果你不想画整个圆弧,那么最后两个参数就定义了起始和终止的角度。这个角度单位是64分之一度,从右边开始,逆时针旋转。


绘制文本是通过Pango Layouts绘制的。最简单的创建 Pango:ayout 的途径是使用 create_pango_layout。一旦被创建,这个显示的区域就可以通过多种途径进行操作,包括改变文本,字体,等等。最后,通过 Gdk:rawable 的方法 draw_layout (它的参数有常用的Gdk::GC,x和y坐标,以及这个显示区域它自己),这个区域可被加以渲染。

例子

下面的例子使用了上面所有的绘图方法:

图 14.2

源代码程序的结构和第一个一样,除了含有讨论到现在的绘图元素的例子之外。


画图像

有两种方法可将图像数据放入绘图区。draw_pixmap() 能够把一个 Gdk:rawable (绘图区的窗口就是一个例子)的内容复制到绘图区。还有一个 draw_bitmap() 用于在绘图区中绘制两色图,和一个绘制多种颜色的 draw_image()。

对于所有的这些方法,第一个参数都是 Gdk::GC。第二个参数是将要复制的相应类型的对象:Gdk:rawable, Gdk::Bitmap, Gdk::Image。下两个参数是将要复制过来的图像的x和y点。接下来是复制到的x和y点。最后两个参数是将要复制的区域的宽和高。

还有一个方法,是从 Gdk:ixbuf 绘制。一个 Gdk:ixbuf 缓存是一个有用的由像素集合组成的 wrapper ,它能从文件中读取,并能通过多种途径操作。

可能最常用的创建 Gdk:ixbufs 的方法是使用 Gdk::Pixbuf::create_from_file(),它可以读取一个图像文件,例如一个读入 pixbuf 准备渲染的png文件。

Gdk::Pixbuf 能够用 render_to_drawable 渲染,它只有很少的参数。render_to_drawable 是 Gdk::Pixbuf 的一个成员,而不是 Gdk:rawable (它并不象早期描述的 draw_* 函数)的成员。同样的,它的第一个参数是要渲染的 drawable 。第二个参数仍然是 Gdk::GC。接下来的两个参数是 pixbuf 中要被绘制的点。然后是要绘制到 drawable 中的点,和实际上要绘制的宽和高(可能不是整个图像,特别当你只想对窗口的一部分作出事件处理机的回应)。最后,是dither类型的参数。如果你使用 Gdk::RGB_DITHER_NONE 作为dither类型,那么dither部分的偏移参数可以都为零。

这里是一小段合起来的代码。(注意,通常你不需要在事件处理机中每次都装载图像!如下面所示的,将它合并起来了)

[php]
bool myarea:n_expose_event(GdkEventExpose* ev)
{
  Glib::RefPtr<Gdk::PixBuf> image = Gdk::PixBuf::create_from_file("myimage.png");
  image->render_to_drawable(get_window(), get_style()->get_black_gc(),
    0, 0, 100, 80, image->get_width(), image->get_height(),
  // draw the whole image (from 0,0 to the full width,height) at 100,80 in the window
  //在窗口中画整个图像(从0,0到整个宽,高,即100,80)。
  Gdk::RGB_DITHER_NONE, 0, 0);
  return true;
}
[/php]
发表于 2004-4-1 15:57:10 | 显示全部楼层
sandbank 兄弟翻译的第十五章:

第十五章 拖放操作

Gtk::Widget有着以"drag_"开头的多种方法和消息。这些用来进行拖放操作。

源及目标

物品从sources拖出,释放在destinations中。每个源及目标含有数据格式的相关信息,并且能够发送与接收这些格式的数据。这些数据格式由Gtk::TargetEntry项提供,。如果有两项使用了一个兼容的Gtk::TargetEntry,那么目标只能接受其中的一个释放项。适当的消息将会被发出,通知消息处理机使用了哪一个Gtk::TargetEntry。

Gtk::TargetEntry 对象包含下列信息:

target:一个名称,例如"STRING"
info:一个将送到你的消息处理机的标识符,以告诉你哪一个TargetEntry 被使用了。
flags:TODO(保留)


方法
使用这些Gtk::Widget方法可使控件被标识为源或目标

void drag_source_set(const ArrayHandle_TargetEntry& targets, GdkModifierType start_button_mask, GdkDragAction actions);

targets:Gtk::TargetEntry (例如:std::list<Gtk::TargetEntry> 或 std::vector<Gtk::TargetEntry>) 元素的一个容器

start_button_mask:一个ORed的组合值,指定哪一个修正键或鼠标键被按下来以触发拖动操作。

actions:一个ORed的组合值,指出对于源哪一个拖放操作是有效的。例如,复制,移动,或连接。用户能通过使用修正键来从这些操作中作出选择,例如shift将复制改为移动,并能显示一个不同的鼠标指针。

void drag_dest_set(const ArrayHandle_TargetEntry& targets, GtkDestDefaults flags, GdkDragAction actions);

flags 一个ORed的组合值,它表明控件将如何对拖放项作出直接的反应。

actions 表明目标能够收到的拖放操作-请看上面的描述。



消息
当一个目标接受了一个被拖动的项,某个消息将会被发出,这决定于选择的是哪一个操作。例如,用户可能按住shift不放,而使复制操作成为了移动操作。记住,用户只能使用你在drag_dest_set() 和 drag_source_set()调用中所指定的操作。


复制
源控件将以下面的顺序发出这些消息:

drag_begin:提供DragContext

drag_motion: 提供DragContext和坐标。你能够调用DragContext 的 drag_status()方法,以表明接受的是哪一个目标。

drag_get: 提供有关拖动的数据格式的信息,和一个GtkSelectionData结构,你在里面存放的是请求的数据。

drag_drop:提供DragContext和坐标。

drag_end: 提供DragContext。


在源发出drag_get消息之后,目标控件将会发出这个消息:
drag_data_received:提供有关拖动的数据格式的信息,和一个含有释放数据的 GtkSelectionData 结构。你需要调用DragContext的drag_finish()方法来判断操作是否成功。


移动
在一个move中,源控件将会发出下面的消息:
drag_delete: 给予源删除原来的数据的的时机。(如果这是适当的)


连接
自己可以找个例子或找篇文档看看

DragContext
拖放消息提供了一个DragContext,它包含拖放操作的一些信息,并能够用来影响当前进程。例如,你可以通过使用set_icon()方法,发现源控件,或是改变拖放图标。更重要的是,你需要从你的drag_data_received消息处理机中调用drag_finish()方法,来表明释放操作是否成功。



例子
这是一个非常简单的例子,演示了一个拖放复制的操作

图15.1 拖放操作

源代码

文件: dndwindow.h
[PHP]
#ifndef GTKMM_EXAMPLE_DNDWINDOW_H
#define GTKMM_EXAMPLE_DNDWINDOW_H

#include <gtkmm/label.h>
#include <gtkmm/window.h>
#include <gtkmm/box.h>
#include <gtkmm/button.h>

class DnDWindow : public Gtk::Window
{

public:
  DnDWindow();
  virtual ~DnDWindow();

protected:
  //Signal handlers:
  //消息处理机
  virtual void on_button_drag_data_get(const Glib::RefPtr<Gdk:ragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time);
  virtual void on_label_drop_drag_data_received(const Glib::RefPtr<Gdk:ragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);

  //Member widgets:
  //成员控件
  Gtk::HBox m_HBox;
  Gtk::Button m_Button_Drag;
  Gtk:abel m_Label_Drop;
};

#endif // GTKMM_EXAMPLE_DNDWINDOW_H
[/PHP]

File: dndwindow.cc
[PHP]
#include "dndwindow.h"
#include <iostream>

DnDWindow:nDWindow()
: m_Button_Drag("Drag Here\n"),
  m_Label_Drop("Drop here\n")
{
  set_title("DnD example");

  add(m_HBox);

  //Targets:
  //目标
  std::list<Gtk::TargetEntry> listTargets;
  listTargets.push_back( Gtk::TargetEntry("STRING") );
  listTargets.push_back( Gtk::TargetEntry("text/plain") );

  //Drag site:
  //拖动区
  //Make m_Button_Drag a DnD drag source:
  //建立一个DnD拖动源m_Button_Drag
  m_Button_Drag.drag_source_set(listTargets);
               
  //Connect signals:
  //连接消息
  m_Button_Drag.signal_drag_data_get().connect( sigc::mem_fun(*this, &DnDWindow:n_button_drag_data_get));

  m_HBox.pack_start(m_Button_Drag);

  //Drop site:
  //释放区
  //Make m_Label_Drop a DnD drop destination:
  //建立一个DnD释放目标m_Label_Drop
  m_Label_Drop.drag_dest_set(listTargets);

  //Connect signals:
  //连接消息
  m_Label_Drop.signal_drag_data_received().connect( sigc::mem_fun(*this, &DnDWindow:n_label_drop_drag_data_received) );

  m_HBox.pack_start(m_Label_Drop);

  show_all();
}

DnDWindow::~DnDWindow()
{
}

void DnDWindow:n_button_drag_data_get(const Glib::RefPtr<Gdk:ragContext>&, Gtk::SelectionData& selection_data, guint, guint)
{
  selection_data.set(selection_data.get_target(), 8 /* 8 bits format */, (const guchar*)"I'm Data!", 9 /* the length of I'm Data! in bytes */);
}

void DnDWindow:n_label_drop_drag_data_received(const Glib::RefPtr<Gdk:ragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)
{
  if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
  {
    //TODO: Use a get_data_as_string or something like that.
    //使用get_data_as_string或类似的方法
    std::cout << "Received \"" << (gchar *)(selection_data.get_data()) << "\" in label " << std::endl;
  }

  context->drag_finish(false, false, time);
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "dndwindow.h"

int main (int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  DnDWindow dndWindow;
  Gtk::Main::run(dndWindow);
  //Shows the window and returns when it is closed.
  //显示窗口,当它关闭时返回
  return 0;
}
[/PHP]

There is a more complex example in examples/dnd.
在examples/dnd有更多更复杂的例子
发表于 2004-4-2 15:39:09 | 显示全部楼层
能否整理一个列表呢?这样看好麻烦。
发表于 2004-4-2 21:35:30 | 显示全部楼层
最初由 风车车 发表
能否整理一个列表呢?这样看好麻烦。


你的意见很好
我们是有这个想法
不过现在打算先翻译完

最后整理成 HTML 的形式发布出去
这样看起来太累了
发表于 2004-4-4 19:35:04 | 显示全部楼层
Sandbank 兄弟一下子又翻译了三章
真是勤奋啊
想想自己停了这么久
都有点不好意思了
这里是 sandbank 兄弟翻译的第十二章:

第十二章 与X-Windows无关的构件

有些构件是与X-Windows无关的,所以他们不会接受 X 的事件。这就意味着在X event signals中描述的信号将不会被发出。如果你想捕获这些构件的事件,你可以使用一个称做Gtk::EventBox的特别容器,在 EventBox 段中对此有所描述。

下面是这些构件的一分清单:

Gtk::Alignment
Gtk::Arrow
Gtk::Bin
Gtk::Box
Gtk::Image
Gtk::Item
Gtk:abel
Gtk:ixmap
Gtk::ScrolledWindow
Gtk::Separator
Gtk::Table
Gtk::AspectFrame
Gtk::Frame
Gtk::VBox
Gtk::HBox
Gtk::VSeparator
Gtk::HSeparator

这些控件主要用来修饰或排版,所以你不会经常要捕获发生在他们上面的事件。为了提高性能,就意味着他们没有X-Window 的支持。


事件盒(EventBox)

TODO: 为什么他们不使用X Windows 中的 explain clipping 呢。 有些构件与X windows没有关联;他们在他们的父窗口上绘制。由于这个原因,他们不能接收事件。还有,如果他们没有正确地改变大小,没有做相应的修剪,你将会得到杂乱而重叠的结果。如果你需要更多的这种构件,事件盒是一个好的选择。从 EventBox 这个名称上看,它强调的是事件处理的方法,实际上这个构件也可像夹子一样来使用。(更多内容,请看下面的例子)

Gtk::EventBox 的构造函数是:

Gtk::EventBox();

子构件能够像这样加入EventBox :

event_box.add(child_widget);

参考文档
例子

下面的例子演示了EventBox的两种用法——一个标签被创建,并放入了一个小盒子,当鼠标单击标签时,触发程序退出。改变窗体的大小会揭示标签的更多变化。

图12.1 EventBox

源代码

文件: examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数
  virtual bool on_eventbox_button_press(GdkEventButton* event);

  //Child widgets:
  //子构件

  Gtk::EventBox m_EventBox;
  Gtk:abel m_Label;
  Gtk::Tooltips m_Tooltips;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件:examplewindow.cc
[PHP]
#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_Label("Click here to quit, quit, quit, quit, quit")
{
  set_title ("EventBox");
  set_border_width(10);

  add(m_EventBox);

  m_EventBox.add(m_Label);

  //Clip the label short:
  //将标签剪短

  m_Label.set_size_request(110, 20);

  //And bind an action to it:
  //对它绑定一个事件

  m_EventBox.set_events(Gdk::BUTTON_PRESS_MASK);
  m_EventBox.signal_button_press_event().connect(
    sigc::mem_fun(*this, &ExampleWindow:n_eventbox_button_press) );

  m_Tooltips.set_tip(m_EventBox, "Click me!");

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

bool ExampleWindow:n_eventbox_button_press(GdkEventButton*)
{
  hide();
  return true;
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它返回时关闭

  return 0;
}
[/PHP]
发表于 2004-4-4 19:38:03 | 显示全部楼层
这里 sandbank 兄弟翻译的第十三章:

第十三章 对话框

对话框被当作“第二个窗体”,它提供特别的信息和用来提出问题。Gtk:ialog 包含一些预封装的构件,以保证一致性,并且它有一个run()方法会一直运行,直到用户取消了这个对话框。

存在有很多可扩展对话框类,你会发现它们是很有用的。举个例子,在大多数简单的通知中,你可能会用到 Gtk::MessageDialog 。但是在其他时候,你可能需要由它开发你自己的对话框类,来提供更复杂的功能。

把构件封装到一个自定义对话框,你需要把他们封装到Gtk::VBox,通过get_vbox()也可以。如果只是在对话框底部增加一个按钮,你可以使用方法add_button() 。

run()方法返回值为int。它可能是从Gtk::ResponseType 返回的一个值(如果用户通过单击一个标准按钮关闭的对话框),也可能是你使用
add_button()时指定的返回值。

参考文档


消息对话框

这是一个很方便的类,用来创建简单的,标准的消息对话框,通过一条消息、一个图标,和按钮让用户作出回应。你可以指定消息的类型和其中的文本,也可以通过Gtk::ButtonsType 的值指定标准按钮。

参考文档
例子
图13.1 消息对话框

源代码

文件:examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数
  virtual void on_button_info_clicked();
  virtual void on_button_question_clicked();

  //Child widgets:
  //子构件
  Gtk::VButtonBox m_ButtonBox;
  Gtk::Button m_Button_Info, m_Button_Question;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"
#include <gtkmm/dialog.h>
#include <iostream>


ExampleWindow::ExampleWindow()
: m_Button_Info("Show Info MessageDialog"),
  m_Button_Question("Show Question MessageDialog")
{
  set_title("Gtk::MessageDialog example");

  add(m_ButtonBox);
  
  m_ButtonBox.pack_start(m_Button_Info);
  m_Button_Info.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_info_clicked) );

  m_ButtonBox.pack_start(m_Button_Question);
  m_Button_Question.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_question_clicked) );

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow:n_button_info_clicked()
{
  Gtk::MessageDialog dialog(*this, "This is an INFO MessageDialog");
  dialog.run();
}

void ExampleWindow:n_button_question_clicked()
{
  Gtk::MessageDialog dialog(*this, "This is a QUESTION MessageDialog", false /* use_markup */, Gtk::MESSAGE_QUESTION, (Gtk::ButtonsType)(Gtk::BUTTONS_OK | Gtk::BUTTONS_CANCEL));
  int result = dialog.run();

  //Handle the response:
  //处理返回值
  switch(result)
  {
    case(Gtk::RESPONSE_OK):
    {
      std::cout << "OK clicked." << std::endl;
      break;
    }
    case(Gtk::RESPONSE_CANCEL):
    {
      std::cout << "Cancel clicked." << std::endl;
      break;
    }
    default:
    {
      std::cout << "Unexpected button clicked." << std::endl;
      break;
    }
  }
  
}
[/PHP]

文件: main.cc
[/PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回
  return 0;
}
[/PHP]

文件选择框

这个框体让用户选择一个文件或文件夹。例如,在保存和装载文档时会用到它。

参考文档

例子

图13.2 文件选择框

源代码

文件:examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数
  virtual void on_button_file_clicked();
  virtual void on_button_folder_clicked();

  //Child widgets:
  //子构件
  Gtk::VButtonBox m_ButtonBox;
  Gtk::Button m_Button_File, m_Button_Folder;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"
#include <gtkmm/dialog.h>
#include <iostream>


ExampleWindow::ExampleWindow()
: m_Button_File("Choose File"),
  m_Button_Folder("Choose Folder")
{
  set_title("Gtk::FileSelection example");

  add(m_ButtonBox);
  
  m_ButtonBox.pack_start(m_Button_File);
  m_Button_File.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_file_clicked) );

  m_ButtonBox.pack_start(m_Button_Folder);
  m_Button_Folder.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_folder_clicked) );

  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow:n_button_folder_clicked()
{
  Gtk::FileSelection dialog("lease choose a folder");
  dialog.set_transient_for(*this);
  dialog.get_file_list()->get_parent()->hide();
  //Prevent the user from selecting a file.
  //阻止用户选择一个文件
  int result = dialog.run();

  //Handle the response:
  //处理返回值
  switch(result)
  {
    case(Gtk::RESPONSE_OK):
    {
      std::cout << "OK clicked." << std::endl;
      std::cout << "Folder selected: " << dialog.get_filename() << std::endl;
      break;
    }
    case(Gtk::RESPONSE_CANCEL):
    {
      std::cout << "Cancel clicked." << std::endl;
      break;
    }
    default:
    {
      std::cout << "Unexpected button clicked." << std::endl;
      break;
    }
  }
}

void ExampleWindow:n_button_file_clicked()
{
  Gtk::FileSelection dialog("lease choose a file");
  dialog.set_transient_for(*this);
  
  int result = dialog.run();

  //Handle the response:
  //处理返回值
  switch(result)
  {
    case(Gtk::RESPONSE_OK):
    {
      std::cout << "OK clicked." << std::endl;

      std::string filename = dialog.get_filename();
      //Notice that it is a std::string, not a Glib::ustring.
      //注意是std::string,而不是Glib::ustring。
      std::cout << "File selected: " <<  filename << std::endl;
      break;
    }
    case(Gtk::RESPONSE_CANCEL):
    {
      std::cout << "Cancel clicked." << std::endl;
      break;
    }
    default:
    {
      std::cout << "Unexpected button clicked." << std::endl;
      break;
    }
  }
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回

  return 0;
}
[/PHP]

颜色选择框

这个框体让用户选择一种颜色

参考文档

例子

图13.3 颜色选择框

源代码

文件: examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数
  virtual void on_button_color_set();

  //Child widgets:
  //子构件
  Gtk::VBox m_VBox;
  Gtk::ColorButton m_Button;
  Gtk:rawingArea m_DrawingArea;
  //To show the color.
  //显示颜色

  Gdk::Color m_Color;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"
#include <iostream>


ExampleWindow::ExampleWindow()
{
  set_title("Gtk::ColorButton example");
  set_default_size(200, 200);
  
  add(m_VBox);
  
  m_VBox.pack_start(m_Button, Gtk:ACK_SHRINK);
  m_Button.signal_color_set().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_color_set) );

  //Set start color:
  //设置开始颜色

  m_Color.set_red(0);
  m_Color.set_blue(65535);
  m_Color.set_green(0);
  m_Button.set_color(m_Color);
  
  m_DrawingArea.modify_bg(Gtk::STATE_NORMAL, m_Color);
  
  m_VBox.pack_start(m_DrawingArea);
  
  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow:n_button_color_set()
{  
  //Store the chosen color, and show it:
  //存储选择的颜色,并且显示它

  m_Color = m_Button.get_color();
  m_DrawingArea.modify_bg(Gtk::STATE_NORMAL, m_Color);
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回

  return 0;
}
[PHP]

字体选择框

这个框体让用户选择一种字体。

参考文档

例子

图13.4 字体选择框

源代码

文件: examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数
  virtual void on_button_font_set();

  //Child widgets:
  //子构件
  Gtk::FontButton m_Button;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"
#include <iostream>


ExampleWindow::ExampleWindow()
: m_Button("sans")
{
  set_title("Gtk::FontSelectionDialog example");
  
  add(m_Button);  
  m_Button.signal_font_set().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_font_set) );
  
  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_button_font_set()
{
  Glib::ustring font_name = m_Button.get_font_name();
  std::cout << "Font chosen: " << font_name << std::endl;
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回

  return 0;
}
[/PHP]
发表于 2004-4-4 19:42:16 | 显示全部楼层
这里是 sandbank 兄弟翻译的第十六章:

第十六章 剪贴板

简单的文本复制和粘贴功能可通过构件如 Gtk::Entry 和 Gtk::TextView 自由使用,但是你可能需要特别的代码来处理你自己的数据格式。例如,一个绘画的程序将需要特别的代码,可以让复制和粘贴在一个视图,或在文档间进行。

Gtk::Clipboard 是单独的。你可以使用 Gtk::Clipboard::get() 得到它和一个实体。

你的应用程序不需要等待剪贴板的操作,特别是用户选择复制,然后选择粘贴的这段时间。许多 Gtk::Clipboard 方法通过 sigc::slots 指定了返回的方法。当 Gtk::Clipboard 准备好了之后,它将会调用这些方法,或是提供要求的数据,或是要求数据。

参考文档

Targets
不同的应用程序含有不同类型的数据,而且他们可让这些数据变为不同的格式。gtkmmm将这些数据类型叫做targets。

例如,gedit能接收和支持 "UTF8_STRING" target,所以你能够从支持这个target的任何程序中粘贴数据到gedit中。或者两个不同的图像编辑程序可支持和接收一些不同的图像格式,它们是以targets形式出现的。只要一个程序能够接收另一个提供的targets中的一个,那么你就可以从一个程序向另一个复制数据。

一个target能以多种二进制格式出现。在这一章,和这些例子中,数据被假定是8位的文本格式。这可以让我们使用XML格式作为剪贴板的数据。然而,这可能对二进制数据如图像是不适合的。Gtk::Clipboard提供了负载,让你需要的话,可以在格式上指定更多的细节。

拖放操作的API使用相同的机制。你将可能在剪贴板和拖放操作中使用相同的数据targets和数据格式。


复制
当用户要求复制一些数据时,你将要告诉剪贴板什么target是有效的,并提供回调函数,让它用来取得数据。这样的话,你需要存储数据的一个副本,当剪贴板调用回调方法时,用来作为对粘贴操作的回应。

例如:
[PHP]
Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();

//Targets:
std::list<Gtk::TargetEntry> listTargets;
listTargets.push_back( Gtk::TargetEntry("example_custom_target") );
listTargets.push_back( Gtk::TargetEntry("UTF8_STRING") );
  
refClipboard->set( listTargets,
  sigc::mem_fun(*this, &ExampleWindow:n_clipboard_get),
  sigc::mem_fun(*this, &ExampleWindow:n_clipboard_clear) );

[/PHP]

当用户选择粘贴数据时,你的回调函数将提供存储的数据。例如:
[PHP]
void ExampleWindow:n_clipboard_get(Gtk::SelectionData& selection_data, guint info)
{
  const Glib::ustring& target = selection_data.get_target();
  
  if(target == "example_custom_target")
    selection_data.set("example_custom_target", m_ClipboardStore);
}
[/PHP]

下面的例子ideal能够支持多于一个的剪贴板target。

当剪贴板用其它的东西代替了它的数据时,这个清除回调函数让你释放内存,它是你存储的数据占用的。



粘贴

当用户从剪贴板获取要粘贴的数据时,你需要指定一个格式,并提供一个回调函数,它将和实际的数据一起被调用。例如:
[PHP]
refClipboard->request_contents("example_custom_target",  sigc::mem_fun(*this, &ExampleWindow:n_clipboard_received) );
[/PHP]
下面是回调函数的一个例子:
[PHP]
void ExampleWindow:n_clipboard_received(const Gtk::SelectionData& selection_data)
{
  Glib::ustring clipboard_data = selection_data.get_data_as_text();
  //Do something with the pasted data.
  //对粘贴的数据做相应的操作
}  
[/PHP]
发现一个有效的target
要从剪贴板上找出当前什么target是对粘贴有效的,请调用方法 request_methods() ,并指定一个和这个信息一起被调用的方法。例如:
[PHP]
refClipboard->request_targets( sigc::mem_fun(*this, &ExampleWindow:n_clipboard_received_targets) );
[/PHP]
在你的回调函数中,同有效的targets(使用他们可以让你的应用程序支持粘贴操作)的一个清单做个比较。你可以启用和禁用一个粘贴菜单项,这决定于粘贴操作当前是否有效。例如:
[PHP]
void ExampleWindow:n_clipboard_received_targets(const Gtk::SelectionData& selection_data)
{
  bool bPasteIsPossible = false;

  //Get the list of available clipboard targets:
  //得到有效剪贴板targets的清单

  typedef std::list<Glib::ustring> type_listTargets;
  type_listTargets targets = selection_data.get_targets();

  //and see if one is suitable:
  //检查它是否合适

  for(type_listTargets::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
  {
    if(*iter == "example_custom_target")
      bPasteIsPossible = true;
  }

  //Do something, depending on whether bPasteIsPossible is true.   
  //做些事情,决定于bPasteIsPossible是否为真。                                       
}
[/PHP]

例子

simple

这个例子允许复制和粘贴应用程序的特别的数据,使用的是标准的文本target。因为这只是一个例子,它并不太完美,当剪贴板的数据作为一种特别的类型时,它并不能识别出。

图 16.1 simple

源代码

文件: examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数

  virtual void on_button_copy();
  virtual void on_button_paste();
  virtual void on_clipboard_text_received(const Glib::ustring& text);

  //Child widgets:
  //子构件

  Gtk::VBox m_VBox;

  Gtk:abel m_Label;
  
  Gtk::Table m_Table;
  Gtk::ToggleButton m_ButtonA1, m_ButtonA2, m_ButtonB1, m_ButtonB2;

  Gtk::HButtonBox m_ButtonBox;
  Gtk::Button m_Button_Copy, m_Button_Paste;
};

#endif //GTKMM_EXAMPLEWINDOW_H
[/PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"

ExampleWindow::ExampleWindow()
: m_Label("Select cells in the table, click Copy, then open a second instance of this example to try pasting the copied data."),
  m_Table(2, 2, true),
  m_ButtonA1("A1"), m_ButtonA2("A2"), m_ButtonB1("B1"), m_ButtonB2("B2"),
  m_Button_Copy(Gtk::Stock::COPY), m_Button_Paste(Gtk::Stock:ASTE)
{                                                                                                
  set_title("Gtk::Clipboard example");
  set_border_width(12);                        

  add(m_VBox);

  m_VBox.pack_start(m_Label, Gtk:ACK_SHRINK);

  //Fill Table:
  //填充表

  m_VBox.pack_start(m_Table);
  m_Table.attach(m_ButtonA1, 0, 1, 0, 1);
  m_Table.attach(m_ButtonA2, 1, 2, 0, 1);
  m_Table.attach(m_ButtonB1, 0, 1, 1, 2);
  m_Table.attach(m_ButtonB2, 1, 2, 1, 2);

  //Add ButtonBox to bottom:
  //在底部增加ButtonBox

  m_VBox.pack_start(m_ButtonBox, Gtk:ACK_SHRINK);
  m_VBox.set_spacing(6);
  
  //Fill ButtonBox:
  //填充ButtonBox

  m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
  m_ButtonBox.pack_start(m_Button_Copy, Gtk:ACK_SHRINK);
  m_Button_Copy.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_copy) );
  m_ButtonBox.pack_start(m_Button_Paste, Gtk:ACK_SHRINK);
  m_Button_Paste.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow:n_button_paste) );
   
  show_all_children();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow:n_button_copy()
{
  //Build a string representation of the stuff to be copied:
  //建立一个要被复制的字符串的副本
  //Ideally you would use XML, with an XML parser here:
  //理想情况下,你会用到XML,这里使用了一个XML分析器

  Glib::ustring strData;
  strData += m_ButtonA1.get_active() ? "1" : "0";
  strData += m_ButtonA2.get_active() ? "1" : "0";
  strData += m_ButtonB1.get_active() ? "1" : "0";
  strData += m_ButtonB2.get_active() ? "1" : "0";
   
  Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
  refClipboard->set_text(strData);
}

void ExampleWindow::on_button_paste()
{        
  //Tell the clipboard to call our method when it is ready:
  //告诉剪贴板准备好了之后调用我们的方法

  Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
  refClipboard->request_text( sigc::mem_fun(*this, &ExampleWindow::on_clipboard_text_received) );
}

void ExampleWindow::on_clipboard_text_received(const Glib::ustring& text)
{
  //See comment in on_button_copy() about this silly clipboard format.
  //请看on_button_copy()中关于这个剪贴板格式的注释。

  if(text.size() >= 4)
  {
    m_ButtonA1.set_active( text[0] == '1' );
    m_ButtonA2.set_active( text[1] == '1' );
    m_ButtonB1.set_active( text[2] == '1' );
    m_ButtonB2.set_active( text[3] == '1' );
  }
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回。

  return 0;
}
[/PHP]


Ideal

这就像是例子simple, 但是它:

1.定义了一个自定义剪贴板target, 但是这个target的格式仍是文本。

2.它支持粘贴两个target - 自定义的和一个文本的,文本的创建了一个自定义数据的专门的文本替代品。

3.它使用 request_targets() ,并禁用Paste按钮(如果它不能使用剪贴板中的任何东西)。


图 16.2. Ideal

源代码

文件: examplewindow.h
[PHP]
#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  virtual ~ExampleWindow();

protected:
  //Signal handlers:
  //信号处理函数

  virtual void on_button_copy();
  virtual void on_button_paste();

  virtual void on_clipboard_get(Gtk::SelectionData& selection_data, guint info);
  virtual void on_clipboard_clear();

  virtual void on_clipboard_received(const Gtk::SelectionData& selection_data);
  virtual void on_clipboard_received_targets(const Glib::StringArrayHandle& targets_array);
   
  virtual void update_paste_status();
  //Disable the paste button if there is nothing to paste.
  //如果没有要粘贴的东西,则禁用粘贴按钮。

  //Child widgets:
  //子构件

  Gtk::VBox m_VBox;

  Gtk:abel m_Label;
  
  Gtk::Table m_Table;
  Gtk::ToggleButton m_ButtonA1, m_ButtonA2, m_ButtonB1, m_ButtonB2;

  Gtk::HButtonBox m_ButtonBox;
  Gtk::Button m_Button_Copy, m_Button_Paste;

  Glib::ustring m_ClipboardStore;
  //Keep copied stuff here, until it is pasted. This could be a big complex data structure.
  //保持要复制的东西在这里,直到它被粘贴了。这可能是一个很大很复杂的数据结构。
};

#endif //GTKMM_EXAMPLEWINDOW_H
[PHP]

文件: examplewindow.cc
[PHP]
#include "examplewindow.h"
#include <algorithm>


namespace
{

const char example_target_custom[] = "gtkmmclipboardexample";
const char example_target_text[]   = "UTF8_STRING";

} // anonymous namespace //匿名名字空间


ExampleWindow::ExampleWindow()
: m_Label("Select cells in the table, click Copy, then open a second instance "
          "of this example to try pasting the copied data.\nOr try pasting the "
          "text representation into gedit."),
  m_Table(2, 2, true),
  m_ButtonA1("A1"), m_ButtonA2("A2"), m_ButtonB1("B1"), m_ButtonB2("B2"),
  m_Button_Copy(Gtk::Stock::COPY), m_Button_Paste(Gtk::Stock:ASTE)
{                                                                                                
  set_title("Gtk::Clipboard example");
  set_border_width(12);                        

  add(m_VBox);

  m_VBox.pack_start(m_Label, Gtk:ACK_SHRINK);

  //Fill Table:
  //填充表
  m_VBox.pack_start(m_Table);
  m_Table.attach(m_ButtonA1, 0, 1, 0, 1);
  m_Table.attach(m_ButtonA2, 1, 2, 0, 1);
  m_Table.attach(m_ButtonB1, 0, 1, 1, 2);
  m_Table.attach(m_ButtonB2, 1, 2, 1, 2);

  //Add ButtonBox to bottom:
  //在底部增加ButtonBox

  m_VBox.pack_start(m_ButtonBox, Gtk:ACK_SHRINK);
  m_VBox.set_spacing(6);
  
  //Fill ButtonBox:
  //填充ButtonBox

  m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
  m_ButtonBox.pack_start(m_Button_Copy, Gtk:ACK_SHRINK);
  m_Button_Copy.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_copy) );
  m_ButtonBox.pack_start(m_Button_Paste, Gtk:ACK_SHRINK);
  m_Button_Paste.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_paste) );
   
  show_all_children();

  update_paste_status();
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_button_copy()
{
  //Build a string representation of the stuff to be copied:
  //建立一个要被复制的字符串的副本
  //Ideally you would use XML, with an XML parser here:
  //理想情况下,你会用到XML,这里使用了一个XML分析器

  Glib::ustring strData;
  strData += m_ButtonA1.get_active() ? "1" : "0";
  strData += m_ButtonA2.get_active() ? "1" : "0";
  strData += m_ButtonB1.get_active() ? "1" : "0";
  strData += m_ButtonB2.get_active() ? "1" : "0";

  //Store the copied data until it is pasted:
  //存储数据直到它被粘贴

  m_ClipboardStore = strData;
   
  Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();

  //Targets:
  std::list<Gtk::TargetEntry> listTargets;

  listTargets.push_back( Gtk::TargetEntry(example_target_custom) );
  listTargets.push_back( Gtk::TargetEntry(example_target_text) );
  
  refClipboard->set( listTargets, sigc::mem_fun(*this, &ExampleWindow::on_clipboard_get), sigc::mem_fun(*this, &ExampleWindow::on_clipboard_clear) );

  update_paste_status();
}

void ExampleWindow::on_button_paste()
{        
  //Tell the clipboard to call our method when it is ready:
  //告诉剪贴板准备好了后,调用我们的方法。

  Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();

  refClipboard->request_contents(example_target_custom,  sigc::mem_fun(*this, &ExampleWindow::on_clipboard_received) );

  update_paste_status();
}

void ExampleWindow::on_clipboard_get(Gtk::SelectionData& selection_data, guint)
{
  //info is meant to indicate the target, but it seems to be always 0,
  //so we use the selection_data's target instead.
  //到了指出target的时候了,但它看起来总是0,
  //所以我们使用 selection_data 的 target 代替。

  const std::string target = selection_data.get_target();

  if(target == example_target_custom)
  {
    // This set() override uses an 8-bit text format for the data.
    //这个set()对数据使用了8位文本格式。

    selection_data.set(example_target_custom, m_ClipboardStore);
  }
  else if(target == example_target_text)
  {
    //Build some arbitrary text representation of the data,
    //so that people see something when they paste into a text editor:
    //建立数据的专有的文本格式替代品,
    //所以当用户粘贴它们到文本编辑器中时,会看到一些东西。

    Glib::ustring text_representation;

    text_representation += m_ButtonA1.get_active() ? "A1, " : "";
    text_representation += m_ButtonA2.get_active() ? "A2, " : "";
    text_representation += m_ButtonB1.get_active() ? "B1, " : "";
    text_representation += m_ButtonB2.get_active() ? "B2, " : "";
                                          
    selection_data.set_text(text_representation);
  }
  else
  {
    g_warning("ExampleWindow::on_clipboard_get(): Unexpected clipboard target format.");
  }
}

void ExampleWindow::on_clipboard_clear()
{
  //This isn't really necessary. I guess it might save memory.
  //这其实不太需要,我猜它可能是节省内存。
  
  m_ClipboardStore.clear();
}

void ExampleWindow::on_clipboard_received(const Gtk::SelectionData& selection_data)
{
  const std::string target = selection_data.get_target();

  if(target == example_target_custom)
  //It should always be this, because that' what we asked for when calling request_contents().
  //它必须总这样,因为它是我们调用request_contents()时需要的。

  {
    Glib::ustring clipboard_data = selection_data.get_data_as_string();

    //See comment in on_button_copy() about this silly clipboard format.
    //请看on_button_copy()中关于这个剪贴板格式的注释。

    if(clipboard_data.size() >= 4)
    {
      m_ButtonA1.set_active( clipboard_data[0] == '1' );
      m_ButtonA2.set_active( clipboard_data[1] == '1' );
      m_ButtonB1.set_active( clipboard_data[2] == '1' );
      m_ButtonB2.set_active( clipboard_data[3] == '1' );
    }
  }
}

void ExampleWindow::update_paste_status()
{
  //Disable the paste button if there is nothing to paste.
  //如果没有要粘贴的东西,则禁用粘贴按钮。
  
  Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();

  //Discover what targets are available:
  //发现什么targets是有效的。

  refClipboard->request_targets( sigc::mem_fun(*this, &ExampleWindow::on_clipboard_received_targets) );
}

void ExampleWindow::on_clipboard_received_targets(const Glib::StringArrayHandle& targets_array)
{
  // Get the list of available clipboard targets:
  //得到有效剪贴板targets的清单。

  const std::list<std::string> targets (targets_array);

  const bool bPasteIsPossible =
      std::find(targets.begin(), targets.end(), example_target_custom) != targets.end();

  // Enable/Disable the Paste button appropriately:
  // 相应地 启用/禁用 按钮Paste。

  m_Button_Paste.set_sensitive(bPasteIsPossible);
}
[/PHP]

文件: main.cc
[PHP]
#include <gtkmm/main.h>
#include "examplewindow.h"

int main(int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  ExampleWindow window;
  Gtk::Main::run(window);
  //Shows the window and returns when it is closed.
  //显示窗体,当它关闭时返回。

  return 0;
}
[/PHP]
发表于 2004-4-9 10:45:53 | 显示全部楼层
顶一下
发表于 2004-4-11 20:27:17 | 显示全部楼层
今天有时间
又翻译了一些
还剩两章
估计明天就可以译完了

贴在这里看起来也不方便
等整理好了再打包放上来吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表