📚 写在前面
FLTK(Fast Light Toolkit)是一个轻量级的跨平台 C++ GUI 库,以其小巧、快速和易用著称。与 Qt 或 wxWidgets 相比,FLTK 的整个库大小只有几 MB,非常适合嵌入式系统、工具软件开发以及需要快速原型设计的场景。
本文将从基础到进阶,全面介绍 FLTK 的核心控件体系,帮助你在实际项目中灵活运用。
🎯 控件继承体系概览
FLTK 采用经典的面向对象设计,所有控件都继承自 Fl_Widget 基类:
Fl_Widget (抽象基类)
├── Fl_Box # 静态盒子(标签、分隔线)
├── Fl_Button # 按钮基类
│ ├── Fl_Button # 普通按钮
│ ├── Fl_Toggle_Button # 开关按钮
│ ├── Fl_Check_Button # 复选框
│ └── Fl_Radio_Button # 单选按钮
├── Fl_Input_ # 输入控件基类
│ ├── Fl_Input # 单行输入框
│ ├── Fl_Int_Input # 整数输入框
│ ├── Fl_Float_Input # 浮点数输入框
│ └── Fl_Text_Editor # 多行文本编辑器
├── Fl_Valuator # 数值调节控件基类
│ ├── Fl_Slider # 滑块
│ ├── Fl_Scrollbar # 滚动条
│ ├── Fl_Dial # 旋钮
│ └── Fl_Counter # 计数器
├── Fl_Group # 容器基类
│ ├── Fl_Window # 窗口
│ ├── Fl_Scroll # 滚动区域
│ ├── Fl_Tabs # 标签页
│ ├── Fl_Pack # 自动布局容器
│ └── Fl_Table # 表格控件
├── Fl_Browser # 文件/列表浏览器
├── Fl_Menu_Bar # 菜单栏
├── Fl_Tree # 树形控件
├── Fl_Progress # 进度条
└── Fl_Help_View # HTML帮助视图
🎨 基础显示控件
1. Fl_Box —— 最简洁的静态控件
Fl_Box 是 FLTK 中最简单的控件,仅用于显示文本或图形,不响应用户交互。
核心特性:
- 纯展示性控件,不可点击
- 支持各种边框样式
- 可作为布局占位符或分隔线
常用方法:
Fl_Box* box = new Fl_Box(x, y, w, h, "label"); box->box(FL_UP_BOX); // 设置边框样式 box->labelsize(16); // 字体大小 box->labelfont(FL_BOLD); // 字体样式 box->labelcolor(FL_RED); // 文字颜色 box->align(FL_ALIGN_CENTER); // 对齐方式
边框样式枚举:
FL_NO_BOX– 无边框FL_FLAT_BOX– 扁平边框FL_UP_BOX– 凸起效果FL_DOWN_BOX– 凹陷效果FL_ROUNDED_BOX– 圆角边框FL_SHADOW_BOX– 阴影效果
代码示例:
// 创建各种样式的盒子 Fl_Box* title = new Fl_Box(50, 10, 200, 30, "应用程序标题"); title->box(FL_FLAT_BOX); title->labelsize(20); title->labelfont(FL_BOLD); Fl_Box* separator = new Fl_Box(50, 50, 300, 5, ""); separator->box(FL_THIN_DOWN_BOX); Fl_Box* content = new Fl_Box(50, 70, 300, 100, "这里是内容区域"); content->box(FL_ENGRAVED_BOX); content->align(FL_ALIGN_INSIDE | FL_ALIGN_TOP_LEFT);
🔘 按钮控件家族
2. Fl_Button —— 标准按钮
最基本的交互控件,用户点击时触发回调函数。
核心特性:
- 支持按下/释放状态
- 可设置快捷键
- 支持工具提示
常用方法:
Fl_Button* btn = new Fl_Button(x, y, w, h, "按钮文字");
btn->callback(my_callback, data); // 设置回调
btn->shortcut(FL_CTRL + 's'); // 快捷键 Ctrl+S
btn->tooltip("这是提示文本"); // 鼠标悬停提示
btn->setonly(); // 设置为默认按钮(回车触发)
btn->value(1); // 设置按下状态
代码示例:
// 回调函数
void on_click(Fl_Widget* w, void* data) {
Fl_Button* btn = (Fl_Button*)w;
fl_message("按钮被点击了!当前标签:%s", btn->label());
}
// 创建按钮
Fl_Button* btn1 = new Fl_Button(50, 50, 100, 30, "点我");
btn1->callback(on_click);
Fl_Button* btn2 = new Fl_Button(50, 100, 100, 30, "退出");
btn2->callback([](Fl_Widget*, void* data) {
((Fl_Window*)data)->hide(); // 使用 lambda 关闭窗口
}, window);
3. Fl_Toggle_Button —— 开关按钮
按压后保持状态,再次按压才弹起。
代码示例:
Fl_Toggle_Button* toggle = new Fl_Toggle_Button(50, 50, 100, 30, "开关");
toggle->callback([](Fl_Widget* w, void*) {
Fl_Toggle_Button* btn = (Fl_Toggle_Button*)w;
if (btn->value()) {
fl_message("开关已打开");
} else {
fl_message("开关已关闭");
}
});
4. Fl_Check_Button —— 复选框
多选场景,通常多个复选框组合使用。
代码示例:
Fl_Check_Button* opt1 = new Fl_Check_Button(50, 50, 120, 25, "选项一"); Fl_Check_Button* opt2 = new Fl_Check_Button(50, 80, 120, 25, "选项二"); Fl_Check_Button* opt3 = new Fl_Check_Button(50, 110, 120, 25, "选项三"); // 获取选中状态 bool isChecked = opt1->value();
5. Fl_Radio_Button —— 单选按钮
互斥选择,同一组的单选按钮只有一个能被选中。
代码示例:
// 方法1:使用 Fl_Group 管理分组 Fl_Group* group = new Fl_Group(50, 50, 150, 100); group->begin(); Fl_Radio_Button* radio1 = new Fl_Radio_Button(50, 50, 100, 25, "选项 A"); Fl_Radio_Button* radio2 = new Fl_Radio_Button(50, 80, 100, 25, "选项 B"); Fl_Radio_Button* radio3 = new Fl_Radio_Button(50, 110, 100, 25, "选项 C"); group->end(); // 方法2:使用 Fl_Radio_Round_Button 获得圆形外观 Fl_Radio_Round_Button* radio_r1 = new Fl_Radio_Round_Button(200, 50, 100, 25, "圆形选项");
📝 文本输入控件
6. Fl_Input —— 单行文本输入
常用方法:
Fl_Input* input = new Fl_Input(x, y, w, h, "标签");
input->value("默认文本"); // 设置/获取文本
input->maximum_size(100); // 最大字符数
input->readonly(1); // 只读模式
input->password(1); // 密码模式(显示星号)
input->wrap(1); // 自动换行
代码示例:
// 用户名输入框 Fl_Input* username = new Fl_Input(120, 50, 150, 25, "用户名:"); // 密码输入框 Fl_Input* password = new Fl_Input(120, 90, 150, 25, "密码:"); password->password(1); // 只读显示框 Fl_Input* display = new Fl_Input(120, 130, 150, 25, "结果:"); display->readonly(1);
7. Fl_Int_Input & Fl_Float_Input —— 数字输入
自动校验输入内容,只能输入数字。
代码示例:
Fl_Int_Input* age = new Fl_Int_Input(120, 50, 100, 25, "年龄:");
age->value("18");
Fl_Float_Input* price = new Fl_Float_Input(120, 90, 100, 25, "价格:");
price->value("99.99");
8. Fl_Text_Editor —— 多行文本编辑器
功能丰富的文本编辑控件,支持选择、复制、粘贴等操作。
代码示例:
// 创建文本编辑器
Fl_Text_Editor* editor = new Fl_Text_Editor(50, 50, 400, 300);
Fl_Text_Buffer* buffer = new Fl_Text_Buffer(); // 文本缓冲区
editor->buffer(buffer); // 绑定缓冲区
// 设置初始文本
buffer->text("这是多行文本编辑器\n支持换行\n可以编辑大量内容");
// 设置编辑器样式
editor->textfont(FL_COURIER); // 等宽字体
editor->textsize(12); // 字体大小
editor->wrap_mode(Fl_Text_Editor::WRAP_AT_BOUNDS, 0); // 自动换行
🎚️ 数值调节控件
9. Fl_Slider —— 滑块
用于在范围内选择数值,支持水平和垂直方向。
常用方法:
Fl_Slider* slider = new Fl_Slider(x, y, w, h, "标签"); slider->bounds(0, 100); // 设置取值范围 slider->value(50); // 设置当前值 slider->step(1); // 设置步长 slider->slider_size(0.1); // 滑块大小比例
滑块类型枚举:
FL_VERTICAL– 垂直滑块FL_HORIZONTAL– 水平滑块FL_VERT_FILL_SLIDER– 填充式垂直滑块FL_HOR_FILL_SLIDER– 填充式水平滑块FL_VERT_NICE_SLIDER– 精美样式垂直滑块FL_HOR_NICE_SLIDER– 精美样式水平滑块
代码示例:
// 水平滑块
Fl_Slider* h_slider = new Fl_Slider(50, 50, 200, 20, "音量");
h_slider->type(FL_HORIZONTAL);
h_slider->bounds(0, 100);
h_slider->value(50);
// 带数值显示的滑块
Fl_Value_Slider* v_slider = new Fl_Value_Slider(50, 100, 200, 25, "亮度");
v_slider->bounds(0, 100);
v_slider->callback([](Fl_Widget* w, void*) {
Fl_Value_Slider* s = (Fl_Value_Slider*)w;
printf("当前值: %.1f\n", s->value());
});
10. Fl_Dial —— 旋钮控件
圆形旋钮,通过旋转来调节数值。
代码示例:
Fl_Dial* dial = new Fl_Dial(50, 50, 80, 80, "音量"); dial->bounds(0, 100); dial->value(50); dial->step(1);
11. Fl_Counter —— 计数器
带有加减按钮的数值调节控件。
代码示例:
Fl_Counter* counter = new Fl_Counter(50, 50, 120, 25, "数量:");
counter->bounds(1, 99);
counter->value(1);
counter->step(1);
counter->lstep(10); // 点击按钮时的步进值
counter->callback([](Fl_Widget* w, void*) {
Fl_Counter* c = (Fl_Counter*)w;
fl_message("当前数量: %d", (int)c->value());
});
12. Fl_Scrollbar —— 滚动条
用于滚动区域的控制器,通常与 Fl_Scroll 配合使用。
📦 容器控件
13. Fl_Window —— 顶层窗口
所有 FLTK 程序的根容器,代表一个操作系统窗口。
代码示例:
// 标准窗口 Fl_Window* win = new Fl_Window(800, 600, "我的应用程序"); // 无边框窗口 Fl_Window* frameless = new Fl_Window(800, 600, "无边框窗口"); frameless->border(0); // 移除边框 // 模态对话框 Fl_Window* dialog = new Fl_Window(300, 200, "提示"); dialog->set_modal(); // 设置为模态
14. Fl_Group —— 基础容器
用于将多个控件组合在一起,支持批量操作和布局管理。
代码示例:
Fl_Group* group = new Fl_Group(50, 50, 300, 150, "控制面板"); group->box(FL_ENGRAVED_BOX); group->begin(); // 添加控件到组内 Fl_Button* btn1 = new Fl_Button(60, 70, 80, 30, "按钮1"); Fl_Button* btn2 = new Fl_Button(150, 70, 80, 30, "按钮2"); Fl_Button* btn3 = new Fl_Button(240, 70, 80, 30, "按钮3"); group->end(); // 批量操作 group->deactivate(); // 禁用组内所有控件 group->activate(); // 启用组内所有控件
15. Fl_Scroll —— 滚动区域
当内容超出可视区域时自动显示滚动条。
代码示例:
Fl_Scroll* scroll = new Fl_Scroll(50, 50, 400, 300);
scroll->type(Fl_Scroll::BOTH); // 水平和垂直滚动
scroll->begin();
// 添加大量内容
for (int i = 0; i < 20; i++) {
char label[32];
snprintf(label, sizeof(label), "项目 %d", i + 1);
new Fl_Button(10, i * 35, 100, 25, label);
}
new Fl_Box(10, 800, 100, 25, "底部内容");
scroll->end();
16. Fl_Tabs —— 标签页容器
管理多个页面,通过点击标签切换。
代码示例:
Fl_Tabs* tabs = new Fl_Tabs(50, 50, 400, 300); // 第一个标签页 Fl_Group* tab1 = new Fl_Group(50, 80, 400, 270, "基本设置"); tab1->begin(); Fl_Button* btn1 = new Fl_Button(60, 100, 100, 30, "按钮1"); Fl_Input* input1 = new Fl_Input(60, 150, 200, 25, "输入框:"); tab1->end(); // 第二个标签页 Fl_Group* tab2 = new Fl_Group(50, 80, 400, 270, "高级设置"); tab2->begin(); Fl_Check_Button* check1 = new Fl_Check_Button(60, 100, 120, 25, "启用高级功能"); Fl_Slider* slider1 = new Fl_Slider(60, 150, 200, 20, "阀值:"); tab2->end(); tabs->end();
17. Fl_Pack —— 自动布局容器
自动排列子控件,支持水平和垂直方向。
代码示例:
// 垂直布局
Fl_Pack* vpack = new Fl_Pack(50, 50, 200, 200);
vpack->type(Fl_Pack::VERTICAL);
vpack->spacing(10); // 间距
vpack->begin();
for (int i = 0; i < 5; i++) {
char label[32];
snprintf(label, sizeof(label), "按钮 %d", i + 1);
new Fl_Button(0, 0, 180, 30, label);
}
vpack->end();
// 水平布局
Fl_Pack* hpack = new Fl_Pack(280, 50, 300, 50);
hpack->type(Fl_Pack::HORIZONTAL);
hpack->begin();
new Fl_Button(0, 0, 80, 30, "确定");
new Fl_Button(0, 0, 80, 30, "取消");
new Fl_Button(0, 0, 80, 30, "应用");
hpack->end();
18. Fl_Table —— 表格控件
功能强大的表格控件,支持自定义绘制。你之前的 CDDTS Agent 程序已经用到了这个控件。
🌲 其他实用控件
19. Fl_Browser —— 文件/列表浏览器
用于显示文件列表或选项列表。
代码示例:
Fl_Browser* browser = new Fl_Browser(50, 50, 200, 300);
browser->type(FL_HOLD_BROWSER); // 单选模式
// 添加项目
browser->add("项目 1");
browser->add("项目 2");
browser->add("项目 3");
// 设置回调
browser->callback([](Fl_Widget* w, void*) {
Fl_Browser* b = (Fl_Browser*)w;
int index = b->value(); // 获取选中项索引
const char* text = b->text(index); // 获取选中项文本
fl_message("选中: %s", text);
});
// 文件浏览器模式
browser->type(FL_MULTI_BROWSER); // 多选模式
browser->type(FL_SELECT_BROWSER); // 单选模式
browser->type(FL_HOLD_BROWSER); // 保持高亮模式
20. Fl_Menu_Bar —— 菜单栏
创建应用程序的标准菜单栏。
代码示例:
Fl_Menu_Bar* menubar = new Fl_Menu_Bar(0, 0, 800, 25);
// 添加菜单项
menubar->add("文件/新建", FL_CTRL + 'n', menu_callback, (void*)"new");
menubar->add("文件/打开", FL_CTRL + 'o', menu_callback, (void*)"open");
menubar->add("文件/保存", FL_CTRL + 's', menu_callback, (void*)"save");
menubar->add("文件/分隔线");
menubar->add("文件/退出", FL_CTRL + 'q', [](Fl_Widget*, void*) {
exit(0);
});
menubar->add("编辑/复制", FL_CTRL + 'c', menu_callback);
menubar->add("编辑/粘贴", FL_CTRL + 'v', menu_callback);
menubar->add("帮助/关于", 0, about_callback);
21. Fl_Progress —— 进度条
显示任务完成进度。
代码示例:
Fl_Progress* progress = new Fl_Progress(50, 50, 300, 25);
progress->bounds(0, 100);
progress->value(0);
progress->color(FL_GREEN);
progress->selection_color(FL_DARK_GREEN);
// 模拟进度更新
void update_progress(Fl_Progress* p, int target) {
for (int i = 0; i <= target; i++) {
p->value(i);
Fl::check(); // 更新界面
Fl::wait(0.05); // 延迟
}
}
22. Fl_Tree —— 树形控件
用于展示层次结构数据。
代码示例:
Fl_Tree* tree = new Fl_Tree(50, 50, 200, 300);
tree->showroot(1); // 显示根节点
// 添加节点
Fl_Tree_Item* root = tree->root();
Fl_Tree_Item* item1 = tree->add("根节点/子项1");
Fl_Tree_Item* item2 = tree->add("根节点/子项2");
Fl_Tree_Item* sub1 = tree->add("根节点/子项1/孙项1");
// 设置回调
tree->callback([](Fl_Widget* w, void*) {
Fl_Tree* t = (Fl_Tree*)w;
Fl_Tree_Item* item = t->callback_item();
if (item) {
fl_message("选中: %s", item->label());
}
});
23. Fl_Help_View —— HTML 帮助视图
显示富文本内容(支持简单的 HTML)。
代码示例:
Fl_Help_View* help = new Fl_Help_View(50, 50, 400, 300);
help->load("help.html"); // 从文件加载
// 或直接设置 HTML 内容
help->value("<h1>帮助文档</h1><p>这是<b>FLTK</b>应用程序的帮助内容</p>");
24. Fl_Chart —— 图表控件
简单图表绘制控件。
代码示例:
Fl_Chart* chart = new Fl_Chart(50, 50, 300, 200); chart->type(FL_BAR_CHART); // 条形图 // chart->type(FL_LINE_CHART); // 折线图 // chart->type(FL_FILL_CHART); // 填充图 // chart->type(FL_SPIKE_CHART); // 脉冲图 chart->add(30, "Jan"); chart->add(45, "Feb"); chart->add(58, "Mar"); chart->add(42, "Apr"); chart->add(67, "May"); chart->maxnum(10); // 最大数据点数 chart->bounds(0, 100); // 取值范围
🎯 控件通用属性
所有 FLTK 控件都继承自 Fl_Widget,因此都具备以下通用属性和方法:
位置和大小
widget->resize(x, y, w, h); // 改变位置和大小 widget->x(); widget->y(); // 获取位置 widget->w(); widget->h(); // 获取大小
标签和文字
cpp
widget->label("新标签"); // 设置标签
widget->copy_label("副本"); // 复制标签(深拷贝)
widget->labelcolor(FL_RED); // 标签颜色
widget->labelsize(14); // 标签字体大小
widget->labelfont(FL_BOLD); // 标签字体样式
widget->align(FL_ALIGN_CENTER); // 对齐方式
颜色和样式
widget->color(FL_BLUE); // 背景色 widget->selection_color(FL_RED); // 选中/激活时的颜色 widget->labelcolor(FL_WHITE); // 文字颜色 widget->box(FL_UP_BOX); // 边框样式
状态管理
widget->show(); // 显示 widget->hide(); // 隐藏 widget->activate(); // 启用 widget->deactivate(); // 禁用 widget->visible(); // 是否可见 widget->active(); // 是否可用
事件回调
widget->callback(my_callback, user_data); // 设置回调函数 widget->do_callback(); // 触发回调 widget->when(FL_WHEN_CHANGED); // 设置触发时机
when() 的可选值:
FL_WHEN_NEVER– 从不触发FL_WHEN_CHANGED– 值改变时触发FL_WHEN_RELEASE– 鼠标释放时触发FL_WHEN_ENTER_KEY– 按下回车键时触发
💡 实用技巧和最佳实践
1. 使用智能指针管理控件
#include <memory> std::unique_ptr<Fl_Window> window(new Fl_Window(800, 600, "App"));
2. 批量设置控件样式
void set_widget_style(Fl_Widget* w, int size, Fl_Font font, Fl_Color color) {
w->labelsize(size);
w->labelfont(font);
w->labelcolor(color);
}
3. 动态创建和删除控件
// 动态添加 Fl_Button* btn = new Fl_Button(10, next_y, 100, 30, label); next_y += 40; parent->add(btn); parent->redraw(); // 动态删除 delete btn; parent->redraw();
4. 布局管理辅助函数
void center_widget(Fl_Widget* w, int container_w, int container_h) {
w->position((container_w - w->w()) / 2, (container_h - w->h()) / 2);
}
📖 学习资源推荐
官方资源
- FLTK 官方网站:https://www.fltk.org
- 在线文档:https://www.fltk.org/documentation.php
- GitHub 仓库:https://github.com/fltk/fltk
书籍推荐
- FLTK Programming Manual (官方手册,PDF 免费)
- Introduction to FLTK (初学者友好)
示例代码
FLTK 安装目录下的 examples/ 文件夹包含了丰富的示例程序:
button.cxx– 各种按钮示例input.cxx– 输入控件示例table.cxx– 表格控件示例browser.cxx– 浏览器控件示例
🚀 总结
FLTK 提供了一套完整且易用的 GUI 控件体系,通过本文的详细介绍,你应该已经对各个控件有了全面的认识。
学习路线建议:
- 从
Fl_Window和Fl_Button开始,掌握基本的事件处理 - 学习
Fl_Group和Fl_Pack,理解布局管理 - 深入研究
Fl_Table、Fl_Tree等复杂控件 - 阅读官方示例代码,实践各种控件的组合使用
FLTK 的学习曲线相对平缓,非常适合快速开发小型工具和跨平台应用。希望这篇博客能帮助你在 FLTK 开发之路上走得更顺利!
如果你有任何问题或想要深入了解某个特定控件,欢迎随时交流讨论!


发表回复