# Y++ 窗口组件语法说明
本文说明 D2D 高级自绘项目中窗口、组件、属性、方法和事件的代码写法。组件必须先在设计器中存在,并以属性面板中的“名称”作为代码标识符。
## 1. 窗口和组件名称
设计器中有以下名称:
```text
主窗口
用户名输入框
登录按钮
状态标签
用户表格
刷新定时器
```
代码通过名称访问:
```yc
用户名输入框.标题 = ""
状态标签.标题 = "等待登录"
登录按钮.可用 = 真
```
名称修改后,事件函数和所有点号调用必须同步修改。
## 2. 属性读取与赋值
通用格式:
```yc
组件.属性 = 值
变量 = 组件.属性
```
示例一:初始化窗口内容:
```yc
函数 主窗口.创建完毕() {
主窗口.标题 = "用户管理"
用户名输入框.标题 = ""
状态标签.标题 = "请输入用户名"
登录按钮.可用 = 真
登录按钮.可视 = 真
}
```
示例二:读取输入并更新标签:
```yc
函数 登录按钮.单击(整数 X, 整数 Y) {
文本 用户名 = 用户名输入框.标题
如果 (用户名 == "") {
状态标签.标题 = "用户名不能为空"
返回()
}
状态标签.标题 = "欢迎:" + 用户名
}
```
示例三:位置和尺寸:
```yc
函数 放大按钮.单击(整数 X, 整数 Y) {
状态标签.宽度 = 400
状态标签.高度 = 40
状态标签.X坐标 = 20
状态标签.Y坐标 = 60
}
```
属性名称和类型因组件而异。标签、编辑框的文本属性可能在 IDE 中显示为“标题”或对应组件的专用名称,应使用补全实际给出的成员。
## 3. 组件方法调用
格式:
```yc
组件.方法(参数)
```
示例一:表格写入和读取:
```yc
函数 主窗口.创建完毕() {
用户表格.清空()
用户表格.添加列("编号", 80)
用户表格.添加列("姓名", 120)
用户表格.添加列("状态", 100)
用户表格.添加行("1001", "张三", "正常")
用户表格.添加行("1002", "李四", "停用")
}
函数 用户表格.双击(整数 行, 整数 列) {
文本 内容 = 用户表格.取项目文本(行, 列)
状态标签.标题 = "双击内容:" + 内容
}
```
表格具体方法名和参数以当前 IDE 表格组件补全为准;列、行下标通常从 0 开始。
示例二:列表框:
```yc
函数 加载分类() {
分类列表.清空()
分类列表.添加项目("全部")
分类列表.添加项目("启用")
分类列表.添加项目("停用")
分类列表.选中索引 = 0
}
```
示例三:Web 浏览器:
```yc
函数 打开网页按钮.单击(整数 X, 整数 Y) {
文本 地址 = 地址输入框.标题
如果 (地址 == "") {
地址 = "https://www.example.com"
}
网页浏览器.打开网页(地址)
}
函数 后退按钮.单击(整数 X, 整数 Y) {
网页浏览器.后退()
}
```
## 4. 事件函数
格式:
```yc
函数 组件名.事件名(事件参数) {
// 事件处理
}
```
常见窗口事件:
```yc
函数 主窗口.创建完毕() {
输出("窗口已经创建")
}
函数 主窗口.窗口关闭() {
输出("窗口已经关闭")
}
函数 主窗口.关闭前() 逻辑 {
// 返回真允许关闭,返回假取消关闭
返回(真)
}
```
按钮单击:
```yc
函数 保存按钮.单击(整数 X, 整数 Y) {
输出("点击坐标:" + 到文本(X) + "," + 到文本(Y))
}
```
有些组件的单击事件是零参数,有些提供坐标、行列或按键参数。窗口也可能同时提供“关闭前”“窗口关闭”“关闭询问”等事件,它们的返回值和触发时机不同。不要把一个组件的事件签名复制给另一个组件,应从设计器事件面板生成,或按 IDE 补全/F1 提示书写。
## 5. 多种组件事件示例
### 编辑框内容变化
```yc
函数 搜索输入框.内容改变() {
文本 关键字 = 搜索输入框.标题
状态标签.标题 = "正在搜索:" + 关键字
}
```
### 定时器周期事件
```yc
整数 刷新次数 = 0
函数 刷新定时器.周期事件() {
刷新次数 = 刷新次数 + 1
状态标签.标题 = "刷新次数:" + 到文本(刷新次数)
}
函数 主窗口.创建完毕() {
刷新定时器.周期 = 1000
刷新定时器.启动()
}
```
### 表格行列事件
```yc
函数 用户表格.单击(整数 行, 整数 列) {
输出("行=" + 到文本(行) + ",列=" + 到文本(列))
}
函数 用户表格.右键单击(整数 行, 整数 列, 整数 X, 整数 Y) {
输出("右键行=" + 到文本(行))
}
```
### 鼠标事件
```yc
函数 绘图区域.鼠标按下(整数 X, 整数 Y, 逻辑 按下) {
如果 (按下) {
状态标签.标题 = "按下:" + 到文本(X) + "," + 到文本(Y)
}
}
函数 绘图区域.鼠标移动(整数 X, 整数 Y) {
坐标标签.标题 = 到文本(X) + "," + 到文本(Y)
}
```
事件参数必须以当前组件帮助显示的签名为准。
## 6. 一个完整表单示例
设计器组件:`姓名输入框`、`年龄输入框`、`保存按钮`、`清空按钮`、`结果标签`。
```yc
函数 清空表单() {
姓名输入框.标题 = ""
年龄输入框.标题 = ""
结果标签.标题 = "等待输入"
姓名输入框.设置焦点()
}
函数 主窗口.创建完毕() {
主窗口.标题 = "人员登记"
清空表单()
}
函数 保存按钮.单击(整数 X, 整数 Y) {
文本 姓名 = 姓名输入框.标题
整数 年龄 = 到整数(年龄输入框.标题)
如果 (姓名 == "") {
结果标签.标题 = "姓名不能为空"
返回()
}
如果 (年龄 <= 0) {
结果标签.标题 = "年龄必须大于 0"
返回()
}
结果标签.标题 = "已保存:" + 姓名 + "," + 到文本(年龄) + " 岁"
}
函数 清空按钮.单击(整数 X, 整数 Y) {
清空表单()
}
```
## 7. 多窗口调用
窗口必须已经加入项目。打开或加载窗口时使用 IDE 支持的窗口命令,不要把窗口文件路径当作组件对象:
```yc
函数 打开设置按钮.单击(整数 X, 整数 Y) {
设置窗口.显示()
设置窗口.激活()
}
```
如果当前补全提供的是窗口对象形式,应按补全显示的方法调用。窗口名称、文件名和代码中的名称要一致。
## 8. 组件与支持库对象的区别
组件来自设计器,不需要在 `.yc` 再声明:
```yc
// 设计器已有 状态标签,直接使用
状态标签.标题 = "完成"
```
支持库类对象需要声明:
```yc
JSON类 数据
数据.置文本("状态", "完成")
```
不要在源码里重新声明与组件同名的变量或对象。
## 9. 后台任务更新界面
耗时任务可在线程执行,但不要长期阻塞创建完毕、单击等界面事件,也不要从后台线程直接连续修改组件。推荐后台取得数据,再通过界面调度或定时器在界面线程更新:
```yc
文本 后台结果 = ""
逻辑 已完成 = 假
函数 读取后台数据() {
后台结果 = 读文件("D:/data/report.txt")
已完成 = 真
}
函数 检查定时器.周期事件() {
如果 (已完成) {
结果多行框.标题 = 后台结果
检查定时器.停止()
}
}
```
## 10. 错误写法与正确写法
### 错误:组件名称不存在
```yc
// 设计器实际名称是 状态标签
标签1.标题 = "完成"
// 正确
状态标签.标题 = "完成"
```
### 错误:重复声明组件
```yc
// 错误:登录按钮已经由设计器生成
按钮 登录按钮
// 正确:直接调用
登录按钮.可用 = 真
```
### 错误:把属性写成方法
```yc
// 错误
状态标签.标题("完成")
// 正确
状态标签.标题 = "完成"
```
### 错误:把方法写成属性
```yc
// 错误
用户表格.清空 = 真
// 正确
用户表格.清空()
```
### 错误:事件写成赋值
```yc
// 错误
登录按钮.单击 = 登录处理
// 正确
函数 登录按钮.单击(整数 X, 整数 Y) {
登录处理()
}
```
### 错误:复制了不属于该组件的事件参数
```yc
// 错误:普通按钮事件不一定有“行、列”
函数 登录按钮.单击(整数 行, 整数 列) { }
// 正确:使用按钮补全给出的签名
函数 登录按钮.单击(整数 X, 整数 Y) { }
```
### 错误:组件属性类型不匹配
```yc
// 错误
登录按钮.可用 = "是"
// 正确
登录按钮.可用 = 真
```
### 错误:在设计器改名后仍用旧名称
```yc
// 组件已从 按钮1 改名为 保存按钮,旧事件不会绑定
函数 按钮1.单击() { }
// 正确
函数 保存按钮.单击() { }
```
### 错误:在函数外执行组件赋值
```yc
// 错误:文件顶层不能放运行语句
状态标签.标题 = "启动"
// 正确
函数 主窗口.创建完毕() {
状态标签.标题 = "启动"
}
```
## 11. 排查顺序
1. 在设计器确认组件名称和组件类型。
2. 保存窗口文件后再编译,避免运行旧布局。
3. 输入 `组件名.` 查看只属于该类型的属性、方法和事件。
4. 从事件面板生成事件函数,避免手写错参数。
5. 属性用 `=`,方法用 `()`,事件用 `函数 组件.事件(...) {}`。
6. 多窗口项目确认目标窗口已经加入项目并保存。
评论