# 第 1 课:GUI 你好窗口 > **本课目标**:从一个空空的程序开始,**自己一步一步**让屏幕上弹出一个写着 "欢迎来到抽卡世界!" 的窗口。 > > **预计时间**:30~40 分钟 > > **学完之后**:你能解释什么是窗口、控件、事件循环,并能凭记忆写出 5~6 行让窗口出现的代码。 --- ## 0. 上课前先理理 ### 命令行程序 vs GUI 程序 | | 命令行(以前的你) | GUI(现在的你) | |---------|-----------------------------|----------------------------------| | 长什么样 | 黑底白字一行行 | 有窗口、按钮、彩色文字 | | 怎么跑 | 一口气从上跑到下,跑完就退出 | 启动后 **一直在等** 你点鼠标 | | 怎么输出 | `std::cout << ...` | 把文字 "贴" 在窗口上的便利贴上 | ### 这一课会认识 3 个新朋友 | 名字 | 比喻 | 干什么用 | |---------------|------------------|-------------------------------------| | `Fl_Window` | **画纸** | 程序的窗口本体 | | `Fl_Box` | **便利贴** | 贴在画纸上的一段文字 | | `Fl::run()` | **不下班的保安** | 让窗口一直待着,等你操作 | > 💡 还会顺带认识两个 C++ 新写法:`new` 和 `->`。先不用搞懂原理,跟着写就行。 --- ## 1. 起步:打开起步骨架,先编译一次 打开 `lesson_gui_1.cpp`。你会看到一个全是 TODO 的骨架。 先在终端里编译一下,确认环境没问题: **Mac / Linux:** ```bash cmake -B build -DLESSON=1 cmake --build build ./build/gacha1 ``` **Windows:** ```bash cmake -B build -DLESSON=1 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build build --config Release build\Release\gacha1.exe ``` > 💡 第一次 `cmake -B build -DLESSON=1` 之后,**后面每次只要改了 `.cpp`,运行前两行就够**: > ```bash > cmake --build build && ./build/gacha1 > ``` ### ✅ 检查点 1 - [ ] 编译没报错 - [ ] 运行后……什么都没发生?**对的**!程序进了 `main`,立刻就 `return 0` 退出了。我们接下来一步步让它"活"起来。 --- ## 2. 步骤 1:变出一个空窗口 ### 🤔 先想一下 - 一个窗口至少要告诉电脑哪些信息?(提示:长什么样、叫什么) - 程序跑完 `main` 就结束了——那窗口怎么能"一直待着"呢? ### ✏️ 在 `main` 里加这 3 件事 **(1) 创建窗口对象**:替换掉 `// TODO(步骤 1):在这里创建一个窗口对象 window` 那一行: ```cpp Fl_Window *window = new Fl_Window(400, 300, "抽卡世界"); ``` 读法:用 `new` "变出" 一个 `Fl_Window`,宽 400、高 300,标题叫 "抽卡世界"。`window` 是它的名字。 **(2) 显示窗口**:替换掉 `// TODO(步骤 1):告诉窗口"控件加完了"…` 那一行: ```cpp window->end(); window->show(); ``` 读法:`->` 念 "的"。`window` 的 `end()` 表示"控件加完啦",`window` 的 `show()` 是"露面"。 **(3) 让程序"待住"不退出**:把最后的 `return 0;` 改成: ```cpp return Fl::run(); ``` `Fl::run()` 就是那个不下班的保安——它会卡在这里,直到你关闭窗口才返回。 ### ▶️ 编译运行 ```bash cmake --build build && ./build/gacha1 ``` ### ✅ 检查点 2 - [ ] 屏幕上出现一个 400×300 的空白窗口 - [ ] 窗口标题栏写着 "抽卡世界" - [ ] 关闭窗口,程序退出,终端回到提示符 🎉 你的第一个 GUI 程序!但里面空空的,下一步贴张便利贴上去。 > ❓ 如果没出来:是不是忘了把 `return 0;` 改成 `return Fl::run();`? --- ## 3. 步骤 2:在窗口里贴一张便利贴 ### 🤔 先想一下 - 贴在窗口里的文字,应该放在窗口的哪个位置?怎么告诉电脑这个位置? - 文字框本身也是一个"东西",那它要不要 `new` 出来? ### ✏️ 改两个地方 **(1) 顶上的 include 区**:把 `// TODO(步骤 2)`:还需要再 `#include 一个头文件` 这行替换成: ```cpp #include ``` 便利贴在 FLTK 里叫 `Fl_Box`,要先告诉编译器去哪儿找。 **(2) 在 `window->end();` **之前**插入这一行**(替换掉对应的 TODO): ```cpp Fl_Box *box = new Fl_Box(50, 100, 300, 100, "欢迎来到抽卡世界!"); ``` 读法:变出一个 `Fl_Box`,位置 (50, 100),宽 300、高 100,文字是 "欢迎来到抽卡世界!"。 ### 📐 坐标到底怎么数? FLTK 的坐标系——和你以前数学课上的不一样,Y 是 **向下** 增大的: ``` (0,0) ──────────── X → │ │ (50,100) │ ↓ │ ┌──────────┐ │ │ 便利贴 │ 宽 300 │ │ │ 高 100 │ └──────────┘ Y ↓ ``` - X 从左到右增大 - Y 从上到下增大 - 原点 (0,0) 在窗口左上角 ### ▶️ 编译运行 ```bash cmake --build build && ./build/gacha1 ``` ### ✅ 检查点 3 - [ ] 窗口里出现了 "欢迎来到抽卡世界!" - [ ] 文字大概在窗口中间偏上的位置 > ❓ 文字看起来很小?没事,下一步搞定字号。 --- ## 4. 步骤 3:让字大起来 ### ✏️ 在 `new Fl_Box(...)` 那行的**下一行**加: ```cpp box->labelsize(24); ``` 意思是:`box` 的 `labelsize`(标签字号)设为 24。 ### ▶️ 编译运行 ```bash cmake --build build && ./build/gacha1 ``` ### ✅ 检查点 4 - [ ] 文字明显变大了 - [ ] 整个窗口看起来终于像个迎宾画面了 🎉 **第 1 课通关!** 你刚刚自己写出了一个完整 GUI 程序。 --- ## 5. 玩一玩:改一改看会发生什么 每改一个,记得 **保存 → 编译 → 运行**: 1. 把 `400, 300` 改成 `600, 400`。窗口变大了吗? 2. 把 `labelsize(24)` 改成 `36`、`12`、`80`。极端值会怎样? 3. 把 `(50, 100, 300, 100)` 里的 `50` 改成 `0`。文字跑哪儿去了? 4. 把窗口标题 `"抽卡世界"` 改成你自己起的名字。 5. **思考题**:怎么让文字 **正好居中**?窗口宽 400,文字框宽 300——X 应该填几? > 💡 想到答案再往下看:宽 400 减宽 300 等于 100,两边各留 50,所以 X = 50。本课的代码刚好就是居中的。 --- ## 6. 课后挑战(选做) 完成以上后还想多玩?挑一个: - **A. 双便利贴**:在窗口的上、下半部分各放一个 `Fl_Box`,写不同的话。 - **B. 给画纸刷色**:在 `window->end()` 前面加 `window->color(fl_rgb_color(255, 240, 200));`,看看效果。(需要 `#include ` 或加在已有头文件里编译试一下,错了就回滚——这就是学编程) - **C. 思考题**:以前 `std::cout` 一打印就显示,再换一行又能继续打印。GUI 的 `Fl_Box` 行为有什么不一样? --- ## 7. 卡住了?常见小问题 | 现象 | 多半是 | |------|-------| | 窗口闪一下就消失 | `return 0;` 没改成 `return Fl::run();` | | 编译报 "找不到 `Fl_Box`" | 忘了 `#include ` | | 编译报 "找不到 `FL/Fl.H`" | FLTK 没装好;Mac 跑一下 `brew install fltk cmake` | | 窗口出来但是全黑/全空白 | `window->show()` 是不是写在 `window->end()` 前面了?顺序反了 | | 中文变方框 | 文件没存成 UTF-8 编码 | --- ## 8. 偷看老师答案 写不出来、或者想对一下? ```bash cmake -B build -DLESSON=1 -DUSE_SOLUTION=ON cmake --build build && ./build/gacha1 ``` 源文件路径:`solutions/lesson_gui_1.cpp`。 **但请尽量自己先动手——卡住 5 分钟以上再看**。 --- ## 9. 下一课预告 第 2 课:加一个 **按钮**,点一下让窗口里的字变样子。你将第一次见到"用户操作 → 程序响应"的 GUI 核心套路:**回调函数**。 > 📝 学完记得在 `学习进度与状态-GUI.md` 里把第 1 课打勾。 **下一课**:`第02课-按钮与回调.md`