Files
chouka/第01课-GUI你好窗口.md
T
2026-05-16 11:09:02 +08:00

195 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第 1 课:GUI 你好窗口
**本课目标**:用 FLTK 创建第一个 GUI 程序——一个窗口,里面写着欢迎语。理解 GUI 程序和命令行程序的不同。
**复习**:你会用 `std::cout` 在命令行输出文字。本课把"输出"搬到**窗口**里。
---
## 1. 这一课要搞懂什么
### 命令行 vs GUI
| | 命令行程序 | GUI 程序 |
|---|---|---|
| 样子 | 黑底白字 | 有窗口、按钮 |
| 运行方式 | 一口气跑完 | 一直等用户操作 |
| 输出 | `cout` 打印到终端 | 显示在窗口里的控件上 |
| 用户操作 | 键盘输入 | 鼠标点击、键盘 |
### 本课三个"新朋友"
| FLTK 类 | 比喻(小朋友版) | 作用 |
|---------|-----------------|------|
| `Fl_Window` | 画纸 | 程序的窗口框架 |
| `Fl_Box` | 便利贴 | 在窗口上显示文字 |
| `Fl::run()` | 不休息的保安 | 让窗口一直显示,等用户操作 |
### 你还认识一个老朋友的变身
- `new`:以前你可能没见过。在 FLTK 里,控件用 `new` 创建。可以简单理解为"变出一个控件来"。
---
## 2. 第一个 GUI 程序
保存为 `lesson_gui_1.cpp`
```cpp
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
int main() {
// 创建窗口:宽 400,高 300,标题"抽卡世界"
Fl_Window *window = new Fl_Window(400, 300, "抽卡世界");
// 在窗口上放一个文字标签:位置(50,100),宽300,高100
Fl_Box *box = new Fl_Box(50, 100, 300, 100, "欢迎来到抽卡世界!");
box->labelsize(24); // 字号 24
// 结束添加控件
window->end();
// 显示窗口
window->show();
// 进入事件循环(让窗口一直显示)
return Fl::run();
}
```
配套 `CMakeLists.txt`
```cmake
cmake_minimum_required(VERSION 3.14)
project(gacha1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
if(MSVC)
add_compile_options("/utf-8")
endif()
find_package(FLTK CONFIG REQUIRED)
add_executable(gacha1 lesson_gui_1.cpp)
target_link_libraries(gacha1 PRIVATE fltk)
```
---
## 3. 代码逐行解释
```cpp
#include <FL/Fl.H> // FLTK 核心
#include <FL/Fl_Window.H> // 窗口
#include <FL/Fl_Box.H> // 文字标签
```
以前的 `#include <iostream>` 是请命令行工具,这三个 `#include <FL/...>` 是请窗口工具。
```cpp
Fl_Window *window = new Fl_Window(400, 300, "抽卡世界");
```
- `Fl_Window` = 窗口
- `400, 300` = 宽 400 像素,高 300 像素
- `"抽卡世界"` = 窗口标题栏上显示的字
- `new` = 创建一个窗口(和以前 `int x = 5` 不同,窗口是"对象"
- `*` = 指针(先记:FLTK 创建的控件都用 `*`
```cpp
Fl_Box *box = new Fl_Box(50, 100, 300, 100, "欢迎来到抽卡世界!");
```
- `50, 100` = 文字在窗口中的位置:从左边数 50 像素,从上边数 100 像素
- `300, 100` = 文字区域的宽 300,高 100
- 最后一个参数 = 显示的文字内容
```cpp
box->labelsize(24);
```
`->` 读作"的"`box``labelsize` 设为 24(字号)。
```cpp
window->end(); // 告诉窗口:控件加完了
window->show(); // 让窗口显示出来
return Fl::run(); // 进入"等待模式",窗口一直显示直到用户关闭
```
---
## 4. 编译和运行
**Mac**
```bash
cmake -B build && cmake --build build && ./build/gacha1
```
**Windows**VS + vcpkg):
```bash
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake && cmake --build build --config Release && build\Release\gacha1.exe
```
运行后应看到一个白色窗口,中间写着"欢迎来到抽卡世界!"。
---
## 5. 坐标系统
FLTK 窗口的坐标系:
```
(0,0) ──────────── X →
│ (50,100)
│ ↓
│ ┌──────────┐
│ │ 文字区域 │ 宽 300
│ │ │ 高 100
│ └──────────┘
Y
```
- X 从左到右增大
- Y 从上到下增大
- 原点 (0,0) 在左上角
---
## 6. 本课课堂小练习
1. 把窗口标题 `"抽卡世界"` 改成你自己起的名字。
2. 把欢迎语改成你喜欢的句子。
3. 试试把窗口改大(比如 600×400),把 `Box` 的位置也调整一下,让文字居中。
---
## 7. 本课课后作业(选做)
-`labelsize(24)` 改成 36、12、8,看文字大小变化。试试极端值,看会发生什么。
- 在窗口上放**两个** `Fl_Box`,一个在上半部分,一个在下半部分,显示不同的文字。
- 思考题:和以前 `std::cout` 输出文字相比,GUI 方式有什么不同?(一个提示:GUI 的文字可以"一直显示",不用 `\n` 刷屏。)
---
## 8. 常见小问题
- **窗口一闪就消失**:检查有没有 `return Fl::run();`,不是 `return 0;`
- **编译报错找不到 FL**:检查 `CMakeLists.txt` 里的 `find_package(FLTK CONFIG REQUIRED)` 是否正确,以及 FLTK 是否已安装。
- **中文乱码**:确保源文件保存为 UTF-8 编码。Mac clang++ 一般默认支持。
- **窗口出来了但是空的**:检查 `window->show()``window->end()` 的顺序。`show()` 必须在 `end()` 之后(本课代码顺序已正确)。
---
## 9. 下一课预告
第 2 课学**按钮和回调**:在窗口上放一个"抽卡"按钮,点一下,文字会变——从"只看不动"到"能交互"。
---
*学完请在 `学习进度与状态-GUI.md` 里更新第 1 课的状态。*
**下一课文档**`第02课-按钮与回调.md`