`
chinamming
  • 浏览: 151397 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

第七章 在FLTK中自定义控件

 
阅读更多

定制图形控件说明

新控件的创建是通过继承已经存在的控件来得到的,一般控件继承Fl_Widget得到,组合控件继承Fl_Group得到

一个普通控件一般通过接收和显示一个值来与用户交互

一个组合控件包含一组子控件并处理子控件的移动,改变大小,显示或隐藏事件。Fl_Group是所有组合控件的基类,其他组合控件比如Fl_Pack, Fl_Scroll, Fl_Tabs , Fl_Tile, Fl_Window都是他的子类

你也可以通过继承其他的已存在控件来得到你要的控件,通过提供不同的外观和接口。比如Button 控件都是 Fl_Button类的子类。他们的共同点是都是通过鼠标点击事件与用户交互。唯一不同的是按钮的外观。

如何开发一个控件的子类

你的子类可以直接继承Fl_Widget 类,也可以继承任何Fl_Widget类的子类。Fl_Widget只有四个虚拟函数,子类必须重载所有的或部分的这些函数。

构造函数

构造函数应该有以下参数

MyClass(int x, int y, int w, int h, const char *label = 0);

这就允许该类能很好的应用于FLUID

这个构造函数必须调用基类的构造函数并传递相同的参数

MyClass::MyClass(int x, int y, int w, int h, const char *label)
: Fl_Widget(x, y, w, h, label) {
// do initialization stuff...
}

Fl_Widget的保护构造函数通过传递的参数x,y,w,h,label分别设置x(),y(),w(),h()label()并初始化其他的属性如:

type(0);

box(FL_NO_BOX);

color(FL_BACKGROUND_COLOR);

selection_color(FL_BACKGROUND_COLOR);

labeltype(FL_NORMAL_LABEL);

labelstyle(FL_NORMAL_STYLE);

labelsize(FL_NORMAL_SIZE);

labelcolor(FL_FOREGROUND_COLOR);

align(FL_ALIGN_CENTER);

callback(default_callback,0);

flags(ACTIVE|VISIBLE);

image(0);

deimage(0);

Fl_Widget的保护成员函数

以下的成员函数是Fl_Widget提供给子类的:

Fl_Widget::clear_visible

Fl_Widget::damage

Fl_Widget::draw_box

Fl_Widget::draw_focus

Fl_Widget::draw_label

Fl_Widget::set_flag

Fl_Widget::set_visible

Fl_Widget::test_shortcut

Fl_Widget::type

void Fl_Widget::damage(uchar mask)
void Fl_Widget::damage(uchar mask, int x, int y, int w, int h)
uchar Fl_Widget::damage()

第一个函数是指对象的部分需要更新。参数mask中的位设置传递给damage().draw()函数能根据该值得到哪些需要重画。公共成员函数Fl_Widget::redraw()只是简单的做Fl_Widget::damage(FL_DAMAGE_ALL),即所有的都重画,但是你的控件真正执行的时候会调用私有成员函数damage(n).

第二个函数指某个区域无效,需要重画。

第三个函数返回所有damage(n)的调用所产生的位。

当重新画一个控件时,你应该先看看无效位,再决定你的控件的哪部分需要重新画。Handle()函数能够设置单独的无效位限制需要重画的数量。

MyClass::handle(int event) {

...

if (change_to_part1) damage(1);

if (change_to_part2) damage(2);

if (change_to_part3) damage(4);

}

MyClass::draw() {

if (damage() & FL_DAMAGE_ALL) {

... draw frame/box and other static stuff ...

}

if (damage() & (FL_DAMAGE_ALL | 1)) draw_part1();

if (damage() & (FL_DAMAGE_ALL | 2)) draw_part2();

if (damage() & (FL_DAMAGE_ALL | 4)) draw_part3();

}

void Fl_Widget::draw_box() const

第一个函数根据该控件的尺度画他的box().第二个函数根据box的类型b ,颜色cbox.

void Fl_Widget::draw_focus() const
void Fl_Widget::draw_focus(Fl_Boxtype b, int x, int y, int w, int h) const

在一个空间的限制box中画出焦点筐。第二个函数允许指定另一个不同box来画焦点

Fl_Widget::draw_label() const
void Fl_Widget::draw_label(int x, int y, int w, int h) const
void Fl_Widget::draw_label(int x, int y, int w, int h, Fl_Align align) const

Draw()函数调用该函数来画一个控件的label,如果标签出了该控件的box 范围,将不会被画出。

第二种形式自定义一个box来画标签,比如用于移动的滑块

第三种形式可以将标签画在任意的地方

void Fl_Widget::set_visible()
void Fl_Widget::clear_visible()

Fl_Widget::show() Fl_Widget::hide()作用相同,但不发送FL_SHOW,FL_HIDE事件。

int Fl_Widget::test_shortcut() const
static int Fl_Widget::test_shortcut(const char *s)

uchar Fl_Widget::type() const
void Fl_Widget::type(uchar t)

返回一个8位的标示符,用于与Forms兼容,你也可以同于其他任何目的,设置的值应该小于100,以免与系统的保留值冲突

处理事件

虚拟函数int handle(int event)被用来处理任何发送给控件的事件.他能:

改变控件的状态

调用Fl_Widget::redraw()如果该控件需要重新显示

调用Fl_Widget::damage(n)当控件需要部分更新时(假如你在Fl_Widget::draw()函数中提供了对该函数的支持)

调用Fl_Widget::do_callback()如果一个回调函数产生时.

调用Fl_Widget::handle()对子控件

事件用一个整数来标识.最近事件产生的其他消息静态存储在本地,调用Fl::event_*()可以得到.

以下是一个利用handle()处理事件的例子,该控件的行为类似按钮同时接收x按键并调用回调函数

int MyClass::handle(int event) {

switch(event) {

case FL_PUSH:

highlight = 1;

redraw();

return 1;

case FL_DRAG: {

int t = Fl::event_inside(this);

if (t != highlight) {

highlight = t;

redraw();

}

}

return 1;

case FL_RELEASE:

if (highlight) {

highlight = 0;

redraw();

do_callback();

// never do anything after a callback, as the callback

// may delete the widget!

}

return 1;

case FL_SHORTCUT:

if (Fl::event_key() == 'x') {

do_callback();

return 1;

}

return 0;

default:

return Fl_Widget::handle(event);

}

}

当你的handle()函数处理某事件后不能返回0,若是返回0,父控件将会把该事件发送给其他控件。

画控件

FLTK需要重画控件时将调用虚拟函数draw().只有在damage()返回非0值时调用该函数,draw()返回后,damage()被清0Draw()应该被声明为保护成员函数,避免在不需要写画图代码时用到。

Damage()将包含从最后一次调用draw()damage(n)调用产生的所有与或位信息,根据该信息只重画需要重画的位置,只有FLTK认为需要全部重画时才打开FL_DAMAGE_ALL位,比如收到expose事件。

修改控件的尺寸

resize(int x,int y,int w,int h)在控件被移动和改变大小时被调用,这些参数分别是新位置,宽度和高度。但是x(),y(),w(),h(),还是以前的值,若要改变这些值,必须在基类中也调用resize()函数

不需要调用redraw()函数,至少只改变x(),y()时不需要,因为一个组合控件有一套更有效的方法来画新的位置

如何制作一个组合控件

一个组合控件包括一个或多个子控件。制作组合控件必须继承Fl_Group.不继承Fl_Group类当然也可能可以制作一个组合控件,但是你还是要重新写Fl_Group类里面的工作

子控件可能在类里面声明

class MyClass : public Fl_Group {

Fl_Button the_button;

Fl_Slider the_slider;

...

};

构造函数要初始化这些子控件。他们将被自动的add()group中。因为Fl_Group构造函数调用了begin().在构造函数中不要忘记调用end()函数

MyClass::MyClass(int x, int y, int w, int h) :

Fl_Group(x, y, w, h),

the_button(x + 5, y + 5, 100, 20),

the_slider(x, y + 50, w, 20)

{

...(you could add dynamically created child widgets here)...

end(); // don't forget to do this!

}

分享到:
评论

相关推荐

    FLTK自定义拖拽控件实现窗口分割

    本文主要介绍了在FLTK中如何自定义一个窗口分割控件,实现窗口的布局,该控件可以实现拖拉窗口和隐藏侧边栏功能。

    FLTK自定义拖拽控件实现窗口分割共11页.pdf.zip

    在本文档“FLTK自定义拖拽控件实现窗口分割共11页.pdf”的内容中,我们将深入探讨如何利用FLTK库来创建自定义的拖拽控件,以实现窗口的动态分割功能。 首先,FLTK库提供了丰富的基本控件,如按钮、文本输入框、窗口...

    fltk中文手册

    - **自定义控件**:教授如何扩展FLTK控件,实现个性化功能。 - **多线程支持**:介绍FLTK如何在多线程环境下工作,以及如何安全地更新GUI。 #### 实践案例 - **项目实战**:通过一系列实际项目,如音乐播放器、...

    fltk教程-中文文档

    2. **自定义性强**:FLTK允许开发者深度定制界面外观和行为,实现个性化应用。 3. **移植性好**:跨平台的特性使得应用可以在多种操作系统上运行,扩大了软件的适用范围。 通过这个中文教程,初学者不仅可以了解...

    基于FLTK的小钟

    在“基于FLTK的小钟”项目中,`Fl_Clock`可能是一个自定义的类,继承自FLTK的某个控件,用于显示时间。开发者可能会在该类中实现时钟的绘制逻辑,根据系统时间实时更新时钟显示。`www.pudn.com.txt`可能是项目资料或...

    FLTK.rar_FLTK_fltk怎么用

    7. **控件和布局**:FLTK允许你创建各种控件,如按钮、输入框、复选框等,并通过布局管理器(如Fl_Group和Fl_Browser)来组织它们。例如,可以添加一个按钮到窗口: ```cpp Fl_Button* button = new Fl_Button(100...

    fltk 总体架构及类的关系

    在FLTK中,控件可以嵌套在其他控件中,形成复杂布局。 4. **Fl_Menu**和**Fl_Menu_Item**:这两类是菜单和菜单项的实现,用于创建下拉菜单和弹出式菜单。 5. **Fl_Box**:基础的绘图容器,可以用来绘制简单的几何...

    多本fltk学习资料

    第二本书可能进一步探讨了FLTK的中级主题,比如布局管理、自定义控件和图形绘制。读者会学到如何更有效地组织用户界面元素,以及如何利用FLTK的绘图功能实现复杂的视觉效果。此外,书中的示例代码和实践项目能帮助...

    fltk-1.1.7-source.zip_FLTK_fltk windo_fltk-1.1.7_轻量级ui

    标题中的"fltk-1.1.7-source.zip_FLTK_fltk windo_fltk-1.1.7_轻量级ui"指的是FLTK的1.1.7版本源码包,适用于创建窗口应用,尤其强调了它的跨平台特性,能够在Windows和Linux等操作系统上运行。 FLTK设计的核心理念...

    fltk-1.3.9 使用VS2022编译好的库

    2. **链接库依赖**: 在链接器设置中,添加FLTK库(如fltk.lib, fltk_images.lib等)。 3. **运行时库匹配**: 确保FLTK库和你的项目使用相同的C++运行时库配置(多线程动态或静态链接)。 4. **头文件和库文件位置**:...

    FLTK使用小例子(FLTK—1.1.7)

    在FLTK中,你可以通过创建窗口、控件(如按钮)、并设置它们的属性和事件处理器来构建用户界面。在这个例子中,我们可能有一个主窗口,然后在窗口内添加了一个Button控件。当用户按下或释放按钮时,FLTK会触发相应的...

    fltk-1.4 使用VS2022编译好的库

    7. **自绘控件**:FLTK允许开发者自定义控件的外观,实现独特的界面设计。 8. **可扩展性**:FLTK的模块化设计使得添加新功能或扩展现有功能变得容易。 对于使用Visual Studio 2022的开发者来说,预编译的FLTK库...

    FLTK 1.3.2 - FLTK Programming Manual

    - **图像绘制**:如何在FLTK中加载和显示图像。 #### 五、设计一个简单的文本编辑器 本章通过设计并实现一个简单的文本编辑器来演示FLTK的实际应用。主要内容包括: - **布局设计**:如何布局编辑器的界面元素。 - ...

    FLTK.rar_FLTK_FLTK嵌入式开发

    在控件方面,FLTK提供了常见的GUI元素,如按钮、文本输入框、滚动条、复选框、单选按钮、滑块、进度条、菜单、对话框等。这些控件易于使用,可以通过简单的API调用来创建和配置。此外,FLTK还支持自定义绘图,允许...

    FLTK user manual

    此外,FLTK还拥有绘制图形和图像的功能,用户可以在窗口中直接绘制所需的元素。 FLTK的开发始于1998年,并持续更新至FLTK 1.3.3版本,由多位贡献者编写和维护。FLTK的程序手册版权归属于Bill Spitzak和其他人,整个...

    FLTK电子教程.PDF

    在【描述】中提及的FLTK v1.3.5版本,说明这份教程是关于FLTK的1.3.5版本的指导材料。FLTK 1.3.5版本作为教程中使用的特定版本,意味着其中介绍的所有功能和方法都是基于这一版本进行讲解的。 【标签】中的“c++ ...

Global site tag (gtag.js) - Google Analytics