封面

文本框: TSLVCL 天软科技 文本框: 本文档所有内容均属于深圳市天软科技开发有限公司的商业机密，深圳市天软科技开发有限公司亦保留上述文档中阐述的包括而不限于技术、方法、思想的所有权。此文档仅仅只许可因本文档所必需传播的范围内使用（仅限于内部），本文档的获得者不得将本文档散发给不相关的其他机构和个人。 深圳天软科技 |


摘要

本文的目的是说明如何使用TSL桌面开发工具开发桌面程序,阅读完本文后您可以使用TSL语言开发桌面应用程序.本文将讨论如下内容:

l 桌面开发工具介绍及环境配置

l 使用界面开发工具构建桌面工程

l TSL桌面开发库的基本架构

l 常用的控件简介

l 绘图库介绍和使用说明


1. 天软桌面开发工具的介绍

TSL语言已经覆盖建模，WEB开发，报表引擎，配置脚本等应用场景。但随着WEB开发越来越广，桌面开发领域越来越小，但在专业应用领域里，桌面开发依旧具有无可替代的作用。

专业桌面开发工具的门槛过高，而其他脚本软件由于基本都是采用第三方库作为桌面开发的基础，底层功能无法或者极难扩展，使得用作真正的桌面开发有其天然的劣势。为了填补这项空白，我们在四年前投入了桌面开发工具的开发中。

2021年，世界上第一个纯脚本（TSL）开发而成的桌面开发工具正式面世，这个桌面开发工具具备传统桌面开发工具的几乎全部特性，同时又兼备脚本语言的优势，它不需要编写大量代码去描述界面元素的外观和位置，只要把预先建立好的对象拖放到屏幕上相应的位置即可。可视化的、面向对象和采用事件驱动方式的结构化工具。

天软桌面开发工具使用的语言是TSL。

TSL是Tinysoft Statistical analysis Language的简称，它是Tinysoft Corp.专门为了迎合统计分析所开发的编程语言。TSL拥有快捷的数据访问方法、强大的运算能力、丰富的函数分析库、灵活强大的数据呈现能力以及强大的数据导入导出功能，拥有了TSL，统计分析将变得更快速，更容易。

TSL是一种类Pascal编程语言，它除了包含有作为一种编程语言所应具有的各种逻辑流程控制功能以外，更出色的是其具有的丰富的函数库以及方便灵活的数据类型。

天软官网提供了TSL语言的学习资料。包括但不限于天软基础语言、矩阵、TS-SQL等的文档和视频学习资料。这里推荐学习：

TSL语言基础：http://www.tinysoft.com.cn/tsdn/helpdoc/index.tsl?type=1

天软课堂TSL语言模块：

1、语言基础：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=15

2、矩阵专题：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=16

3、如何优化程序：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=21

4、时间序列统计关键字：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=57

5、TS-SQL：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=92

6、面向对象：http://www.tinysoft.com.cn/tsdn/tstrain/detail.tsl?id=93

其他更多学习，请访问天软首页及天软课堂。


2. 桌面开发工具环境配置


2.1 所需环境

天软提供了在Windows上运行的桌面工具，在Linux上运行的界面工具同样即将推出。


2.2 下载及安装工具包

安装包 | 说明
tslvctltool-setup.exe | windows平台
tslvcltool.*.*.*.*.deb | linux对应的版本


2.3 获取帮助

用户可以通过本手册获取相关的操作说明帮助，以及界面相关的控件说明。如需获取TSL语言上的帮助，请访问天软TSDN进行查询。


3. 开发工具操作界面介绍


3.1 进入工具界面

执行tslvcltool.exe，进入界面工具的操作界面。


3.2 操作界面介绍

运行TSL桌面开发工具,可以看到如下图所示.操作界面分为7个主要部分：

1）菜单栏

2）代码编辑栏、

3）管理工程文件

4）控件工具栏

5）编辑窗口

6）控件树

7）属性及事件编辑器。

其中编辑窗口需要新建/打开工程开启。


3.3 菜单栏

菜单栏中提供了界面工具的所有功能入口，将鼠标移至某菜单项，下拉可看到各界面功能。菜单项包括：文件、视图、工程、运行、工具、帮助。每个菜单项下包含多个子菜单项。具体菜单项说明见下表：

表1. 菜单项说明

菜单项 | 菜单子项 | 说明
文件 | 保存 | 保存正在编辑的文件
 | 代码编辑 | 打开tsl代码编辑器
视图 | 管理工程文件 | 打开工程浏览器可以添加或者删除文件/目录
 | 对象浏览 | 显示对象查看器（当前窗口控件树和当前节点属性\事件编辑器）。
工程 | 新建工程/打开工程 | 对工程执行相应的操作。
 | 打开历史 | 显示设计器打开工程的历史。
运行 | 运行 | 运行当前工程。
工具 | 打开图片 | 可以打开图片并将其转换为16进制字符串形式。
帮助 | 使用手册/控件详情/范例 | tsl桌面开发的各种帮助


3.4 代码编辑栏

代码编辑栏提供代码编辑相关功能按钮，包括：打开文件、保存全部、保存、注释、反注释、撤销、反撤销、查找、调试等功能，方便用户编辑TS代码。

具体代码编辑栏说明如下：

代码编辑项图标 | 代码编辑项 | 说明
 | 打开文件 | 打开.tsl/.tsf的TS代码文件。
 | 保存全部 | 保存当前工程的所有文件
 | 保存 | 保存当前编辑的窗口文件
 | 取消注释 | 取消注释
 | 注释 | 注释
 | tsl代码格式化 | 自动格式化成tsl代码
 | 撤销 | 撤销
 | 反撤销 | 反撤销
 | tsl语法检查 | 检查是否符合tsl语法
 | 查找 | 可查找关键字位置，替换等
 | 后退 | 代码编辑中向后切换代码文件
 | 前进 | 代码编辑中向前切换代码文件
 | 快捷说明 | 打开快捷键说明
 | 代码地图 | 展示代码树结构，快速定位代码段
 | 添加/删除断点 | 添加/删除断点
 | 运行 | 调试运行
 | 暂停 | 暂停

当调试时才会弹出调试栏

功能说明如下：

代码编辑项图标 | 代码编辑项 | 说明
 | 添加/删除断点 | 添加/删除断点，F5快捷键设置
 | 运行 | 调试运行
 | 进入 | 进入光标行所在的函数
 | 跳出 | 跳出当前函数，返回上层
 | 下一行 | 执行下一行
 | 终止 | 终止调试
 | 刷新符号表 | 刷新所有变量
 | 刷新当前符号 | 刷新当前选中变量


3.5 控件工具栏

控件工具栏包含常用、对话框。


3.5.1 常用

常用的具体说明如下：

控件图标 | 控件名称 | 说明
 | 容器控件 | 用来放置其他控件的窗口（不含标题）。
 | 分组框 | 用来放置其他控件的窗口（含标题）。
 | 成对分配器 | 可以鼠标调整大小的两个容器。
 | 页面控件 | 各个容器分页显示的控件。
 | 定时器 | 不可视控件，每隔一定时间就执行特定任务的控件。
 | 图像列表 | 不可视控件，用来组织程序中用到的图像。
 | 剪切板 | 将文本复制到剪切板
 | 主菜单 | 列出程序拥有的功能。主菜单是只有主窗口才能使用的菜单。
 | 右建菜单 | 列出程序拥有的功能。弹出菜单是所有控件都能使用的菜单，右建弹出。
 | 工具条容器 | 可拖动的容器控件，里面一般包含两个或多个子控件
 | 工具栏 | 放置工具按钮的长条面板，位于窗口的顶部。
 | 状态栏 | 通常位于窗口的底部,显示程序的运行状态。
 | 托盘 | 系统托盘（系统右下角图标）。
 | actionlist | 管理程序中的Action。
 | 按钮 | 鼠标点击执行特定函数的控件。
 | 静态文本框 | 不可编辑的文本框。
 | 分割条 | 灵活分割开两个控件，实现可拖动改变控件大小
 | 文本框控件 | 输入一行可显示文本的控件。
 | 密码框 | 输入密码框，不会直接显示输入的字符，而是显示一个个‘*’符号。
 | 多行文本 | 输入多行文本的编辑框
 | 语法高亮 |
 | 单选框 | 有多个这样的按钮时，只能选择其中的一个
 | 复选框 | 按钮可以选中，可以同时有多个复选按钮维持选中状态。
 | 下拉选择框 | 下拉选择。
 | 列表框 | 下拉框中展示列表项的控件。
 | 列表视图控件 | 显示一个表格。
 | 树控件 | 显示一棵多叉树，能够直观地展示各节点间的关系。
 | 自绘制表格 | 绘制表格
 | 进度条 | 进度条,显示程序的运行状态。
 | 时间日期选择 | 时间日期选择功能。
 | 时间选择 | 时间选择功能。
 | 日历 | 日历形式的日期选择功能。
 | SpinEdit | 以固定的间隔改变整数值的大小。
 | IP地址控件 | 输入IP。
 | 颜色下拉选择框 | 下拉选择颜色。
 | 颜色列表框 | 颜色列表框。


3.5.2 对话框

对话框的具体说明如下：

控件图标 | 控件名称 | 说明
 | 文件打开 | 选择要打开文件的对话框
 | 文件保存 | 选择要保存文件的对话框
 | 颜色选择 | 用来选择颜色的对话框
 | 字体选择 | 用来选择字体的对话框
 | 文件夹选择 | 用来选择文件夹，不能选择文件
 | 提示框 | 弹出提示框


3.6 管理工程文件

对于一个程序，往往会包含多个窗口，或者执行函数等，可以通过工程文件管理器在工程中添加、删除、 打开等操作。

具体说明如下：

图标 | 名称 | 说明
 | 添加 | 可以点击节点然后点击此按钮添加窗口、添加面板、添加函数、添加脚本和添加目录。
 | 删除 | 删除节点文件。
 | 打开 | 打开选中节点的文件。
 | 上移 | 上移节点。
 | 下移 | 下移节点。

下方为工程文件树，是相关窗口、面板、函数、脚本等相关项目内容的树结构。


3.7 编辑窗口

通过管理工程文件栏目下面的工程文件树，单击可以打开指定工程文件的编辑窗口。用户可以通过当前编辑的窗口进行界面文件编辑。如增加控件、调整控件大小、位置等。


3.8 控件树

控件树为正在编辑窗口中涉及到的相关控件树结构，点击可选择对应控件，查看控件当前节点属性\事件编辑器。通过修改属性或事件，对该控件进行调整。

右键还可添加、删除、上移或下移控件。


3.9 属性/事件编辑器

属性/事件编辑器中列出了控件树中的指定控件的属性和事件，用户可通过属性/事件编辑器调整控件。


3.9.1 属性

控件的属性列表，可通过点击“propertys”查看及编辑。属性包括name、action、left、top等。具体的属性说明见控件的常用属性介绍。


3.9.2 事件

控件的事件列表，可通过点击“events”查看及编辑。事件包括onclick、ondblclick、onmousemove等。详细的事件说明见控件的常用事件介绍。


4. 构建TSL桌面程序流程

下图为构建TSL桌面程序的简单流程图：


4.1 新建/打开工程


4.1.1 新建工程

新建工程操作步骤：

1、菜单栏—工程—新建工程。

2、在打开的文件选择对话框中，选择新建工程的路径。

3、输入工程名(如：newprojecta)，并点击打开。

说明：

1、工程的路径指定的文件夹最好是专为该工程指定的文件夹。

新建的工程文件有多个，将直接放置在该文件夹下。为了区分不同的工程文件，建议新建空文件夹管理。

如上步骤中，打开指定路径后，在界面工具路径下新建newprojecta文件，作为工程newprojecta的文件夹。

2、工程名可以由英文、下划线及数字组成，不支持中文及其他特殊字符。

3、新建工程时，自动关闭原打开的工程。请保存原工程之后再新建工程。


4.1.2 打开工程

打开工程操作步骤：

1、菜单栏—工程— 打开工程；

2、在打开的文件选择对话框中，进入工程所在文件夹

3、选择需要打开的工程，点击*.tpj文件，并点击打开。如：newprojecta.tpj

工程目录的文件及文件夹说明：

1、*.tpj文件：工程信息文件(打开工程时选择该文件)。如newprojecta.tpj。

2、*.tfm文件夹：窗体资源文件夹。如resource.tfm 。

3、*.tsl文件：工程执行入口文件。如newprojecta.tsl。

4、*.tsf文件：工程主窗口文件(默认添加窗口)。如newprojectamain.tsf 。


4.2 添加/删除控件

控件工具栏中提供了常用、对话框两大块的控件支持。各类型控件的说明，请查看控件工具栏的介绍。

1、添加控件：选择需要添加的控件，单击编辑窗口中选定的位，可看到该即已添加到工程的编辑窗口中。

2、调整控件大小及位置：通过鼠标拖拽可以改变选定控件的位置和大小。

3、删除控件：可在编辑窗口中右键点击控件，在弹出框删除；也可以通过控件树节点，同样通过右键点击，在弹出框中选择删除。

下图为在窗口右键删除方式：

下图为在控件树节点右键删除方式：


4.3 设置控件属性

用户可以通过对象浏览器“属性/事件编辑器”设置控件的属性，这是一个可视化的控件属性设置窗口。用户可通过该窗口查看并设置属性(protertys)，可设置的控件属性会依据控件的类型不同而不同。具体的控件的属性介绍可参考：常用属性。

用户也可以通过直接编辑代码的方式添加或修改、删除相关控件属性。


4.4 编辑窗口代码

双击指定控件，打开代码编辑窗口查看窗口类(如下图的testmain）的代码，包括窗口类及其中的控件定义的成员变量和方法，如属性、事件等。用户可根据需求添加或修改窗口类中的成员变量和成员方法。

注意，不要改变窗口类中指定的控件成员的public属性。如下截图中按钮控件tbtn，定义为 “btn1:tbtn”。这个按钮btn1在这里默认为public变量。如果修改其变量属性，即不能私有化，否则会导致控件构造失败。


4.5 添加响应处理

双击控件可打开代码编辑器，通过代码编辑器添加或修改控件的响应事件。

如果控件存在相关的处理事件events，工具一般会提供一个默认的处理方法。用户在添加控件并双击控件打开代码编辑器后，工具会自动帮助创建一个默认的处理方法。在代码编辑器中，也可以自定义添加函数作为事件的处理方法，完成后在控件events事件属性中选择其作为事件回调。

比如，btn*_clk是tbtn按钮控件一个默认响应函数，添加并双击tbtn控件之后自动生成这个响应函数。如下图中btn1按钮中的events下，onclick事件的响应函数btn1_clk。即按钮默认回调btn1_clk函数。

注意，不同控件有不同的events事件作为触发条件。具体常用事件可参考常用事件。


4.6 调试/执行

添加完控件后，用户进行调试或者直接执行主窗口后点击需测试的控件，测试是否完成指定工作。


4.6.1 调试操作步骤

1、在代码编辑器中，点击 [image] 或这按“F5”设置断点。行前标记为橙色即设置断点成功。

2、点击”调试运行“按钮

3、当触发控件事件或其他操作，比如：按钮控件需要点击触发，运行到断点时，即可进行调试。绿点即运行到当前行

4、进行调试操作，具体调试按钮功能可查看代码编辑栏

比如：

4.1、执行“下一行”，echo打印信息，可在tsl.exe中可查看得到

4.2、可在代码编辑器中查看对应变量取值


4.6.2 执行操作步骤

1、运行-》运行：点击菜单栏的“运行”，再点击下拉框中的“运行”，即执行了主窗口；

2、测试事件：通过鼠标操作或其他控件操作测试主窗口配置的该控件事件；


4.7 发布

用户如果需要把该工具发布出去，目前只能通过打包相关文件的方式。

文件必须包括：

1、 打包工程目录的整个文件。如上述例子中newprojecta。

2、 发送该文件包。

注意，接收方也需下载了该界面工具才可执行工程。

执行方式：

1、打开工程方式，打开桌面开发工具，打开工程然后执行。

2、DOS窗口命令行，或将命令编辑到cmd文件方式执行。

例如:tslediter在C盘下，执行命令如下：

"c: \tslediter\tsl.exe" "c:\ tslediter\newprojecta\newprojecta.tsl"


5. 界面库简介


5.1 库文件

库 | 说明
tslvcl | 界面库及其常用组件


5.2 类层次结构

TSL界面开发常用类及其的继承关系

图1. tslvcl库主要类层次结构（在继承链省略了一些不重要的类）


5.2.1 公共基类TSLUIBASE和组件基类TComponent

TSLUIBASE是界面库组件的公共基类，定义了一些常用的成员函数以及各种常量。

TComponent是组件基类，定义了组件的基本操作；记录了组件间的拥有和被拥有的关系，定义了当组件创建、析构时将会执行的操作。

TComponent的派生类分为两类，其中一类是TControl，这个是可视控件基类，所有的可视控件都是继承自该类；另一类是不可视控件，Tcontrol以外的所有类都属于这一类别，其中的所有控件在最终完成的界面程序上是看不到的。


5.2.2 可视控件基类TControl

TControl是可视控件基类，该类定义了控件的可视属性，如位置、大小等，并且还定义了如菜单、鼠标操作等控件的通用行为。

表2. TControl类常用属性

属性 | 类型 | 说明
left | int | 控件的左侧位置，以像素为单位，从其parent的窗口区域左边开始。
top | int | 控件的顶部位置，以像素为单位，从其parent的窗口区域顶部开始。
width | int | 控件的宽度，以像素为单位。
height | int | 控件的高度，以像素为单位。
caption | string | 控件的标题。
visible | bool | 是否隐藏控件，默认为1（显示）。
border | bool | 使用隐藏边框，默认为1（显示）。
parent | twincontrol | 父窗口，设置某个控件的父窗口后，该控件将会显示在其父窗口上。
popupmenu | tpopupmenu | 弹出菜单，当鼠标在控件中单击右键时，将会显示该菜单。

除了可以设置对象的属性外，控件还定义了一系列可以设置回调函数的属性，这些属性都是函数指针类型，将指定的函数指针赋值给它后，当控件发生相应的操作后，就会调用该函数。有两种方法设置回调函数：

1. 匿名函数：

可以直接定义一个匿名函数赋值给相应属性。

2. 绑定非匿名函数的函数指针

该方法需要定义一个对象可以访问到的函数，然后可以通过thisfunction或findfunction关键字绑定其函数指针。

注意函数的参数需要同属性提供的一致。调用函数时，编译器会将函数调用端提供的参数按照顺序传递到函数的参数列表中。

下表是TControl类提供的可绑定回调函数的属性，tslvcl库中这样的属性大多都是提供两个参数。一般来说，其中一个是控件自身对象，另一个是包含发生的操作的信息的对象。

表3. TControl类常用回调函数属性

函数名 | 参数o | 参数e | 说明
onsize | tcontrol自身 | tmmouse | 鼠标调整控件大小时回调。
onmove | tcontrol自身 | tmmouse | 鼠标拖动控件移动时回调。
onmousemove | tcontrol自身 | tmmouse | 鼠标在控件中移动时回调。
onmouseup | tcontrol自身 | tmmouse | 鼠标按键按下时回调。
onmousedown | tcontrol自身 | tmmouse | 鼠标按键松开时回调。

TControl类的回调函数属性大多是鼠标操作事件引发的，他们的第二个参数类型是tmmouse，这个类包含了该事件的信息，该类拥有属性xpos和ypos，分别是该操作发生时鼠标指针的x位置和y位置；类中有函数shiftstate()，其返回值是整数数组类型，该数组中的数字对应着操作发生时按下的键。其中常见常量如下表所示：

表4. 鼠标操作常用常量

常量名 | 说明
ssShift | shift键被按下
ssCtrl | ctrl键被按下
ssLeft | 鼠标左键被按下
ssRight | 鼠标右键被按下
ssMiddle | 鼠标滑轮被按下
ssDouble | 鼠标双击


5.2.3 窗口控件基类TWinControl

TWinControl是窗口控件的基类，从图1中可以看出，除了TLabel等少数控件外，其他控件都是由TWinControl派生来的。该类有一些较为常用的属性：

l onKeyDown属性，函数指针类型，当用户按下一个按键时将会调用。

l onKeyUp属性，函数指针类型，当用户松开一个按键时将会调用。

l onKeyPress属性，函数指针类型，当用户输入一个字符时将会调用。

以上的函数调用都是按键引发的。这些函数的第二个参数是TMKEY类型，该参数中包含按下的按键的信息。注意只有可以拥有键盘输入焦点的窗口控件，例如能够输入字符的可编辑文本框或者容器和表格控件等等才能使用这些函数指针成员。


5.2.3.1 按键操作TMKEY

每一个TMKEY对象都表示一次按键操作，该对象中包含按下的按键的信息。TMKEY类拥有以下属性：

l char属性，字符类型，操作中按下的字符。

l charCode属性，整数类型，操作中按下的字符的ascii码。

注意keydown和keyup不同于keypress，前者只是按下的按键，后者才是输入的字符。例如当键盘的大小写锁未开启时，按一下“A”键将调用onkeyDown一次，其中char为“A”；调用onKeyPress一次，其中char为“a”；调用onKeyUp一次，其中char为“A”。当大小写锁开启时，这三次调用的char就都是“A”了。


6. 常用控件

各类控件会有一些常用属性和常用事件，可以通过节点属性\事件编辑器进行手动编辑。不同控件有不同属性和事件，还有些特定的属性和函数需要在代码层使用。


6.1 控件列表

控件 | 说明
tbtn | 按钮
tlabel | 标签
tedit | 编辑框
tpassword | 密码框
tmemo | 多行文本框
twrapmemo | 自动换行文本框
tradiobtn | 单选按钮
tcheckbtn | 多选按钮
tlistbox | 列表框
tcombobox | 下拉列表框
tlistview | 多列列表框
ttreeview | 树控件
tgridctl | 表格控件
tprogressbar | 进度控件
tdatetimepicker | 日期时间选择控件
ttimepicker | 时间控件
tmonthcalendar | 日历控件
tspinedit | spin控件
tsplitter | 分割控件
tpagecontrol | 页面容器控件
ttabcontrol | 页面标签控件
tpairsplitter | 带一个分隔符的容器
ttimer | 定时器
tworkerctl | 工作线程控件
tcontrolimagelist | 图标列表控件
tclipboard | 剪切板
tmainmenu | 主菜单
tpopupmenu | 弹出菜单
tcoolbar | 带拖动子控件功能的容器
ttoolbar | 工具栏
tstatusbar | 状态栏
tactionlist | action列表
tbevel | 边框控件
tpanel | 容器控件
tgroupbox | 带标题的容器控件


6.2 常用属性

属性 | 说明
action | 绑定action对象，当action对象属性改变，本控件的对应属性一起改变。
caption | 控件的标题。
align | 对齐方式，跟上层窗口对齐。 alnone:无。 altop:上端对齐。 albottom:低端对齐。 alleft:左端对齐。 alright:右端对齐。 alclient:延申到整个上层窗口的大小。
anchors | 固定位置，拉伸上层窗口时固定方位的距离不变。可多选，默认[akleft aktop](左上)。 aktop：固定上端。 akleft：固定左端。 akright：固定右端。 akbottom：固定低端。
autosize | 自动调整大小，控件会自动根据内容大小调整自身大小。默认为FALSE（不会自动调整大小）。
left | 控件的左侧位置，以像素为单位，从其parent的窗口区域左边开始。
top | 控件的顶部位置，以像素为单位，从其parent的窗口区域顶部开始。
width | 控件的宽度，以像素为单位。
height | 控件的高度，以像素为单位。
visible | 是否隐藏控件，默认为1（显示）。
border | 使用隐藏边框，默认为1（显示）。
enabled | 控件是否有效。默认为1（有效）。
childsizing | 子控件布局（顾名思义需要控件为容器类型，能放置子控件才会有该属性），用于类似表格式布局子控件位置的属性。 Layout:：none（自定义）; LeftToRightThenTopToBottom（从左至右再从上到下）; TopToBottomThenLeftToRight（从上到下再从左至右）; Controlsperline：每行列控制数（从左至右则每行控制列数，从上到下则每列控制行数）； Horizontalspacing：水平间距； Verticalspacing：垂直间距； Leftrightspacing：左右间距； Topbottomspacing：上下间距；
color | 控件颜色。
font | 控件字体。
popupmenu | 弹出菜单，当鼠标在控件中单击右键时，将会显示该菜单。
parentcolor | 采用父控件的颜色
parentfont | 采用父控件字体
tabstop | 表示该控件在用tab键进行切换焦点时，是否要得到焦点。默认为False。
Wsdlgmodalframe | 设置边框重影展示，默认为False


6.3 常用事件

双击窗口弹出编辑器后保存函数，在对应事件选项会弹出相应的函数列表，选择回调的函数即可。

事件 | 说明
onsize | 鼠标调整控件大小时回调。
onmove | 鼠标拖动控件移动时回调。
onmousemove | 鼠标在控件中移动时回调。
onmouseup | 鼠标按键按下时回调。
onmousedown | 鼠标按键松开时回调。
onKeyDown | 当用户按下一个按键时将会调用。
onKeyUp | 当用户松开一个按键时将会调用。
onKeyPress | 当用户输入一个字符时将会调用。
onClose | 当用户点击了窗口的关闭按钮时将会调用
onactivate | 窗口切换到当前控件时调用
onnotification | 通知回调，根据e.sender：发出通知控件和e.msg ：通知的内容进行回调，其他控件可通过 o.relnotification(info)发送通知

事件触发的函数，系统调用时会自动送入两个对象，其中一个是控件自身对象o，另一个是发生操作的信息对象e。所以，我们在定义事件触发的函数时需要定义这两个参数接收变量，如function btn1_clk(o;e);

不同对象有不同的属性和方法，o控件本身可参考常用控件自带的方法属性，e信息对象常用的有鼠标消息（onmousemove，onmousedown，onmouseup）和按键消息（onKeyDown，onKeyUp，onKeyPress）。

e信息对象的属性方法如下：

e信息对象 | 属性or方法 | 说明
鼠标消息 | 属性 | pos:数组，鼠标的x，y位置
 |  | Ypos:整数，鼠标的x位置
 |  | Ypos:整数，鼠标的y位置
 | 方法 | Shiftstate():数组，按键状态， shift键：ssshift常量 alt键：ssalt常量 ctrl键：ssctrl常量 鼠标双击：ssdouble常量 可用ssshift in Shiftstate()判断。
按键消息 | 属性 | Char：字符串，键符号
 |  | Charcode：整数，ascii码
 |  | Shiftstate：按键状态， shift键：ssshift常量 alt键：ssalt常量 ctrl键：ssctrl常量


6.4 按钮控件

按钮的主要作用就是在用户按下的时候执行某种绑定的事件操作。

按钮控件一组控件，如下所示：

各类型按钮

类 | 控件图标 | 形态 | 说明
TBtn |  |  | 普通按钮
TCheckBtn |  |  | 复选按钮
TRadioBtn |  |  | 单选按钮


6.4.1 普通按钮TBtn

TBtn是最基础的按钮，主要提供鼠标点击的回调函数属性，其他的按钮控件都是由TBtn的派生类，这些控件都可以用TBtn的属性。


6.4.1.1 事件

l Onclick：在鼠标单击左键时调用。


6.4.2 单选按钮TRadioBtn

TRadioBtn是单选按钮，单选意思是有多个这样的按钮时，只能选择其中的一个。当有多个TRadioBtn对象的parent相同时，选中其中某个按钮时，其他的按钮如果有被选中的，其选中状态会改成未选中状态。注意必须是直接在同一个窗口上的才有这种效果，举个例子，某窗口上有两个tpanel（可以放置其他控件的控件），这两个tpanel上各有几个单选按钮，则每个tpanel上的单选按钮是互斥的，跟另一个tpanel上的单选按钮是没有关系的。


6.4.2.1 属性

l checked：整数类型，该属性显示该复选框是否被选中，未选中时为0，选中时为1。

l leftText：布尔类型，通过设置该属性可设置复选框外观为文字在坐，按钮在右。

l Textpos：控件标题文本的位置。


6.4.2.2 事件

l Onclick：在鼠标单击左键时调用。


6.4.3 复选按钮TCheckBtn

TCheckBtn是复选按钮，该按钮可以选中；跟TRadioBtn不同的是，该按钮跟不会因为其他同类按钮的状态改变而改变，可以同时有多个复选按钮维持选中状态。


6.4.3.1 属性

l checked属性：整数类型，该属性显示该复选框是否被选中，未选中时为0，选中时为1。

l leftText属性：布尔类型，通过设置该属性可设置复选框外观为文字在左，按钮在右。

l Textpos：控件标题文本的位置。


6.4.3.2 事件

l Onclick：在鼠标单击左键时调用。


6.5 文本框

文本框的作用就是给界面软件使用者输入相关字符，同时软件可捕获使用者输入状态、当前输入、焦点转移等信息，触发相应事件。

文本框含有一组控件，如下所示：

各类型文本框

类 | 控件图标 | 形态 | 说明
TEdit |  |  | 普通编辑框
TPassword |  |  | 密码框
TMemo |  |  | 多行文本框
Tlabel |  |  | 不可编辑文本框


6.5.1 通用属性

l text：字符串类型，用来设置或获取编辑框内的文本，可以设置初始值。

l readonly：布尔类型，用来设置或获取编辑框是否是只读的。

l Placeholder：字符串类型，空白时的提示。

l limitlength：文本框的最大输入字符数限制，特别要注意的是一个汉字占用两个字符。

l TextAlign：文本框文本对齐方式，AlignStyle9 类型的成员。


6.5.2 通用事件

l onmaxtext：当输入的文本长度已达到最大限制(limitlength属性)时，就会调用该函数。

l onkillfocus：函数指针类型，每当编辑框失去输入焦点，例如用户输入完文本点击窗口的其他地方时，就会调用该函数。

l onsetfocus：函数指针类型，每当编辑框获得输入焦点，例如用户点击编辑框准备输入文本时，就会调用该函数。

l onchange：函数指针类型，每当编辑框内文本发生变化时（用户输入或删除文本），就调用该函数。注意，文本框的初始化也会触发该事件。

onSetFocus和onKillFocus这两个属性看似不常用，但事实上相当有用。举个例子，在网站上注册账户，一般都可以自己设置用户名，然后系统会检查该账户名是否合法及可用。系统不会每输入一个字就检测一次，而是等用户输入完毕，点击其他地方，例如用户输入完密码进入下一条信息的编辑的时候，此时就可以设置密码编辑框的onKillFocus属性为检查账户名编辑框内的文本是否可用的操作。


6.5.3 普通编辑框TEdit

TEdit是编辑框，也就是可以重复编辑修改的文本编辑控件。


6.5.4 密码框TPassword

密码框控件是用来输入密码的文本框，系统不会直接显示输入的字符，而是显示一个个‘*’符号。


6.5.4.1 属性

l passwordChar：字符类型，用来设置密码框中用来代替真正密码而显示的字符。


6.5.5 多行文本框TMemo

TMemo是可以输入多行文本的编辑框。


6.5.5.1 对象属性和函数

l getLineCount()函数：无参数，返回值为整数类型，返回文本框内的行数。

l SelAvail属性：布尔类型，是否有文本被选中。

l TabChar属性：tab键对应的字符。

l Highlighter属性：语法高亮对象thighlighter。

l Completion属性：输入提示对象 TSynCompletion。

l TopLine属性：首行，数字类型。

l CaretX属性：光标所在列。

l CaretY属性：光标所在行。

l LineText属性：当前行的字符串。

l SelText属性：选中的文本。

l Lines属性：数据集合。

l LineHeight属性：行高。

l LineInterval属性：行间距。

l autogutterwidth属性：行标自动宽度。

l currentLineColor属性：当前行的背景色。

l guttercolor属性：行标背景色。

l ongutterclick属性：行标点击的回调。

l oncaretposchanged属性：光标位置改变。

ExecuteCommand(cmd,data) 命令执行函数

cmd:常量

ecTab 执行tab缩进；

ecShiftTab 执行向前缩进；

ecClearAll 全部清除；

ecEditorTop 跳到首行；

ecSelEditorTop 跳到首行并选中；

ecEditorBottom 跳到末尾；

ecSelEditorBottom 跳到末尾并选中；

ecString 在当前光标处插入字符串，data对应的字符串；

ecLineEnd 跳转到行尾；

ecSelLineEnd 选中到行尾；

ecLineStart 调转到行首；

ecSelLineStart 选中到行首；

ecLeft 光标左移；

ecSelLeft 向左选中；

ecRight 光标右移；

ecSelRight 向右选中；

ecGotoXY 跳转，data为对应的位置array(行，列)；

ecSelGotoXY 选中到跳转，data为对应的位置array(行，列)；

ecSelectAll 全部选中；

ecDeleteLine 删除当前行；

ecUndo 撤销；

ecRedo 反撤销；

ecCut 剪切选中；

ecPaste 粘贴到当前位置；

ecCopy 复制当前选中。


6.5.6 自动换行辑文本框twrapmemo

该控件可以对超过长度的文本，自动换行，但是不支持编辑


6.5.7 不可编辑文本框TLabel

上面介绍了可编辑的文本框，这些文本框都可以输入字符，而TLabel是不可编辑的文本框，只能通过其caption属性修改其显示的文本。


6.5.7.1 属性

l transparent属性，布尔类型，是否采用父控件的背景


6.6 工作线程控件tworkerctl

该控件，是在另外的线程中处理，对于占用cup较多的任务使用该控件可以提升界面的使用体验。


6.6.1 属性和事件

l script属性：执行的脚本

l OnMessage属性：对象收到工作线程的通知回调

l onerror 属性：对象收到工作线程错误的通知回调


6.6.2 简单范例

worker范例

----------------------------workerdo.tsf------------------------------------

function workerdo(o,d);

begin

    echo "workerdo";

    o.postmessage("worker send");

end

----------------------------------------------------------------

---------------------------------主程序-------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;

    begin

        inherited;

        fwk := new tworkerctl(self); //创worker对象

        fwk.onmessage := thisfunction(ongetmsg); //设置定时操作

        fwk.script := %% this := thisfunction(workerdo);%%;

        fwk.postmessage("send to worker"); //发送任务

    end

    function ongetmsg(o,d);

    begin

        echo "\r\nongetmesage:",d;

    end

    fwk;

End

----------------------------------------------------------------


6.7 计时器TTimer

计时器是可以设置每隔一定时间就执行特定任务的控件，它是不可见控件。


6.7.1 属性

l interval：正整数类型，通过该属性设置计时器间隔，单位是ms；


6.7.2 事件

l ontimer：函数指针类型，每经过interval指定的时间，就执行一次该事件绑定的函数。


6.7.3 对象常用属性和函数

l enable：布尔类型，通过读取该属性值可获取计时器是否已启动的信息；

l start()：参数返回值皆无，调用该函数将开启计时器；

l stop()：参数返回值皆无，调用该函数将暂停计时器；


6.7.4 简单范例

ttimer范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;

    begin

       inherited;

       label1:=new tlabel(self);

       label1.width:=200;

       label1.parent:=self;

       timer:=new ttimer(self);//创建定时器

       timer.onTimer:=thisfunction(timerOnTimer);//设置定时操作

       timer.interval:=1000;//设置间隔时间

       timer.start();//启动定时器

    end

    function timerOnTimer(o,e);begin

       label1.caption:=datetimetostr(now());

    end

    timer;

    label1;

End

----------------------------------------------------------------

当代码执行的时候，会不断更新当前时间。我们在构造函数中创建ttimer并设置其间隔、执行的操作，并且令该计时器启动；当程序运行的时候，定时器可以随时打开、关闭。


6.8 树形控件TTreeView

TTreeView是树形控件，该控件可以显示一棵多叉树，能够直观地展示各节点间的关系。TTreeView拥有一个逻辑根节点，控件的显示的所有的树的根节点就是该控件根节点的子节点。

TTreeView控件的每个节点都是一个TTreeNode对象。


6.8.1 常用属性

l checkBox：布尔类型，用来设置控件的节点是否带有一个复选按钮，当该属性为1时，每个节点上都带有一个复选框可供选中，每个节点的复选框的选中状态跟其他复选框是无关的，可以同时有多个节点被选中。特别地，选中父节点会同时全选其子节点。

l hasLine：布尔类型，用来设置控件的节点间是否有线相连

l Lazyitems：数组结构的节点信息,通过该属性设置或者获取节点。

l selectionColor：选中节点的颜色，rgb颜色值

l LineColor：线的颜色

l Linestyle：线的样式

l expandsigncolor：展开标记的颜色

l expandsigntype：展开符合的的样式

tvestTheme

tvestPlusMinus

tvestArrow

tvestArrowFill

l nodecreator：节点构造器，继承于TcustomTreeCtlNode 的类型

l onEmptyNodeExapanding：不存在子节点的节点被展开


6.8.2 常用事件

l Onselchanged:被选中的节点发生变化触发。


6.8.3 对象属性和函数

l rootNode：TTreeNode类型，该属性就是控件的根节点。

l currentNode：TTreeNode类型，用来获取控件当前选中的节点，这个当前选中的结点就是用户在控件内最后一次点击的节点，注意区分于节点复选框的选中状态。

一般来说使用该控件是获取其根节点，然后在根节点上进行增加、删除、查找等操作。

l Createtreenode()：创建TTreeNode对象。


6.8.4 树形控件结点TTreeNode

TTreeNode是树形控件的节点，通过设置TTreeNode属性方法，即可影响整个树形结构状态。


6.8.4.1 对象常用属性和方法

l itemCount：整数类型，作用是获取该结点当前子节点的数量。

l items：数组类型，作用是获取该结点当前的子节点。

l parent：TTreeNode类型，作用是获取该结点的父节点。

l checked：布尔类型，作用是设置或获取当前节点的复选框（如果有）是否被选中。

l caption：字符串类型，作用是设置或获取当前节点显示的名称。

l lastChild：TTreeNode类型，作用是获取该结点最后一个子节点。

l getNodeByIndex(idx:int)：参数是整数类型，作用是获取指定索引的子节点。

l indexOf(v:TTreeNode)：参数是TTreeNode，作用是根据给定子节点获取其索引。

l insertNodeStr(s:string,idx:int)：作用是根据给定字符串s构造一个新的节点并将其插入到子节点中索引为idx的位置，返回值是这个被插入的节点。

l insertNode(it:TTreeNode,idx:int)：类似insertNodeStr，不过插入的是给定的节点。

l deleteNode(nd:TTreeNode)：参数是TTreeNode类型，作用是当指定子节点存在时就删除它。deleteNodeByIndex(idx:int)：参数是整数类型，作用是当指定索引的子节点存在时就删除它。

l expand()：展开该节点。

l unExpand()：折叠该节点。


6.8.5 简单范例

TTreeView范例

----------------------------------------------------------------

uses tslvcl;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

fm.left := 10;

r := fm. _wapi.GetScreenRect();

echo tostn(r);

app.run();

type tfm = class(TVCForm)

    function Create(AOwner);

    begin

        inherited;

        //left := 20;

        //width := 700;

        fhds := new TMyArrayB();

        //创建树结构

       tree := new TTreeView(self);

        tree.Height := 500;

       //创建树节点

        for i:= 0 to  10 do

        begin

        nd := tree.createtreenode();

        nd.Caption := "node " $ i;

        nd.parent := tree.RootNode;

        //continue;

            if i in array(0,3,5,7)then

            begin

                for j := 0 to 5  do

                begin

                    nd2 := tree.createtreenode();

                    nd2.Caption := "node2--- " $ j;

                    nd2.parent := nd;

                    for k := 0 to 4 do

                    begin

                        nd3 := tree.createtreenode();

                        nd3.Caption := "node3--- " $ k;

                        nd3.parent := nd2;

                    end

                end

            end

        end

        tree.parent := self;

        //设置隐藏节点按钮

        btn := new tbtn(self);

        btn.left := 500;

        btn.parent := self;

       btn.Caption :="隐藏选中节点";

        btn.onclick := function(o,e)begin

            it := tree.CurrentNode;

            if it then

            begin

                it.Visible := false;

                fhds.Push(it);

            end

        end

        //设置显示隐藏节点按钮

        btn2 := new tbtn(self);

       btn2.Caption :="显示隐藏节点";

        btn2.left := 500;

        btn2.top := 200;

        btn2.parent := self;

        btn2.onclick := function(o,e)begin

            //it := tree.CurrentNode;

            //if it then

            //it.Visible := true;

            it := fhds.pop();

            if it then it.Visible := true;

        end

    end

    fhds;

    tree;

end

----------------------------------------------------------------

上述范例中，创建了一个树结构，点击“隐藏选中节点”按钮时，当控件中有节点被选中，则直接隐藏该节点，点击“显示隐藏节点”按钮时，会显示前一个被隐藏的的树节点。


6.9 表格控件TListView

TListView是比较常用的控件，可以用来显示一个表格。TListView分为行和列，列相当于字段，每一行都是一个记录，也是一个数组，其中的元素按照索引的顺序显示在控件上。列的增加、删除、修改不会影响的数据，只会影响到数据的显示。例如某控件有5个列，其中的一行有5个元素，当删除其中某个列的时候，行的元素不会被删除一个，而是最后的元素不会被显示。同理，当列的数量高于行的元素数量时，行最后一个元素后面的格子就显示为空，如下图所示：

每一行的元素数都不同的表格


6.9.1 属性

l Itemcount：设置列表行数；

l Gridline：是否显示表格内部边框；

l Columnheader：是否显示表头；

l Columns:设置表头，设置时指定宽度及列名，设置完后应用；

l Selectedid：鼠标指定行索引，索引值从0开始；

l Selbkcolor：根据selectedid选中的行，指定该行背景颜色；

l Mouseonbkcolor：鼠标定位行颜色；


6.9.2 事件

l Ondblclick：在鼠标双击左键时调用。

l Oncolumnclick：点击表头触发事件

l Oncheckitem：添加数据触发


6.9.3 对象属性和函数

l insertColumn(txt:string,wd:int,idx:int)函数，功能是插入一个列，其中txt是要插入列的列名，wd是要插入列的宽度，idx是要插到第几列前。

l deleteColumn(idx:int)函数，功能是删除指定的列，其中idx是要删除的列的索引。

l deleteAllColumns()函数，功能是删除所有的列。

l getColumnText(n:int)函数，功能是获取指定索引n的列的列名，n从0行开始。

l setColumnText(n:int,t:string)函数，功能是设置指定索引n的列的列名为t，n从0行开始。

l appendItem(v:array)函数，功能是在所有行后面添加一个行。

l appendItems(v:array)函数,可添加多维数组，即在所有行后面加多行数据

l insertItemAfter(v:array,id:int)函数，功能是在指定索引id的行的后面插入一个行

l getItem(idx:int)函数，功能是获取指定索引的行的数据

l setItem(idx:int,v:array)函数，功能是设置指定索引的行的数据为数组v，数据表有该索引的数据时才能使用

l setSubItemByIndex(idx:int,subidx:int,v)函数，功能是设置指定索引idx的行的第subidx个元素值为v

l columns属性，数组类型，用来获取控件的列的数据。

l itemCount属性，整数类型，用来获取控件的行数。

l selectedId属性，整数类型，用来获取被选中项的行号。

l ListValues属性，数组类型，用来获取控件的行的数据。


6.9.4 简单范例

以下是一个简单的TListView范例：

TListView范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       lv:=new TListView();

       lv.width:=500;

       b1:=new tbtn(self);

       b1.top:=290;

       b1.caption:="添加一列";

       b1.onclick:=thisfunction(b1click);

       b2:=new tbtn(self);

       b2.top:=330;

       b2.caption:="添加一行";

       b2.onclick:=thisfunction(b2click);

       cnt:=0;

setini();

    end

    function setini();

begin

       lv.parent:=self;

       b1.parent:=self;

       b2.parent:=self;

    end

private

    function b1click(o,e);begin

       lv.insertColumn(inttostr(cnt++),100,length(lv.columns));

    end

    function b2click(o,e);begin

       i:=length(lv.columns);

       arr:=array();

       for x:=0 to i-1 do

           arr[x]:=inttostr(rand()*100);

       lv.appenditem(arr);

    end

    lv;

    b1;

    b2;

    cnt;

end

----------------------------------------------------------------


6.10 菜单TMenu

菜单是一类特殊的控件，通常用来列出程序拥有的功能。分为主菜单和弹出菜单。主菜单是只有主窗口才能使用的菜单，而弹出菜单是所有控件都能使用的菜单。

主菜单是TMainMenu，在TVCForm类中有一个属性叫mainmenu，将指定的TMainMenu对象赋值给它就设置了窗口的菜单。同理，弹出菜单类是TPopupMenu，各个窗口都拥有popupmenu这一属性（见2.2.2），将指定的TPopupMenu对象赋值给它就设置了窗口的菜单。

主菜单和弹出菜单的编辑方法是相同的，菜单由菜单项TMenu组成，这些菜单项就是菜单直接的子菜单项。子菜单项本身也可以拥有子菜单项，这样就形成了菜单的嵌套。

主菜单

弹出菜单


6.10.1 基本使用


6.10.1.1 主菜单

1. 点击菜单栏添加主菜单

2. 在窗口控制树，右键主菜单添加子菜单

3. 编辑子菜单属性、事件


6.10.1.2 弹出菜单

1. 点击菜单栏添加弹出菜单

2. 在窗口控制树，右键点击弹出菜单添加子菜单

3、编辑子菜单属性、事件


6.10.2 属性

l Bitmap：选择位图放置对应子菜单前

l Tseparator：设置为True时，子菜单不可用，设置为分隔符

l itemcount：子菜单数量

l items：子菜单集合

l checked：是否选中

l zorder：设置序号

l shortcut：快捷方式


6.10.3 事件

l Onrbuttonup:鼠标右键点击触发事件

l Onselect:鼠标移动到该菜单时触发事件

l onclick：被点击调用


6.10.4 对象常用属性和函数

l parent属性，TMenu类型，用来获取该菜单项上一级的菜单或菜单项。

l insertItem(item:TMenu,bef:int)函数，参数item是要插入的tmenu，bef是要插入的位置，bef非法时会插入到最后。插入成功时返回-1，否则返回-2。

l removeItemByIndex(idx:int)函数，参数是要删除的子菜单项的索引，当索引合法时删除其对应得菜单项。

l indexOf(item:TMenu)函数，参数是子菜单项，返回其在本TMenu中的索引。

l getItemByIndex(idx:int)函数，参数是子菜单项索引，返回本TMenu中对应该索引的子菜单项。


6.10.5 简单范例

具体范例可查看，菜单栏-》帮助->范例-》menu-》E_Menu.tpj。


6.11 下拉框TCombobox

下拉框由一个编辑框和一个下拉按钮组成；当点击下拉按钮时，下拉框会显示一个列表框，点击该列表框中的某个列表项，该项就会显示在编辑框里。


6.11.1 属性

l Readonly:用来设置或获取编辑框是否是只读的。

l checkBox：布尔类型，是否带有一个复选按钮

l multisel:布尔类型，是否多选。

l Dropdowncount:整数，最多显示多少条记录。

l Itemindex:设置下拉框默认项索引

l Items:设置下拉框可选项值，如下图所示


6.11.2 事件

l Oncloseup:下拉列表关闭后未将值赋给下拉框触发事件

l Ondropdown:点击下拉框触发事件

l Onselchanged:选中下拉列表某项值并将值赋给下拉框后触发事件

l Oneditchanged:下拉框值发生改变并将值赋给下拉框后触发事件

l Oneditupdate:下拉框值发生改变未将值赋给下拉框时触发事件


6.11.3 对象属性和方法

l appendItem(str:strng)函数，参数类型是字符串，功能是将该字符串添加到控件的列表项的最后边。

l insertItem(str:string,idx:int)函数，第一个参数类型是字符串，第二个参数类型是整数，功能是将给定字符串插至列表项中指定位置。

l deleteItem(idx:int)函数，参数类型是整数，功能是删除指定索引的列表项。

l clean()函数，功能是清空列表项。

l getItemCount()函数，返回值是整类型，功能是获取列表项的数量。

l getItemText(idx:int)函数，参数是整数类型，返回值是字符串类型，功能是获取指定下标的列表项文字。

l showDropdown(b:bool)函数，参数是布尔类型，功能是设置是否一直显示下拉框的列表框。


6.12 范围选择控件tspinedit


6.12.1 事件

l OnIncrease：增加时候的回调。

l OnDecrease：减少时候的回调。


6.12.2 属性

l Increment：步长；

l MinValue：最小值；

l MaxValue：最大值；

l Value：当前值。


6.13 分割控件tsplitter

该控件可以，支持用过鼠标调整位置，达到控制兄弟节点控件的大小，位置的效果。


6.14 列表框TListBox

列表框就是下拉框中展示列表项的控件，相比于下拉框中的列表框，列表框控件拥有的功能更多。


6.14.1 属性

l Items:字符串数组类型，用来设置和获取列表框的项的文本。

l itemindex：选中的项目序号

l selbkcolor：选择时背景颜色

l Multisel:设置为True时，可实现多选功能

l checkBox：布尔类型，是否带有一个复选按钮

l ownerdraw:布尔类型，是否自绘制，若是则调用事件ondrawlist回调函数。

l Itemcount:整数，自绘制时的条目数量

l Popupmenu:添加的弹出菜单，右键弹出


6.14.2 事件

l Onselchange:列表框选中值发生变化时触发事件

l Ondrawlist:ownerdraw属性为TRUE触发。


6.14.3 对象属性和方法

l appendItem(item:string)函数，参数是字符串类型，功能是将该字符串添加至列表框的末尾。

l appendItems(arr:array of string)函数，参数是字符串数组，功能是将该数组中所有字符串添加至列表框的末尾。

l insertItem(item:string,idx:int)函数，第一个参数是字符串类型，第二个参数是整数类型，功能是将该字符串插入列表框内指定位置。

l insertItems(arr:array of string,idx:int)函数，第一个参数是字符串数组，第二个参数是整数类型，功能是将该数组内所有字符串从列表框内指定位置开始插入。

l deleteItem(idx:int)函数，参数是整数类型，功能是删除指定索引的列表项。

l deleteItems(b:int,e:int)函数，两个参数都是整数类型，功能是删除指定两个索引位置上及其间的所有列表项。

l getItemCount()函数，返回值是整数类型，功能是获取列表框的项数。

l getItemText(idx:int)函数，参数是整数类型，返回值是字符串类型，功能是获取指定索引的项的文本。

l clean()函数，功能是清空列表框。

l getCurrentSelection()函数，返回值是整数类型，功能是获取当前选中项的索引。

l setCurrentSelection(idx:int)函数，参数是整数类型，功能是定位到设置索引的项。

l getItemSelectedState(idx:int)函数，参数是整数类型，返回值是布尔类型，功能是获取指定项的选中状态。


6.15 文件对话框

文件对话框是用来选择文件或文件夹的控件，该控件是不可见控件，一般通过设置按钮并在按钮中创建文件对话框对象，通过对象设置其属性并调用相关方法。不同于TTimer，它可以弹出一个对话框来供用户选择文件或文件夹。


6.15.1 文件保存对话框TSavefileADlg

文件保存对话框用来选择要保存文件的对话框，用来选择文件或文件夹的对话框都是相似的，但是文件保存对话框有自己独特的功能。例如文件和文件夹选择对话框只能选择已有的文件或文件夹，而文件保存对话框往往要创建并保存到一个新的文件，这样就需要允许文件保存对话框返回一个不存在的文件路径。并且，文件保存对话框选择了一个已有的文件时，为了数据安全，应该允许程序弹出一个警告对话框以询问用户是否确定覆盖该文件。


6.15.1.1 属性

l filter:：数组类型，用来设置对话框的过滤文件类型，格式举例：

array("所有文件":"*.*","文本文件":"*.txt")

l defaultFileExtension：用来设置默认扩展名，也就是当文件名输入框中未指定扩展名且未选择保存类型时将使用的扩展名。

l showHidden：布尔类型，用来设置是否显示隐藏的文件。

l overwritePrompt：布尔类型，用来设置开启覆盖保存提示。

l Filemustexist：布尔类型，若在文件名输入框中输入不存在的文件名则提示文件名不存在；默认则不提示而直接返回路径，用于打开对话框。


6.15.1.2 对象属性和方法

l Filename属性，获得选中的文件全名。

l chooseDlg()函数，返回值是布尔类型，打开对话框以选择文件，当选择有效的文件路径时，返回1，否则返回0.

l getSelectedItemName()函数，返回值是字符串类型，返回所选择的文件的文件名，当选择不止一个文件时，返回首文件名。

l getResults()函数，返回值是字符串数组类型，功能是获取所选择的所有文件的完整路径。


6.15.2 文件打开对话框TOpenfileADlg

文件打开对话框是用来选择文件以打开的对话框，相比于文件保存对话框，其功能较为简单。


6.15.2.1 属性

l filter属性，数组类型，用来设置对话框的过滤文件类型，格式示例：

array("所有文件":"*.*","文本文件":"*.txt")

l defaultFileExtension属性，用来设置默认扩展名，也就是当文件名输入框中未指定扩展名且未选择保存类型时将使用的扩展名。

l showHidden属性，布尔类型，用来设置是否显示隐藏的文件。

l multiSelected属性，布尔类型，用来设置对话框是否可多选。


6.15.2.2 对象属性和方法

l Filename属性，获得选中的文件全名。

l chooseDlg()函数，返回值是布尔类型，打开对话框以选择文件，当选择有效的文件路径时，返回1，否则返回0.

l getSelectedItemName()函数，返回值是字符串类型，返回所选择的文件的文件名，当选择不止一个文件时，返回首文件名。

l getResults()函数，返回值是字符串数组类型，功能是获取所选择的所有文件的完整路径。

上述对话框支持多选，此时选择的文件的完整路径将作为字符串数组被保存，可以通过getResults()函数获取该数组，当对话框未开启多选模式或开启多选模式但只选择一个文件的情况下，该数组就只有一个元素了。


6.15.3 文件夹选择对话框TFolderChooseADlg

文件夹选择对话框只能用来选择文件夹，不能选择文件。跟其他的文件对话框不同的是，文件夹选择对话框不能够多选，外观也完全不同。


6.15.3.1 属性

l rootFolder属性，字符串类型，用来设置对话框选择范围：指定该属性为某路径时，则只能在该路径下选择文件夹。


6.15.3.2 对象常用属性和方法

l Root属性，获得选中的文件夹全名。

l chooseDlg()函数，返回值是布尔类型，打开对话框以选择文件夹，当选择有效的文件路径时，返回1，否则返回0.


6.15.3.3 简单范例

列表框和文件对话框范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       b:=new tbtn(self);

       listbox:=new TListBox(self);

       listbox.left:=10;

       listbox.top:=10;

       listbox.height:=350;

       listbox.width:=300;

       addFileBtn:=new tbtn(self);

       addFileBtn.left:=330;

       addFileBtn.top:=10;

       addFileBtn.caption:="添加文件";

       addFileBtn.onclick:=thisfunction(addFileBtnClick);

       deleteItemBtn:=new tbtn(self);

       deleteItemBtn.left:=330;

       deleteItemBtn.top:=50;

       deleteItemBtn.caption:="删除选中项";

       deleteItemBtn.onclick:=thisfunction(deleteItemBtnClick);

       clearBtn:=new tbtn(self);

       clearBtn.left:=330;

       clearBtn.top:=90;

       clearBtn.caption:="清空列表";

       clearBtn.onclick:=thisfunction(clearBtnClick);

       printBtn:=new tbtn(self);

       printBtn.left:=330;

       printBtn.top:=130;

       printBtn.caption:="打印路径";

       printBtn.onclick:=thisfunction(printBtnClick);

//文件夹选择框

dirBtn:=new tbtn(self);

dirBtn.left:=330;

dirBtn.top:=170;

dirBtn.caption:="文件夹选择框";

dirBtn.onclick:=thisfunction(dirBtnClick);

dir_ := new TFolderChooseADlg(self);

//dir_.RootFolder := "D:\\Files\\天软\\桌面工具测试\\";

dir_.editBox := 1;

dir_.defaultDir := "D:\\Files\\天软\\桌面工具测试\\";

       file:=new TOpenFileADlg(self);

       file.multiSelected:=1;

       file.caption:="添加文件";

       save:=new TSavefileADlg(self);

       save.filter:=array("文本文件":"*.txt","所有类型":"*.*");

       save.defaultFileExtension:="txt";

Save.OverwritePrompt := 1;

       save.caption:="保存文件";

setini();

    end

    function setini();

begin

       listbox.parent:=self;

       addFileBtn.parent:=self;

       deleteItemBtn.parent:=self;

       clearBtn.parent:=self;

       printBtn.parent:=self;

       file.parent:=self;

       save.parent:=self;

dir_.parent := self;

dirBtn.parent := self;

    end

private

    function addFileBtnClick(o,e);begin

       if (not file.chooseDlg()) then

           return;

       for i,v in file.getResults() do

           listbox.appendItem(v);

    End

function dirBtnClick(o,e);begin

        if (not dir_.chooseDlg()) then

           return;

       listbox.appendItem(dir_.Folder);

    End

    function deleteItemBtnClick(o,e);begin

       i:=listbox.getCurrentSelection();

       if i>=0 then

           listbox.deleteItem(i);

    end

    function clearBtnClick(o,e);begin

       listbox.clean();

    end

    function printBtnClick(o,e);begin

       if (not save.chooseDlg()) then

           return;

       dir:=save.getResults()[0];

       if(fileExists("",dir))then

           fileDelete("",dir);

       str:=array2str(listbox.Items,"\n");

       r:=writeFile(rwraw(),"",dir,0,length(str),str);

       if r=1 then

           MessageBoxA("保存成功","保存成功",0,self.Handle);

       else

           MessageBoxA(r,"保存失败",0,self.Handle);

    end

    listbox;

    file;

    save;

dir_;

    addFileBtn;

    deleteItemBtn;

    clearBtn;

    printBtn;

dirBtn;

end

----------------------------------------------------------------

该范例可以选择一些文件，并将它们的路径保存到指定目录下。

列表框和文件对话框范例


6.16 图像列表TControlImageList

图像列表是不可视控件，可以设置，但需要设置其他控件引用时方能在界面显示（详见工具栏TToolbar提供样例），但从功能上来看，它更像是一种数据结构，用来组织程序中用到的图像，以便于其他控件检索、使用。


6.16.1 属性

l Images:图标数组，将需要使用的图片添加到数组中并应用

l Imgwidth:图标数组各个图标展示时显示的宽度

l Imgheight:图标数组各个图标展示时显示的图标高度


6.16.2 对象属性和方法

l addBmp(bmp:TBitmap)函数，参数是TBitmap类型（见3.11.1），功能是向图像列表中添加图像。

l imgheigt 图标高度,修改后会清空图标,在addbmp前设置

l imgwidth 图标宽度,修改后会清空图标,在addbmp前设置

l removeImge(idx:int)函数，参数是整数类型，功能是移除指定索引的图像。

l imageCount属性，整数类型，用来获取图像列表中的图像数量。


6.16.3 位图类TBitmap

位图对象，用来存储位图信息以供程序中使用。

l id属性，表示图像的资源id，将该属性设置为硬盘中图像的路径即可读取并保存。图像应该是bmp或png格式的小图，其路径可以是绝对路径；也可以是相对路径（见代码6），此时相对路径起始地址从执行该程序所用的解释器所在的路径开始计算。

位图对象创建并设置后，即可将其添加至图像列表中以备使用。


6.17 工具栏TToolbar

工具栏是一个可以放置工具按钮的长条面板，位于窗口的顶部。往往将程序中最常用的功能添加到上面。

工具栏高度依赖工具栏按钮，控件机制的设计是将工具栏上的每一个按钮抽象出来，成为一个单独的类，在这些按钮对象中定义它们各自的属性，要想使用工具栏，不但需要创建工具栏控件，还需要创建并设置要用到的工具栏按钮对象，并将它们添加的工具栏上。


6.17.1 属性

l Imagelist:工具栏使用的图标列表

l Mainmenu：设置tmainmenul主菜单对象。


6.17.2 对象属性和方法

l addButton(btn:TToolButton)函数，参数是TToolButton类型，功能是将该工具栏按钮添加到上面

l insertButton(btn:TToolButton,bef:int)函数，第一个参数是TToolButton类型，是要添加的工具栏按钮，第二个参数是要添加的位置。

l deleteButton(btn:TToolButton)函数，参数是TToolButton类型，功能是当该工具栏控件已经被添加到工具栏上时，就把它移除。


6.17.3 工具栏按钮TToolButton

属性：

l imageId属性，整数类型，用来设置该按钮的图标（工具栏使用的图标列表对应的图标位置索引）。

事件：

l onclick属性，函数指针类型，当鼠标点击了该按钮时触发的事件。


6.17.4 简单范例

工具栏范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       //创建图像列表

       aImageList:=new TControlImageList(self);

       //创建位图对象并设置图像

       bmpo:=new TBitmap(self);

       //设置位图对象所用图像的硬盘位置，此处使用的是相对路径。

       bmpo.id:=".\\a.bmp";

       //将位图对象添加到图像列表中，此时图像列表中只有一个图像，其索引值为0.

       aImageList.addbmp(bmpo);

       //创建工具栏控件

       toolBar:=new TToolBar(self);

       //创建工具按钮，并设置其属性

       button:=new TToolButton(self);

       button.caption:="exit";

       button.imageid:=0;//将imageid属性设置为0，则

       button.onclick:=thisfunction(doexit);

       //设置工具栏的使用的图像列表

       toolBar.imagelist:=aImageList;

       //将按钮添加到工具条中

       toolBar.addbutton(button);

toolBar.parent:=self;

    end

private

    function doexit(o,e);begin

       if MessageBoxA(self.Handle,"是否退出","退出",1)=1 then

           ExitMessageLoop();

    end

    toolBar;

    aImageList;

end

----------------------------------------------------------------

代码中使用了如下所示的图标：

则在程序运行时，工具栏的显示如下所示：

另有界面案例演示范例相见目录：\tslediter\designer\Examples\toolbar


6.18 剪切板tclipboard


6.18.1 属性

l Text 属性：设置或者获取文本

l Bmp 属性：设置或者获取位图


6.19 状态栏TStatusBar

状态栏,通常位于窗口的底部,显示程序的运行状态。


6.19.1 属性

l items :属性,设置或者获取所有的item项目,二维数组包括,text 和 width 两个字段：

items := array(("width":0.8,"text":"a"),("width":100,"text":"b"));


6.19.2 事件

l Ondblclick：在鼠标双击左键时调用。


6.19.3 对象属性和方法

l Itemorder属性：布尔类型，项目排序方式，0：从左到右，1：从右到左。

l Itemtext(idx)属性：字符串，通过下标设置文本。其中idx是指定项索引，需idx存在才可修改，如itemtext(idx):=string。

l Ittemwidth(idx)属性：整数，通过下标设置项目宽度。其中idx是指定项索引，需idx存在才可修改，如itemwidth(idx):=width。

l simplepanel属性：显示单个状态字符串，布尔类型

l simpletext属性：显示的字符串，和simplepanel 配合使用

l additem(str:string,wd:integer)方法：新增下标项，str：下标项文本，wd：宽度。

l deleteitem(idx)方法：删除指定索引的下标项，idx是指定项索引。

l setitemtext(caption:string,idx:integer)方法：设置指定下标项的文本，其中idx是指定项索引，caption为该指定项设置的文字


6.19.4 简单范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.CreateForm(class(tvcform),fm);

status := new TStatusBar(fm);

status.items := array(("width":0.8,"text":"a"),("width":100,"text":"b"));

status.parent := fm;

Status.itemorder:=true;

Status.itemtext(1):="hello";

Status.itemwidth(1):=300;

fm.show();

app.run();

----------------------------------------------------------------

状态栏效果图


6.20 进度条tprogressbar

进度条,显示程序的运行状态。


6.20.1 属性

l Vertical:设置进度条进度走向是否为竖向展示

l Range:设置进度条的上下界,如range:=array(1,100)

l Position:设置进度条的进度到达的当前位置

l Barcolor: rgb颜色值,设置进度颜色


6.20.2 简单范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.CreateForm(class(tvcform),fm);

progress := new tprogressbar(fm);

progress.range := array(0,100);

progress.Position := 30;

progress.parent := fm;

fm.show();

app.run();

----------------------------------------------------------------

进度条效果图


6.21 日期选择控件


6.21.1 日历TMonthCalendar

为用户提供日历形式的日期选择功能，支持按月份前后滑动查看、输入指定年份、选择指定月份、跳回当天日期等，开发者可获取用户选择的日期、修改日期显示等。


6.21.1.1 属性

l border：布尔类型，设置日历控件是否有边框。


6.21.1.2 对象常用属性和函数

l getcurrentselection()：若返回一个array(year,month,day)类型则表示成功，0表示失败，nill表示未设置过此项。获取当前选择的日期。

l setcurrentselection(y,m,d)：参数分别未整数的年、月、日，返回1表示成功，0为失败，-1是出错。设置当前的选择日期。

l gettodayinfo()：返回一个array(year,month,day)类型则表示成功，0表示失败。获取“今日”按钮的日期信息。

l settodayinfo(y,m,d):参数分别是整数类型的年月日，返回为空。设置“今日”按钮的日期。


6.21.2 时间日期选择 TDatetimePicker

时间日期选择控件在使用方式上与日历控件一致，只是此控件只用三组数字显示年月日信息，而不把整个日历图标显示出来。


6.21.3 时间选择 TTimePicker

与事件日期选择控件类似，此控件提供时、分、秒的选择和设定，常常与时间日期选择控件一起搭配使用。


6.21.3.1 对象常用属性和函数

l gettime()：返回类型为array(hour,minute,second)。获取控件当前选择的时间。

l settime(h,m,s)：参数分别为整数类型的时（24小时制）、分、秒。设置控件当前选择的时间。


6.22 自绘制表格gridctl

自绘制表格，根据需要绘制表格。


6.22.1 属性

l Columncount：整数类型，列数

l Itemcount：整数类型，行数

l mousesizecell：布尔类型，是否可调整列宽

l Fixedrows：布尔类型，固定首行

l Fixedcolumns：布尔类型，固定首列


6.22.2 事件

l ondrawcell：自行绘制表格，通过消息对象e的row,col,rec,cavas等属性进行绘制。

l Onhttcellsizer：当mousesizecell是否可调整列宽为真时，触碰单元格右边线时触发。

l Ondblclick：在鼠标双击左键时调用。


6.22.3 对象常用属性和方法

l Mergecells(cells:array)函数：合并单元格，格式array((开始行，开始列，结束行，结束列))，多个范围合并时，cells数组第二行为第二个合并范围。


6.22.4 简单范例

Tgridctl范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;

    begin

       inherited;

       gridctl1:=new tgridctl(self);

       gridctl1.columncount:=5;

       gridctl1.itemcount:=5;

       gridctl1.top:=210;

       gridctl1.height:=260;

       gridctl1.width:=600;

       gridctl1.ondrawcell:=thisfunction(gridctl2_drawcell);

       gridctl1.mergecells(array(1,1,2,2));

gridctl1.parent:=self;

    end

    function gridctl2_drawcell(o;e);virtual;

    begin

    {**

        @explan(说明) 绘制表格 %%

        @param(o)(tlistview) grid对象 %%

        @param(e)(tuieventbase) 消息对象包括,row,col,rec,cavas等属性提供绘制信息 %%

    **}

    //绘制表头

       i := e.row;

       j := e.col;

       rec := e.rec;

       cvs := e.canvas;

       if i<o.FixedRows or j<o.FixedColumns then

       begin

           cvs.Draw('FrameControl',array(rec[0:1],rec[2:3]),DFC_BUTTON,DFCS_BUTTONPUSH); //DFCS_CHECKED DFCS_FLAT

       end

       //绘制网格线

       cvs.moveto(rec[array(2,1)]);

       cvs.LineTo(rec[array(2,3)]);

       cvs.LineTo(rec[array(0,3)]);

       if j=0 then

       begin

           cvs.LineTo(rec[array(0,1)]);

       end

       if i=0 then

       begin

           cvs.MoveTo(rec[array(0,1)]);

           cvs.LineTo(rec[array(2,1)]);

       end

       //绘制文本

       cvs.drawtext(format('%d,%d',i,j),rec,DT_VCENTER .| DT_SINGLELINE .| DT_CENTER .| DT_NOPREFIX);

       inherited;

    end

private

    gridctl1;

End

上述范例，生产坐标，并合并（1，1）至（2，2）单元格


6.23 分割条splitter

分割条，用于分割两个容器，实现类似分页控件的功能，不过使用上更加灵活。通过设置控件A、控件B，和分割条的algin对齐方式属性，使控件A，B以分割条间隔开，并可通过拖拽分割条改变两控件的大小显示。


6.23.1 属性

l transparent属性，布尔类型，是否采用父控件的背景


6.24 容器控件

前面介绍了常用的控件，这些控件都是拥有特定功能的窗口，接下来要介绍的是没有自己的功能，专门用来放置其他控件的窗口，叫做容器。


6.24.1 属性

l minWidth：整数类型，用来设置窗口的最小宽度，当窗口的宽度等于该值时，将不能调整的更小。

l minHeight：整数类型，用来设置窗口的最小高度，当窗口的高度等于该值时，将不能调整的更小。

l wssizebox：布尔类型，设置是否显示边框样式。


6.24.2 程序主窗口 TVCForm

TVCForm是程序的主窗口，所有的控件最终都要被放置在主窗口上，一个程序可能拥有多个主窗口。运行以下代码即可创建一个空的、原始的主窗口。


6.24.2.1 事件

l Oncreated：窗口初始化后触发

l Ondestroy：窗口关闭后触发


6.24.2.2 简单范例

创建一个主窗口

----------------------------------------------------------------

uses tslvcl;//使用库文件

app := InitializeApplication();//初始化UI程序

app.createform(class(tvcform),form);//创建程序窗口

app.run();//启动程序窗口

----------------------------------------------------------------

主窗口tvcform

tvcform只是一个空的窗口，为了能够开发出可用的程序，可以使该类派生出一个新类，然后在新类中设置控件及功能，然后令程序创建这个新的类作为窗口。

自定义窗口

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tvcform),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       //在此实现所需的功能

    end

end

----------------------------------------------------------------

在上述类中，有一个create函数，这个是类的构造函数，通常在此处为该类中定义的新的数据成员初始化；

TVCForm有一个常用的属性：onClose函数指针，当用户点击了窗口的关闭按钮时将会调用该函数。可以在该函数中执行一些有必要的操作；程序调用函数的第二个参数拥有一个skip属性，将该属性设置为1就能够跳过该操作：关闭窗口的操作。利用这个特性可以实现当关闭窗口时询问是否确定关闭的操作，如下所示：

文本框: self.onclose:=function(o,e);begin if MessageBoxA(self.Handle,"是否退出","退出",1)<>1 then e.skip:=1; end

在主窗口的构造函数中加入以上代码，就能够实现这个效果。

窗口关闭提示


6.24.3 带标签的容器tgroupbox


6.24.3.1 属性

l textPos属性：标签位置


6.24.4 带边框样式的控件 tbevel


6.24.4.1 属性

l shape：外形 tbevelshape 成员

l style：样式 tbevelstyle 成员


6.24.5 面板 TPanel

TPanel和TVCForm一样都是，可以放置其他的控件或容器，而不同的是，TPanel不是一个主窗口，也就意味着它需要被放置在其他的容器中。


6.24.5.1 属性

l wspopup：布尔类型，设置是否允许面板在父窗口外自由放置。

l wscaption：布尔类型，设置是否显示标题，标题内容可在caption属性中修改。

l wssizebox：布尔类型，可调整边框大小。

l wssysmenu：布尔类型，设置是否显示标题及其菜单菜单栏。

l bevelinner：设置内斜面样式。

l bevelouter：设置外斜面样式。

l bevelwidth：设置斜面宽度。

l borderwidth：设置边框宽度。


6.24.6 页面控件ttabcontrol

该控件和tpagecontrol控件类似，但不提供容器功能，使用者可以根据标签的改变，执行安排行为


6.24.6.1 属性

l cursel：当前标签的序号

l TabCount：标签总数

l tabs：标签

l ownerdraw：是否支持自绘制


6.24.6.2 事件

l onmeasuretabwidth：宽度测量回调

l TabPosition：位置，上下左右

l tabheight：高度

l ondrawtab：自绘制回调，和ownerdraw配合使用


6.24.7 选项卡控件 TPageControl

选项卡控件是可以像笔记本一样，将各个容器分页显示的控件。控件上方是页名，下侧是显示的具体的页。当点击上方的某个页名时，控件下侧即切换至该页名对应的页。在控件标签空白处右键即可添加选选项卡页对象，可将普通控件放入到每个选项卡页面中，它们彼此独立。

选项卡控件


6.24.7.1 属性

l tabsheet(i):序号对应的tabsheet。

l activetabsheet：当前的tabsheet


6.24.7.2 对象常用属性和方法

l cursel属性：整数类型，用来设置默认展示的页。

l tabCount属性：整数类型，用来获取控件中选项卡页的数量。

l setTabIndex(oidx:int,newidx:int)函数，参数是整数类型，功能是调整选项卡页的顺序：将索引为oidx的页调整至newidx的位置。


6.24.8 选项卡页 TTabSheet

选项卡控件中可以新建选项卡页，选项卡页可以当做普通的容器使用；通过修改其caption属性可以改变该页在控件上显示的名称。


6.24.8.1 简单范例

选项卡控件范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       pageControl:=new TPageControl(self);

       label1:=new tlabel(self);

       label1.caption:="PAGE1";

       tabsheet1:=new TTabSheet(self);

       tabsheet1.caption:="1";

       tabsheet2:=new TTabSheet(self);

       tabsheet2.caption:="2";

setini();

    end

    function setini();begin

       tabsheet1.parent:=pageControl;

       label1.parent:=tabsheet1;

       tabsheet2.parent:=pageControl;

       pageControl.parent:=self;

    end

private

    pageControl;

    tabsheet1;

    tabsheet2;

    label1;

end

----------------------------------------------------------------


6.24.9 分页控件 TPairSplitter

分页控件也是容器，可以分栏显示（默认是并排显示）两个容器，它们之间互不影响。

分页控件


6.24.9.1 属性

l splitterType属性：整数类型，用来设置控件视图，可选pstHorizontal横向和pstVertical纵向。

l position属性：整数类型，用来获取和设置控件中间分隔位置，以像素为单位。

l wspopup：布尔类型，设置是否允许面板在父窗口外自由放置。

l wscaption：布尔类型，设置是否显示标题，标题内容可在caption属性中修改。

l wssizebox：布尔类型，可调整边框大小。

l wssysmenu：布尔类型，设置是否显示标题及其菜单菜单栏。


6.24.9.2 简单范例

分页控件范例

----------------------------------------------------------------

uses tslvcl;

app := InitializeApplication();

app.createform(class(tforma),form);

app.run();

type tforma=class(tvcform)

    function create(AOwner);override;begin

       inherited;

       pairSplitter:=new TPairSplitter(self);

       pairSplitter.width:=300;

       pairSplitter.height:=300;

       label1:=new tlabel(self);

       label1.caption:="SIDE1";

       pairSplitterSide1:=new TPairSplitterSide(self);

       pairSplitterSide2:=new TPairSplitterSide(self);

setini();

    end

    function setini();begin

       pairSplitterSide1.parent:=pairSplitter;

       label1.parent:=pairSplitterSide1;

       pairSplitterSide2.parent:=pairSplitter;

       pairSplitter.parent:=self;

       pairSplitter.position:=100;

    end

private

    pairSplitter;

    pairSplitterSide1;

    pairSplitterSide2;

    label1;

end

----------------------------------------------------------------


6.24.10 工具条容器tcoolbar

工具条容器，可以将各类控件放置到工具条容器中，形成一个多功能可自由拖动的控件。

如：工具中的代码编辑栏


6.24.10.1 属性

l autosize,布尔类型，自动调整大小。

l dragbtncolor：设置拖动按钮颜色

l arrange:设置子控件的次序，同一行的用逗号“,”隔开，换行的用分号“;”隔开。如0,1;2；


7. 绘图库介绍


7.1 绘图库基础类介绍


7.1.1 常量类 tg_const

tg_const为常量类型，作为绘图库中所有类型的基类，提供常量别名。

该常量类包含常量别名说明如下：

l 基础类型

1. tgc_off：赋值off，说明绘制对象属性赋值关闭，line_mode:=tgc_off跟line_mode:=’off’含义一样；

2. tgc_on：赋值on，说明绘制对象属性赋值打开，line_mode:=tgc_on；

l 坐标轴类型

1. tgc_direct_asc：赋值asc，说明刻度在坐标轴上方，axis.tics_diretion:=axis.tgc_direct_asc;

2. tgc_direct_desc：赋值desc，说明刻度在坐标轴下方，axis.tics_diretion:=axis.tgc_direct_desc;

3. tgc_top：赋值top，说明坐标轴置于坐标系顶部，axes.x_location := axes.tgc_top；

4. tgc_bottom：赋值bottom，说明坐标轴置于坐标系底部，axes.x_location:=axes.tgc_bottom；

5. tgc_left：赋值left，说明坐标轴置于坐标系左部，axes.y_location:=axes.tgc_left；

6. tgc_right：赋值right，说明坐标轴置于坐标系右部，axes.y_location:=axes.tgc_right;

7. tgc_middle：赋值middle，说明坐标轴置于坐标系中部，axes.y_location:=axes.tgc_middle；

8. tgc_origin：赋值origin，说明坐标系置于坐标系原点，axes.y_location:=axes.tgc_origin；

9. tgc_box_off：赋值off，说明坐标系对象边框属性赋值关闭；axes.box:= axes.tgc_box_off；

10. tgc_box_on：赋值on，说明坐标系对象边框属性赋值打开；axes.box:=axes.tgc_box_on；

11. tgc_box_half：赋值half，暂无效；axes.box:=axes.tgc_box_half；

12. tgc_box_hidden_axes：赋值hidden_axes，暂无效；axes.box:=axes.tgc_box_hidden_axes；

13. tgc_tics_v：赋值v，说明坐标轴刻度计算方式为自定义；axis.tics_style:=axes.tgc_tics_v；

14. tgc_tics_r：赋值r，说明坐标轴刻度计算方式为等分法；axis.tics_style:=axes.tgc_tics_r；

15. tgc_tics_i：赋值i，暂无效；axis.tics_style:=axes.tgc_tics_i；

l 标记类型

1. tgc_mks_dot：赋值dot，说明标记类型样式为点类型；line.markinfo.style:=line.tgc_mks_dot；

2. tgc_mks_plus：赋值plus，说明标记类型样式为加号类型；line.markinfo.style:=line.tgc_mks_plus；

3. tgc_mks_star：赋值star，说明标记类型样式为圆形-加号类型；line.markinfo.style:=line.tgc_mks_star；

4. tgc_mks_diamond：赋值diamond，说明标记类型样式为方块类型；line.markinfo.style:=tgc_mks_diamond；

5. tgc_mks_diamond_plus：赋值diamond_plus，说明标记类型样式为方块-叉类型；line.markinfo.style:=line.tgc_mks_diamond_plus；

6. tgc_mks_square：赋值square，说明标记类型样式为正方形类型；line.markinfo.style:=line.tgc_mks_square；

7. tgc_mks_circle：赋值circle，说明标记类型样式为圆形类型；line.markinfo.style:=line.tgc_mks_circle；

8. tgc_mks_pentagram：赋值pentagram，说明标记类型样式为星星类型；line.markinfo.style:=line.tgc_mks_pentagram；

9. tgc_mks_asterisk：赋值asterisk，说明标记类型样式为米字类型；line.markinfo.style:=line.tgc_mks_asterisk；

10. tgc_mks_cross：赋值cross，说明标记类型样式为叉类型；line.markinfo.style:=line.tgc_mks_cross；

11. tgc_mks_triangle_up：赋值triangle_up，说明标记类型样式为三角类型（顶角向上）；line.markinfo.style:=line.tgc_mks_triangle_up；

12. tgc_mks_triangle_down：赋值triangle_down，说明标记类型样式为三角形类型（顶角向下）；line.markinfo.style:=line.tgc_mks_triangle_down；

13. tgc_mks_triangle_left：赋值triangle_left，说明标记类型样式为三角形类型（顶角向左）；line.markinfo.style:=line.tgc_mks_triangle_left；

14. tgc_mks_triangle_right：赋值triangle_right，说明标记类型样式为三角形类型（顶角向右）；

l 数据提示类型

1. tgc_DT_always：赋值always，说明一直显示数据提示；

2. tgc_DT_mouseclick：赋值mouseclick，说明区域经鼠标点击显示数据提示；

3. tgc_DT_mouseover：赋值mouseover，说明区域经鼠标悬置显示数据提示；

l 线类型

1. tgc_PS_SOLID：赋值0x0，说明线对象的线类型为实线；line.lineinfo.style:=line.tgc_PS_SOLID；

2. tgc_PS_DASH：赋值0x1，说明线对象的线类型为虚线（长线条虚线）；line.lineinfo.style:=line.tgc_PS_DASH；

3. tgc_PS_DOT：赋值0x2，说明线对象的线类型为虚线（点状虚线）；line.lineinfo.style:=line.tgc_PS_DOT；

4. tgc_PS_DASHDOT：赋值0x3，说明线对象的线类型为虚线（长线-点虚线）；line.lineinfo.style:=tgc_PS_DASHDOT;

5. tgc_PS_DASHDOTDOT：赋值0x4，说明线对象的线类型为虚线（长线-点-点修仙）；line.lineinfo.style:=line.tgc_PS_DASHDATDOT；

6. tgc_PS_NULL：赋值0x5，说明线对象的线类型为无（不显示）；line.lineinfo.style:=line.tgc_PS_NULL；

l 线型类型

1. tgc_LS_interpolated：赋值interpolated，说明线型类型赋值曲线样式；line.polyline_style:=line.tgc_LS_interpolated；

2. tgc_LS_staircase：赋值staircase，说明线型类型赋值楼梯样式；line.polyline_style:=line.tgc_LS_staircase；

3. tgc_LS_arrowed：赋值arrowed，说明线型类型赋值箭头样式；line.polyline_style:=line.tgc_LS_arrowed；

4. tgc_LS_barplot：赋值barplot，说明线型类型赋值条形样式；line.polyline_style:=line.tgc_LS_barplot；

5. tgc_LS_filled：赋值filled，说明线型类型赋值条形填充颜色样式；line.polyline_style:=line.tgc_LS_filled；

6. tgc_LS_bar：赋值bar，说明线型类型赋值条样式；line.polyline_style:=line.tgc_LS_bar;

l 相对位置类型

1. tgc_in_upper_right：赋值in_upper_right，说明相对位置是基于parent对象内部右上角位置；lg.location:=lg.tgc_in_upper_right；

2. tgc_in_upper_left：赋值in_upper_left，说明相对位置是基于parent对象内部左上角位置；lg.location:=lg.tgc_in_upper_left；

3. tgc_in_lower_right：赋值in_lower_right，说明相对位置是基于parent对象内部右下角位置；lg.location:=lg.tgc_in_lower_right；

4. tgc_in_lower_left：赋值in_lower_left，说明相对位置是基于parent对象内部左下角位置；lg.location:=lg.tgc_in_lower_left；

5. tgc_upper_caption：赋值upper_caption，说明相对位置是基于parent标题近的上方位置；lg.location:=lg.tgc_upper_caption；

6. tgc_lower_caption：赋值lower_caption，说明相对位置是基于parent标题近的下方位置；lg.location:=lg.tgc_lower_caption；

7. tgc_by_coordinates：赋值by_coordinates，说明相对位置是基于parent坐标位置；lg.location:=lg.tgc_by_coordinates；

8. tgc_by_axes：赋值by_axes，说明相对位置是基于parent坐标系位置；lg.location:=lg.tgc_by_axes；

l 事件类型

1. evt_mouse_down：赋值mouse_down，鼠标按下事件；

2. evt_mouse_wheel：赋值mouse_wheel，鼠标滚轮滚动事件；

3. evt_mouse_move：赋值mouse_move，鼠标移动事件；

4. evt_mouse_in：赋值mouse_in，鼠标在区域内事件；

5. evt_mouse_out：赋值mouse_out，鼠标在区域外事件；

6. evt_mouse_up：赋值mouse_up，鼠标松开事件；


7.1.2 绘图画布类 tg_canvas

tg_canvas创建的对象以窗口中的canvas为父类，并且增量了相关辅助函数。

基础函数：

l Axesclip()：限定到坐标系区域；

l Axesunclip()：取消坐标系区域限定；

l Axesrec()：坐标系的范围；


7.1.3 画笔线型信息类 tg_line_info

tg_line_info对象用于保存画笔线型相关属性信息。

基础属性：

l Style：线型样式；具体样式请参考常量类tg_const中的线类型说明，列如要设置线对象中的线类型样式为长线条虚线时语句：line.lineinfo.style:=line.tgc_PS_DASH；

l Size：线宽度，单位像素；设置线宽度为2像素的语法范例：line.lineinfo.size:=2；

l Color：线的颜色；设置线的颜色为红色语法范例：line.lineinfo.color:=0x0000ff；

l Bkcolor：线型封闭后背景的颜色；设置线型封闭后背景颜色为黄色语法范例：line.lineinfo.bkcolor:=0x00ffff；


7.1.4 字体信息类 tg_font_info

tg_font_info对象用于保存图形字体相关属性信息。

基础属性：

l Size：正整数类型；字号，宽度的像素；设置坐标系中x轴刻度字体大小为8范例：axs.axises(0).fontinfo.size:=8；

l Color：字体颜色；设置坐标系中x轴刻度字体颜色为红色范例：axs.axises(0).fontinfo.color:=0x0000ff；

l Bkcolor：背景颜色；设置坐标系中x轴刻度字体块背景填充颜色为黄色范例：axs.axises(0).fontinfo.bkcolor:=0x00ffff；


7.1.5 点标记信息类 tg_mark_info

tg_mark_info对象用于保存图形中点标记相关属性信息。

基础属性：

l Style：点标记样式；点标记具体样式参考常量类tg_const中的标记类型；列如线对象中点标记类型设置为点标记类型时语句：line.markinfo.style:=line.tgc_mks_dot；

l Size：点标记大小，单位为像素；设置线对象中标记的大小为5像素范例：line.markinfo.size:=5；

l Color：标记点颜色；设置线对象中标记信息的颜色为红色范例：line.markinfo.color:=0x0000ff;

l Bkcolor：标记点背景颜色；设置线对象中标记信息填充颜色为黄色范例：line.markinfo.bkcolor:=0x00ffff;


7.1.6 绘图类基类 tg_base

tg_base属于绘图类基类，提供一些基础功能，以及层次关系。

基础功能：

l Markinfo：标记信息，tg_mark_info对象类型；说明tg_base类以及继承它的子类创建的对象都可以使用tg_mark_info类创建的markinfo对象，并给该对象相关属性赋值；比如tg_Polyline类创建线对象line，并给它的markinfo对象的标记样式赋值为点标记样式的范例：line.markinfo.style:=line.tgc_mks_dot；

l Lineinfo：画笔信息，tg_line_info对象类型；说明tg_base类以及继承它的子类创建的对象都可以使用tg_line_info类创建的lineinfo对象，并给该对象相关属性赋值；比如tg_Polyline类创建线对象line，并给它的lineinfo对象的线条颜色属性赋值为红色范例：line.lineinfo.color:=0x0000ff；

l Fontinfo：字体信息，tg_font_info对象类型；说明tg_base类以及继承它的子类创建的对象都可以使用tg_font_info类创建的fontinfo对象，并给该对象相关属性赋值；比如tg_axis类创建线对象ais，并给它的fontinfo对象中字体颜色属性赋值为红色范例：ais.fontinfo.color:=0x0000ff；

l line_mode：是否画线；说明图形是否用数据画出线图，line.line_mode:=line.tgc_off语句代表图像中不会出现画线；

l Mark_mode：是否画点的标记；说明图形是否用数据画出点标记，line.mark_mode:=line.tgc_on语句代表图像显示数据画出点标记；

l clip_state：是否裁剪区域；说明图形是否超出父容器裁剪区域，line.clip_state:=line.tgc_off语句代表着图形能够超出裁剪区域显示；

l zoom_to_xyz(x,y,z,var _x,var _y,var _z)：通过坐标点计算画布点位置；通过坐标点（2，1，0）获取到画布点的范例：axs.zoom_to_xyz(2,1,0,_x,_y,_z);；

l xyz_to_zoom(x,y,z,var x_,var y_,var z_)：通过画布点位置计算坐标点位置；

l Set_lineinfo_to_canvas(cvs,peninfo)：设置当前画笔信息到画布；设置范例：set_lineinfo_to_canvas(cvs);；

l Set_fontinfo_to_canvas(cvs,info)：设置当前字体信息到画布；

l Paint(cvs);vartual;该函数由tg_figure的管理者适当时候发起，并送入tg_canvas对象；

l addEventListener(etype,fun(e),ifCapture)：添加消息处理；

l removeEventListener(etype,fun(e),ifCapture)：移除消息处理；

l dispatchEvent(evt)：分发消息；

层次关系：

l Parent：设置父节点；

l Nodecount：获取子节点数量；

l GetNodeByIndex：通过序号获取子节点；

l Set_node_index(nd,idx)：设置子节点的序号；


7.1.7 坐标容器类 tg_figure

tg_figure创建的对象，可以在上面放坐标系，设置坐标系的位置信息。

基础属性：

l Rec_getter：区域获取，返回画布区域 array(左上右下)；该属性定义为回调函数，使用时须自己定义函数赋值给它；列如：ffigure.rec_getter:=function()begin return array(0,0,200,200); end；

l fresh_caller：刷新回调；该属性也是回调函数，使用时须自定义函数赋值给它；

基础函数：

l Add_axes(axes)：添加坐标系；

l Del_axes(axes)：删除坐标系；

l executecommand(cmd,p)：命令行执行；

l Paint(cvs)：送入画布对象，绘制各个图形；如果是窗口，在onpaint消息中调用该函数；


7.1.8 坐标系类 tg_axes

tg_axes创建的对象作为绘图的基础载体，以及位置关系的基准。

基础属性：

l Title：标题，tg_label类型；用于设置坐标系的标题属性，设置坐标系标题名为“tg_axes test”范例：axs.title.text :=’tg_axes test’；

l y_label：y轴标签，tg_label_axis类型；用于设置坐标系y轴标签属性，设置坐标系y轴标题名为“y 轴”范例：axs.y_label.text :=’y 轴’；

l x_label：x轴标签，tg_label_axis类型；用于设置坐标系x轴标题属性，设置坐标系x轴标题名为“x 轴”范例：axs.x_label.text :=’x 轴’；

l Axises(idx)：tg_axis数组类型，其中idx为0,1,2时分别获取对应坐标系的x,y,z轴；设置坐标系中x轴字体大小为5像素范例：axs.axiese(0).fontinfo.size:=5；

l Axes_reverse(idx)：设置tgc_on|tgc_off 代表坐标轴是否反向，默认为tgc_off正向；设置坐标系中x轴反向范例：axs.axes_reverse(0):=axs.tgc_on；

l Auto_ticks(idx)：自动刻度线，设置tgc_on|tgc_off，设置坐标轴刻度是否自动计算，默认为tgc_on自动计算；设置坐标系x轴不要自动计算范例：axs.auto_ticks(0):=axs.tgc_off；

l Margins：空白区域，array(左上右下)设置上下左右空白，tg_figure区域百分比；设置坐标系上下左右空白区域为左百分之五、上百分之十五、右百分之十、下百分之十的范例：axs.margins:=array(0.05,0.15,0,1,0.1)；

l Axes_bounds：坐标轴边界，array(左，上，右，下)设置坐标系的范围，扣除margains边界，按比例分配；输出获取坐标系中坐标轴默认边界范例：echo “axesbounds: ”,tostn(axs.axes_bounds),’\r\n’;输出结果为axesbounds: array(0,0,1,1)；

l Data_bounds(idx)：数据边界，获取或者设置数据范围，array((x0,x1),(y0,y1),(z0,z1))；设置之后，对应轴的数据显示范围不会随着数据改变而改变；如果需要改变则设置data_bounds(idx):=tgc_off;

l X_location：X坐标轴方向，tgc_bottom（x轴居下），tgc_top（x轴居上），tgc_middle（x轴居中），tgc_origin（x轴原点）；

l Y_location：Y坐标轴方向，tgc_left（y轴居左），tgc_right（y轴居右），tgc_middle（y轴居中），tgc_origin（y轴原点）；

l BOX：设置tgc_on|tgc_off，代表是否有边框，默认为tgc_off无边框；设置坐标系有边框范例：axs.box:=axs.tgc_on；

l Grid(idx)：背景网格属性，tg_line_info对象，size属性为0或者false时网格线消失；设置水平方向有网格范例：axs.grid(0).size:=1或者axs.grid(0).size:=true；

l Squred：等长宽属性，设置tgc_on|tgc_off代表绘制区域是否采用等长宽(比例)，适用于饼图等；

l Zoom_box：视图范围；获取坐标系的视图范围范例：echo ‘zoom_box: ’,tostn(axs.zoom_box),’\r\n’；输出结果为：zoom_box: array((0,1),(0,1),(0,1));


7.1.9 坐标轴类 tg_axis

tg_axis对象可以放置在坐标系对象中，且可以放置任意多个坐标轴。

基础属性：

l tics_direction：坐标轴方向，tgc_direct_asc(坐标轴指向的左手方向)，tgc_direct_desc；

l tics_style：刻度类型，类型赋值：ais.tics_style:=ais.tgc_tics_v(设置值，设置tics_coord刻度值时由用户自定义)，类型赋值ais.tics_style:=ais.tgc_tics_r(自动计算，[x0,x1,interval]，x0代表坐标轴起始值，x1代表坐标轴终点值，interval则代表起点到终点中的刻度线数目)；

l Tics_coord：刻度，根据tics_style确定用户自定义[2,3,4,5,6,7]，自动计算计算[start,end,interval]；当tics_style为tgc_tics_v时赋值刻度范例：ais.tics_coord:=array(2,3,4,5,6)；当tics_style为tgc_tics_r时赋值刻度范例为：ais.tics_coord:=array(2,6,5)；

l Ytics_coord：位置，设置在另一个方向的位置，相对坐标系的数据位置；array(x,y,z)对应三维坐标，x,y,z中为非数字的值时表示该坐标轴在对应维度上面；设置一个横向坐标轴对应y轴0.2刻度到坐标系中范例：ais.ytics_cood:=array(’x’,0.2,0)；

l Tics_segment：是否有轴线,赋值布尔型true|false，默认为true有刻度线；设置坐标轴没有刻度线范例：ais.tics_segment:=false；

l tics_color：刻度线颜色；设置刻度线颜色为红色范例：ais.tics_color:=0x0000ff；

l sub_tics：子刻度个数；设置子刻度线个数为5范例：ais.sub_tics:=5；

l tics_labels：刻度值对应的标签，一串字符串数组；给坐标轴上刻度值赋值对应刻度线范例：ais.tics_labels:=array(’0.2’,’0.3’,’0.4’,’0.5’,’0.6’)；

l axis_label：轴标签；


7.1.10 标签类 tg_label

tg_label对象以axes作为父节点。

基础属性：

l Text：文本；设置标签文本为‘consts’范例：axs.title.text:=’consts’；

l Postion：坐标系位置；获取坐标系标题位置范例：echo 'label_position：',tostn(axs.title.Position),'\r\n';返回结果为label_position：array(0,0)；

l auto_position：自动位置，在坐标轴标签中使用；

l font_angle：设置角度；说明：标签中其他字体相关通过fontinfo设置；设置坐标系标题文本旋转45度范例：axs.title.font_angle := pi()/4；


7.1.11 图基类 tg_graph_base

tg_graph_base图基类继承绘图类基类tg_base，兼容绘图和goup两个类型。

基本函数：

l Get_data_bounds();virtual;：获取数据边界；


7.1.12 图形类 tg_graph

tg_graph图形类继承图基类tg_graph_base，绘图对象，包括数据、提示等内容。

基础属性：

l graph_data：绘图数据；

基础函数：

l get_data_tips()：获取数据提示对象；

l get_legend_size(var w,var h);virtual;：获取图例中的大小；

l paint_legend(cvs,rec);virtual;：绘制图例；

l get_graph_data_by_idx(idx);：通过数据序号获取数据；


7.1.13 线图类tg_polyline

tg_Polyline线图对象，以图形类tg_graph为父类。

基础属性：

l Closed：是否封闭的图像，布尔类型，默认为false不封闭；设置为封闭图像范例：line.closed:=true；

l polyline_style：线类型，详细属性值见常量类tg_const中线型类型；设置线类型为箭头样式范例：line.polyline_style:=line.tgc_LS_arrowed；

l Bar_width：柱状宽度，柱形图类型时候的宽度；设置柱宽度为10像素范例：line.bar_width:=10；


7.1.14 图例类tg_legend

tg_legend图例对象，以绘图类基类tg_base为父类。

基础属性：

l Location：相对位置类型，具体属性见常量类tg_const中相对位置类型说明；设置图例相对位置处于坐标系内部右上角范例：lg.location:=lg.tgc_in_upper_right；

l Position：位置，定位为tgc_by_coordinates，设置具体位置array(x,y)；设置图例位置为坐标系原点范例：lg.positon:=array(0,0)；

l Line_mode：边框线，布尔类型，默认为true存在边框线；存疑,设置为false时，边框好像还是存在；

l Links：关联的绘图，tg_graph数组；设置图例对象管理线型绘图范例：lg.links:=array(line)；

l Text：文本内容，字符串数组；设置绘图回应图例中相关文本范例：lg.text:=array(’aaa’);


7.1.15 数据点提示类tg_tips

tg_tips数据点提示对象，父节点为tg_graph对象。

基础属性：

l Location：对应位置；

l Text：文本数组；

l Data：数据；

l data_idx：绑定数据序号；


7.1.16 文本展示类tg_text

tg_text文本展示对象，以绘图类基类tg_base为父类，主要用于图形文本展示。

基础属性：

l Text：文本内容，字符串数组；

l Font_angle：角度；设置文本旋转45度范例：axs.title.font_angle := pi()/4;

l Data：array(x,y,z)相对于坐标系的位置；


7.1.17 绘图展示窗口类tg_wincontrol

Tg_Wincontrol绘图展示窗口对象。管理一个tg_figure对象，在paint消息的时候构造tg_canvas对象，并调用tg_figure的paint函数实现图形的绘制。其仅仅作为一个案例，用户可以按照其原理构建自己的画布类，驱动绘制，得到想要的图形。


7.1.18 图片容器类tg_picture

tg_picture为图片容器对象，可以将图片保存为png。

基础函数:

l save_png(fn)函数: 参数fn为将图片保存的路径，将绘图保存到指定路径下的png格式图片。


7.1.19 图像组合类tg_compound

Tg_compound为图像组合对象，组合多个图像，继承图形类Tg_graph；主要用于将多个图像对象存放到Tg_compound对象中，并自动组合计算在容器的边界。


7.2 绘图库基础类使用范例


7.2.1 保存绘制图片到PNG范例

uses utvclgraphics;

//创建图片tg_picture对象

fg := new tg_picture(800,800);

//////////设置坐标轴属性////////////////////////

axs := new tg_axes(); //创建坐标系对象

axs.box := false; //设置坐标系无边框

axs.figure := fg; //设置坐标系的坐标容器

axs.title.text := "hello pie "; //设置坐标系标题文本

axs.axises(1).visible:=false;//设置坐标系y轴不显示

axs.axises(0).visible:= false;//设置坐标系x轴不显示

axs.data_bounds(0) := array(-0.1,2.1); //设置坐标系x轴数据范围在-0.1到2.1之间

axs.data_bounds(1) := array(-0.1,2.1); //设置坐标系y轴数据范围在-0.1到2.1之间

axs.data_bounds(2) := array(-0.5,0.5);//设置坐标系z轴数据范围在-0.5到0.5之间

args := array(

(pi()/4,pi()/3,0x0000ff),

(pi()/3,pi()/2,0x00ff00),

(pi()/2,pi()*3/4,0xff0000),

(pi()*3/4,pi(),0xff00ff),

(pi(),pi()*9/4,0x000000)

); //设置绘制饼图的区块以及区块颜色的数据

prominentidx := 0; //凸显的块

prominentrate := 0.1; //凸显的块

for i,v in args do

begin

line := new tg_Polyline(); //创建线对象

line.polyline_style := line.tgc_LS_filled;//设置线对象的线类型为填充类型

line.closed := true;//设置线对象是封闭图

line.graph_data := 1+get_pie_lines(v[0],v[1],i=prominentidx,prominentrate); //设置画线图的数据

line.lineinfo.bkcolor := v[2]; //设置闭环线图的背景填充颜色

line.parent := axs; //设置线图的父节点

end

fg.save_png(%% D:\test\ppt2.png%%); //保存

function get_pie_lines(arg1,arg2,prominent,prominentrate);//处理饼图数据函数

begin

stp := pi()/180;

r := array();

r[0] := array(0,0);

idx := 1;

for i:= arg1+(prominent?stp:0) to arg2-(prominent?stp:0) step stp do

begin

r[idx++] := array(sin(i),cos(i));

end

r[idx] :=array(0,0);

if prominent then //是否凸出

begin

rx := r[integer(idx/2)]*prominentrate;

for i := 0 to idx do

begin

r[i]+=rx;

end

end

return r;

End


7.2.2 线图范例

uses tslvcl,utvclgraphics;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

Caption := "line";

fg := new tg_WinControl(self); //设置绘图展示窗口对象

fg.Caption := "hello1"; //设置窗口标题文本

fg.parent := self; //设置窗口父节点

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes(); //创建坐标系对象

axs.figure := fg.figure; //设置坐标系的坐标容器

axs.title.text := "你好 plot "; //设置坐标系标题文本内容

axs.title.fontinfo.size := 15; //设置坐标系标题文本字体大小

axs.title.fontinfo.color := 0xff0000;//设置坐标系标题字体颜色

axs.x_label.text := "x fanli "; //设置坐标系x轴标题文本

axs.axises(0).tics_color := 0x00ff00; //设置坐标系x轴刻度线的颜色

axs.axises(0).fontinfo.size := 5; //设置坐标系x轴刻度字体大小

axs.axises(0).lineinfo.color := 0x0000ff; //设置坐标系x轴轴线颜色

axs.y_label.text := "Y轴范例"; //设置坐标系y轴标题文本

axs.axises(1).tics_color := 0x0000ff; //设置坐标系y轴刻度线的颜色

axs.axises(1).fontinfo.size := 8; //设置坐标系y轴刻度字体大小

axs.axises(1).lineinfo.color := 0x00ff00; //设置坐标系y轴轴线颜色

axs.grid(0).Width := 0; //设置坐标系纵向网格线不显示

axs.grid(0).color := 0x0ff0f0; //设置坐标系纵向网格线颜色

axs.grid(1).Width := 1; //设置坐标系横向网格线显示

axs.grid(1).color := 0x0ff0f0; //设置坐标系横向网格线颜色

//设置线型属性

line := new tg_Polyline(); //设置线图对象

//设置线类型为点虚线等同于line.lineinfo.color:=line.tgc_PS_DOT

line.lineinfo.style := 2;

line.lineinfo.color := 0x000000; //设置线图线条颜色

line.markinfo.bkcolor := 0x00ff00; //设置线图数据点标记背景填充颜色

line.markinfo.color := 0x0000ff; //设置线图数据点标记颜色

{

注释：如果需要使用Tg_const常量类中的常量属性，须调用对应对象的常量；如：line.tgc_on;

Line.mark_mode := "on"; 等同于line.mark_mode:=line.tgc_on; 设置线图点标记样式开启；

}

line.mark_mode := "on";

line.markinfo.size := 20; //设置线图点标记大小

{

设置线图点标记样式为三角形-顶角向下，等同于line.markinfo.style:=line.tgc_mks_triangle_down;

}

line.markinfo.style:= "triangle_down";

line.polyline_style := "bar"; //设置线图样式为柱状样式

line.bar_width := 20; //样式为柱状时，设置柱状宽度

//设置线图绘制数据

d := array();

idx := 0;

for i:= -pi() to 2*pi() step 0.2 do

begin

d[idx] := array(i,sin(i));

idx++;

end

line.graph_data := d;

line.parent := axs;

end

fg;

end


7.2.3 表面图范例

uses tslvcl,utvclgraphics;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

Caption := "surface";

fg := new tg_WinControl(self); //设置绘图展示窗口对象

fg.Caption := "hello1"; //设置窗口标题文本

fg.parent := self; //设置窗口父节点

fg.Align := alClient; //设置文本居中样式

//////////设置坐标轴属性////////////////////////

axs := new tg_axes(); //创建坐标系对象

// 旋转坐标轴

t := pi()*70/180;

a := pi()*60/180;

axs.set_trans(t,a);

axs.box := true; //设置坐标系对象有边框显示

axs.figure := fg.figure; //设置坐标系的坐标容器

axs.title.text := "你好 surface "; //设置坐标系标题文本内容

axs.title.fontinfo.size := 15; //设置坐标系标准文本字体大小

axs.title.fontinfo.color := 0xff0000; //设置坐标系标题文本字体颜色

axs.margins := array(0.05,0.15,0.1,0.1);//设置坐标系空白区域

axs.x_label.text := 'x轴'; //设置坐标系x轴标签文本

axs.axises(0).tics_color := 0x0000ff; //设置坐标系x轴刻度线颜色

axs.axises(0).fontinfo.size := 8; //设置坐标系x轴刻度值文本字体大小

axs.axises(0).lineinfo.color := 0x00ff00;//设置坐标系x轴刻度线轴线颜色

axs.y_label.text := 'y轴'; //设置坐标系y轴标签文本

axs.axises(1).tics_color := 0x0000ff; //设置坐标系y轴刻度线颜色

axs.axises(1).fontinfo.size := 8; //设置坐标系y轴刻度值文本字体大小

axs.axises(1).lineinfo.color := 0x00ff00;//设置坐标系y轴刻度线轴线颜色

axs.z_label.text := 'z轴'; //设置坐标系z轴标签文本

axs.axises(2).tics_color := 0x0000ff; //设置坐标系z轴刻度线颜色

axs.axises(2).fontinfo.size := 8; //设置坐标系z轴刻度值文本字体大小

axs.axises(2).lineinfo.color := 0x00ff00;//设置坐标系z轴刻度线颜色

sf := new tg_my_surf(); //创建自定义表面图类对象

sf.lineinfo.color := 0x0000ff; //设置表面图对象线条颜色

sf.lineinfo.style := sf.tgc_BS_SOLID; //设置表面图对象线条样式为线条

sf.graph_data := get_surf_data(); //设置表面图对象画图数据

sf.parent := axs; //设置表面图对象父节点为坐标系

return ;

end

fg;

function c_3(x,y);

begin

return X - 3*X*sin(X)*cos(Y-4) ;

end

function get_surf_data(); //设置表面图画图数据函数

begin

st1 := (12)/50;

vs1 := array(-10,st1)->2;

st2 := 10/50;

vs2 := array(-5,st2)->5;

d := array();

dlen := 0;

for i,vi in vs1 do

begin

for j,vj in vs2 do

begin

r := array();

x0 := vi;

y0 := vj;

x1 := vi+st1;

y1 := vj+st2;

v1 := array(x0,y0,c_3(x0,y0));

v2 := array(x1,y0,c_3(x1,y0));

v3 := array(x1,y1,c_3(x1,y1));

v4 := array(x0,y1,c_3(x0,y1));

d[dlen++] := array(v1,v2,v3,v4,v1);

end

end

return d;

end

end

type tg_my_surf = class(tg_graph) //绘图对象,包括数据,提示等内容

function create(pms);

begin

inherited;

lineinfo.bkcolor := 0x00f0f0;

end

function get_data_bounds();override;

begin

d := graph_data;

r := array((inf,-inf),(inf,-inf),(inf,-inf));

for i ,v in d do

begin

for j,vj in v do

begin

for k := 0 to 2 do

begin

r[k,0] := min(r[k,0],vj[k]);

r[k,1] := max(r[k,1],vj[k]);

end

end

end

for k := 0 to 2 do

begin

r[k,0] -= abs(r[k,0]*0.1);

r[k,1] += abs(r[k,1]*0.1);

end

return r;

end

function paint_legend(cvs,rec);virtual; //绘制图例

begin

end

function paint(cvs);override;

begin

d := graph_data;

cvs.axesclip(); //画布设置裁剪坐标系范围

set_lineinfo_to_canvas(cvs); //设置线条信息到画布对象中

dp := cvs.draw_polygon(); //填充折线绘制

bx := axes.zoom_box; //获取坐标系对象的视图范围

for i,v in d do

begin

ps := array();

flg := false;

zz := 0;

for j,vj in v do

begin

if vj[0]<bx[0,0] or vj[1]<bx[1,0] or vj[2]<bx[2,0] or vj[0]>bx[0,1] or vj[1]>bx[1,1] or vj[2]>bx[2,1] then

begin

flg := true;

break;

end

zoom_to_xyz(vj[0],vj[1],vj[2],_x,_y,_z);

zz := vj[2];

ps[j] := array(_x,_y);

end

if flg then continue;

if zz>0 then cvs.brush.color := 0x00ff00;

else

cvs.brush.color := 0xff0000;

dp.points(ps).requiregdi().draw();

end

cvs.axesunclip(); //设置画布对象取消裁剪

end

End


7.2.4 饼图范例

uses tslvcl,utvclgraphics;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

//该范例基本同图片保存范例一样都时使用的饼图绘制

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

caption := "pie";

width := 800;

Height := 800;

fg := new tg_WinControl(self);

fg.Caption := "hello1";

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.box := true;

axs.figure := fg.figure;

axs.title.text := "hello pie ";

axs.axises(1).tics_color := 0x0000ff;

axs.axises(1).fontinfo.size := 8;

axs.data_bounds(0) := array(-0.1,2.1);

axs.data_bounds(1) := array(-0.1,2.1);

axs.data_bounds(2) := array(-0.5,0.5);

args := array(

(pi()/4,pi()/3,0x0000ff),

(pi()/3,pi()/2,0x00ff00),

(pi()/2,pi()*3/2,0xff0000),

(pi()*3/2,pi()*9/4,0xff00ff)

);

prominentidx := 0; //凸显的块

prominentrate := 0.1; //凸显的块

for i,v in args do

begin

line := new tg_Polyline();

line.polyline_style := line.tgc_LS_filled;

line.closed := true;

c := (i=2)?1.1:1;

line.graph_data := 1+get_pie_lines(v[0],v[1],i=prominentidx,prominentrate);

line.lineinfo.bkcolor := v[2];

line.parent := axs;

end

end

function get_pie_lines(arg1,arg2,prominent,prominentrate);

begin

stp := pi()/180;

d := 1;

r := array();

r[0] := array(0,0);

idx := 1;

for i:= arg1+(prominent?stp:0) to arg2-(prominent?stp:0) step stp do

begin

r[idx++] := array(sin(i),cos(i));

end

r[idx] :=array(0,0);

if prominent then

begin

rx := r[integer(idx/2)]*prominentrate;

for i := 0 to idx do

begin

r[i]+=rx;

end

end

return r;

end

fg;

End


7.3 绘图库拓展类介绍


7.3.1 K线图tg_Polycandlestick

tg_Polycandlestick用于绘制证券市场的K线图。所谓K线图，就是将各种股票每日、每周、每月的开盘价、收盘价、最高价、最低价等涨跌变化状况,用图的方式表现出来。K线又称阴阳线、棒线、红黑线或蜡烛线，它起源于几个世纪前的日本，目前已成为股票技术分析中的重要方法。K线图绘制成连接开盘价和收盘价的竖立的矩形，从矩形两端上下延伸的竖线代表了最高价和最低价。

基础属性：

l bar_width：柱宽度；设置K线柱宽度；用于设置K线图柱宽度，赋值大于等于零的数字类型；设置柱宽度为20像素范例：line.bar_width:=20；

l Bullcolor：牛色，设置K线柱牛市(上涨)的颜色；设置K线柱的牛色为红色范例：line.bullcolor := 0x0000ff；

l Bearcolor：熊色，设置K线柱熊市(下跌)的颜色；设置K线柱的熊色为绿色范例：line.bearcolor := 0x00ff00；

K线图画图数据赋值说明：

赋值数据为集合类型，其中须包含日期、开盘价、现价（收盘价）、最高价和最低价；其中日期那列为日期字符串类型，其他价格为非负数字类型；

赋值范例：line.graph_data := array(('2017-10-24',11,10,13,7),("2017-10-25",8,12,12,5));


7.3.2 须盒图tg_polyboxplot

Tg_polyboxplot类用于绘制盒须图。箱形图（Box-plot）又称为盒须图、盒式图或箱线图，是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。在各种领域也经常被使用，常见于品质管理。它主要用于反映原始数据分布的特征，还可以进行多组数据分布特征的比较。箱线图的绘制方法是：先找出一组数据的上边缘、下边缘、中位数和两个四分位数；然后， 连接两个四分位数画出箱体；再将上边缘和下边缘与箱体相连接，中位数在箱体中间。

绘图主要数据由上边缘（既上限值）、下边缘（既下限值）、中位数Q3、两个四分位数(下四分位数Q1和上四分位数Q2)以及异常值组成；是由一个集合计算获取上面数据array(12,15,17,19,20,23,25,28,30,33,34,35,36,37)为例说明这六大因数来由：

l 下四分位数Q1：它等于该样本中所有数值由小到大排列后第25%的数字。确定四分位数的位置，Qi所在位置等于i(n+1)/4，其中i=1,2,3；n表示序列中包含的项数。根据位置，计算相应的四分位数（以上面聚合为例：Q1所在的位置=(14+1)/4=3.75，Q1=0.25*第三项+0.75*第四项，既0.25*17+0.75*19=18.5）。

l 中位数（第二个四分位数）Q2：它等于该样本中所有数值由小到大排序后第50%的数字。Q2所在位置=2*(14+1)/4=7.5，Q2=0.5*第七项+0.5*第八项，既0.5*25+0.5*28=26.5。

l 上四分位数Q3：它等于该样本中所有数值由小到大排列后第75%的数字，计算方法同下分位数。Q3所在的位置=3(14+1)/4=11.25，Q3=0.75*第十一项+0.25*第十二项，既0.75*34+0.25*35=34.25。

l 上边缘（上限值）：上限是非异常值范围内的最大值；这个首先需要知道四分位距如何计算的？四分位距（interquartile range，IQR，又称四分差）。四分位距IQR=Q3-Q1，那么上限值=Q3+1.5*IQR。

l 下边缘（下限值）：下限是非异常范围内的最小值；下限值=Q1-1.5*IQR。

l 异常值：在Q3+1.5*IQR 和Q1-1.5*IQR处画两条与中位线一样的线段，这两条线段为异常值截断点，称其为内限，在Q3+3*IQR和Q1-3*IQR处画两条线段，称其为外限。处于内限以外位置的点表示的数据都是异常值。其中在内限与外限之间的异常值为温和的异常值（mild outliers），在外限以外的为极端的异常值(extreme outliers)。

基础属性：

l Bar_width：柱宽度；用于设置盒须图柱宽度，赋值大于等于零的数字类型；设置柱宽度为20像素范例：line.bar_width:=20；

须盒图画图数据赋值说明：

赋值数据为集合类型，其中数据全为数字类型，然后通过这些数据计算画出须盒图，注意如果需要显示异常值信息时需要设置须盒图对象点标记信息的相关属性信息，详细说明见tg_mark_info类说明；

异常值开启显示设置范例：

line.mark_mode := true;

line.markinfo.Style := line.tgc_mks_star;

line.markinfo.size := 5;；

赋值范例：line.graph_data := array(array((850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960),

(960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800),

(880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840));


7.3.3 饼图tg_polypie

Tg_polypie类用于绘制饼图，其中饼图支持三种类型（饼图，环形图，玫瑰图）。

饼图（Pie Chart）是一种常见的数据可视化图形，用于展示各类别在总体中所占的比例。它通常用于统计学模块，通过将数据分成不同的扇形部分，每个扇形部分的大小表示数据的相对比例。

环形图（Ring Chart）又称之为甜甜圈图，是饼图的一种变体，是指将两个及以上的大小不一的饼图叠在，挖去中间部分构成的图形，本质是饼图将中间区域挖空。

玫瑰图（Nightingale Rose Chart）又名鸡冠花图（Coxcomb Chart）、极坐标区域图（Polar Area Diagram），是极坐标化的柱图，可以将其理解为披着饼图外皮的柱状图。

基础属性：

l color_map：颜色地图；设置饼图颜色地图，赋值颜色集合；对象建立时初始化已经赋值初始的颜色地图数据，如果用户需要自定义颜色地图数据就需要自己重新赋值；赋值范例为：line.color_map:=array(0x00CED1,0xFA8072,0x00BFFF,0xFFFFE0);

l pie_type：饼图类型；赋值字符串类型，取值枚举于(pie-饼，rase-玫瑰, ring-环形)三种类型；设置饼图类型为玫瑰图范例：line.pie_type := "rose"；

l show_text：显示饼图数据占比文本；赋值为布尔类型true|false,默认为true展示饼图数据占比文本；设置不展示饼图数据占比文本范例：line.show_text := false；

饼图画图数据赋值说明：

赋值数据为集合类型，数据中包含饼图区域名称（name）和饼图区域数值（value），赋值时集合中索引时严格区分大小写且必须一致，其中名称为字符串类型，数值为非负数字类型；

赋值范例：line.graph_data := array(('name':'a区','value':300)

,('name':'b区','value':200)

,('name':'c区','value':500)

,('name':'d区','value':700)

,('name':'e区','value':300));


7.3.4 雷达图tg_polydar

Tg_Polyradar用于绘制雷达图。雷达图（Radar Chart）是一种可视化图标，也被称为蛛网图、星形图或极坐标图。它以一个中心点为起点，从中心点向外延伸出多条射线，每条射线代表一个特定的变量或指标。每条射线上的点或线段表示该变量在不同维度上的取值或得分。雷达图常用于比较多个变量在不同维度上的表现，以及展示各个变量之间的相对关系。每个变量在雷达图上的表现可以通过长度、角度、面积等方式进行表示。通过观察雷达图的形状和变化，可以直观地了解各个变量地相对重要性、差异程度和趋势。雷达图的主要构成要素：中心点（所有射线的起点）、射线（从中心点向外延伸的线段）、轴标签（每条射线上的轴标签表示对应变量或指标名称或取值范围）、数据点或线段（数据点或线段表示每个变量在不同维度上的取值或得分）、数据区域（数据区域是由数据点或线段连接而成的区域，代表了各个变量在不同维度上的表现）、标题和图例（雷达图通常包含一个标题，用于描述图表的主题或目的）和刻度线和标签（刻度线和标签用于标记每条射线上的数值或得分）。雷达图常应用于企业经营状况（收益性、生产性、流动性、安全性和成长性的评价）。

基础属性：

l color_map：颜色地图；设置雷达图颜色地图，赋值颜色集合；对象建立时初始化已经赋值初始的颜色地图数据，如果用户需要自定义颜色地图数据就需要自己重新赋值；赋值范例为：line.color_map:=array(0x00CED1,0xFA8072,0x00BFFF,0xFFFFE0,0xF0FFFF);

l Indicator：指标轴,设置雷达图指标轴相关数据,赋值为数组对象，格式为array(’name’:值,’max’:值)；需注意集合中索引是严格区分大小写且必须一致，比如设置雷达图中语数外三科成绩指标范例：line.indicator:=array((’name’:’语文’,’max’:150),(’name’:’数学’,’max’:150),(’name’:’英语’,’max’:120));

雷达图画图赋值说明：

赋值数据为集合类型，其中数据有对照变量名（name）和该变量对应的各个维度数值（value），两个关键字赋值时须注意严格区分大小写且必须一致，其中对照变量名为字符串类型，数值为非负数字类型的集合；

参考上面Indicator赋值的指标范例后，赋值范例：

line.graph_data:=array(

('name':'一班','value':array(90, 110, 85)),

('name':'二班','value':array(85,100, 70)),

('name':'三班','value':array(70, 90, 80))

);


7.3.5 树形图tg_Polytree

Tg_polytree用于绘制树结构图形。树图是一种利用包含关系表达层次化数据的可视化方法。它通过将事物或现象分解成树枝状结构，展示其构成或内在逻辑关系。树图通常用于将主要类别逐渐分解成越来越详细的层次，从而帮助思维从一般到具体的逐步转化。树图在多个领域中得到了广泛应用，包括科学、社会学、工程和商业等。它可以用于新产品研制过程中设计质量的展开、制订质量保证计划、明确部门职能、管理职能，以及解决企业有关质量、成本、交货期等问题的创意展开。

基础属性：

l Node_space_x：设置节点柱状宽度，赋值为大于零的数字类型；设置树节点间隔距离为100像素范例：line.node_space_x := 100;

l Show_text：是否显示节点文本，赋值为布尔类型true|false,默认为true展示节点文本；设置不展示节点信息数据范例：line.show_text := false；

树形图画图数据赋值说明：

赋值类型为集合类型，集合赋值格式为节点名称（name）、节点是否显示（show）和子节点信息（children），其中节点名称为字符串类型，节点是否显示为布尔类型，且赋值时关键字严格区分大小写且必须一致，而子节点信息则为集合（包含上述三个数据，节点名称、节点是否显示和子节点信息），其中节点是否显示为可选属性，不赋值时默认为显示节点，还有当前节点没有子节点时，可以不用赋值子节点信息；额外注意树形图赋值只能有一个根节点，多余根节点都不生效；

赋值范例：

line.graph_data := array(

//下面设置该树形图根节点，一个画图只有一个根节点赋值能生效（第一个）

'name':'aaa', 'show':true, 'children':(

('name':'abb', 'children':(

//show设置为false时，表示该节点在图中不显示出来

('name':'aba','show': false, 'children':()),

('name':'abc')

)),

//当该节点没有子节点时，可以不用给children数据信息

('name':'acc')

),

// 设置第二个根节点时，程序不会报错，但是也不会生效生成第二个树形图

// 'name':'bbb', 'children':(('name':'baa'),('name':'bcc'))

);；


7.3.6 旭日图tg_Polysunburst

Tg_polysunbust用于绘制旭日图。旭日图通过不同的环形区域和扇形区域来表示数据的层次和大小关系，从而形成一个太阳形状，因此得名。旭日图中每个级别的数据通过一个圆环表示，离原点越近代表圆环级别越高，最内层的圆表示层次结构的顶级，然后一层一层去看数据占比情况。越往外级别越低且分类越细。因此它既能像饼图一样表示局部和整体的占比，又能像矩形图一样表现层级关系，旭日图可以等同于n张饼图，但是饼图只能体现一层数据的比例情况，而旭日图不仅可以体现数据比例，还能体现数据层级之间的关系；它超越了传统饼图和环图，适合用于展示不同层级的数据。

基础属性：

l color_map：颜色地图；设置旭日图颜色地图，赋值颜色集合，对象建立时初始化已经赋值初始的颜色地图数据，如果用户需要自定义颜色地图数据就需要自己重新赋值；赋值范例为：line.color_map:=array(0x00CED1,0xFA8072,0x00BFFF,0xFFFFE0,0xF0FFFF,0xFDF5E6,0xFAF0E6);

l show_text：显示旭日图区块文本；赋值为布尔类型true|false,默认为true显示旭日图区块文本；设置不展示旭日图区块文本信息范例：line.show_text := false；

旭日图图形赋值说明：

赋值类型为集合类型，集合赋值包含层次对应名字（name）、层次区域样式（itemstyle）、层次对应数值（value）和子层次信息（children）；其中层次对应名称为字符串类型，层次区域样式为集合类型，暂时主要用于赋值饼图区域颜色样式，这个属性不赋值时默认取颜色地图color_map中第一个颜色，层次对应数值为大于零数值类型，父层次不赋值时会由子层级按数值填充，子层次信息赋值集合类型（name、itemsty、value、children），注意赋值时关键字严格区分大小写且必须一致。

赋值范例：

Line.graph_data := array(

'name': '学科',

'children':(

('name':'基础学科', 'itemstyle':('color':0x0000ff), 'children':(

('name': '语文', 'value': 1),

('name': '数学', 'value': 1),

('name': '英语', 'value': 1)

)),

('name':'理科', 'itemstyle':('color':0x00ff00), 'children':(

('name': '物理', 'value': 1.2),

('name': '化学', 'value': 1),

('name': '生物', 'value': 0.8)

)),

('name':'文科', 'itemstyle':('color':0xff0000), 'children':(

('name': '政治', 'value': 1),

('name': '历史', 'value': 1),

('name': '地理', 'value': 1)

))

)

);


7.4 绘图库拓展类使用范例


7.4.1 K线图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

Caption := "k线图";

fg := new tg_WinControl(self);

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.figure := fg.figure;

axs.title.text := "k线图 ";

axs.title.fontinfo.size := 15;

axs.title.fontinfo.color := 0xff0000;

axs.x_label.text := "日期";

axs.grid(0).Width := 0;

axs.grid(0).color := 0x0ff0f0;

axs.auto_ticks(0) := false;

//设置线型属性

line := new tg_Polycandlestick();

line.lineinfo.color := 0xff0000;

line.bullcolor := 0x0000ff; //设置牛色为红色

line.bearcolor := 0x00ff00; //设置熊色为绿色

line.graph_data:= array(("2017-10-24",1.1,1,1.3,0.3),("2017-10-25",3,4,4.5,2.5),("2017-10-26",5,8,9,3),("2017-10-27",10,8,9,3),("2017-10-28",5,8,9,8.5),("2017-10-29",5,8,9,3),("2017-10-30",5,8,9,3),("2017-10-31",5,8,9,3),("2017-11-01",5,8,9,3));

line.parent := axs;

end

fg;

End


7.4.2 须盒图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

Caption := "盒须图";

fg := new tg_WinControl(self);

fg.Caption := "盒须图";

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.figure := fg.figure;

axs.title.text := "盒须图";

axs.title.fontinfo.size := 15;

axs.title.fontinfo.color := 0xff0000;

axs.axises(1).tics_color := 0x0000ff;

axs.axises(1).fontinfo.size := 8;

axs.axises(1).lineinfo.color := 0x00ff00;

axs.grid(1).Width := 2;

axs.grid(1).color := 0x0ff0f0;

line := new tg_Polyboxplot();

line.lineinfo.color := 0xff0000;

line.graph_data := array((850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960),

(960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800),

(880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840),

(890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780),

(890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870)

);

line.parent := axs;

end

fg;

End


7.4.3 饼图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm=class(tvcform)

function create(aowner);

begin

inherited;

caption := "玫瑰图";

width := 800;

Height := 800;

fg := new tg_WinControl(self);

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.figure := fg.figure;

axs.title.text := "玫瑰图";

// 赋值绘制玫瑰图数据

args := array(('name':'a','value':300)

,('name':'b','value':200)

,('name':'c','value':500)

,('name':'d','value':700)

,('name':'e','value':300)

,('name':'f','value':200)

,('name':'g','value':500)

,('name':'h','value':700)

,('name':'i','value':300)

,('name':'j','value':200)

,('name':'k','value':500)

,('name':'l','value':700)

);

line := new tg_Polypie(); //创建饼图对象

line.graph_data := args;

line.pie_type := "rose"; //设置饼图类型为玫瑰图类型

line.parent := axs;

//绘制图例

lg := new tg_legend(); //创建图例对象

lg.parent := axs;

lg.location := lg.tgc_by_axes;

lg.links := array(line);

end

fg;

End


7.4.4 雷达图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

caption := "雷达图";

width := 800;

Height := 800;

fg := new tg_WinControl(self);

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.box := true;

axs.figure := fg.figure;

axs.title.text := "雷达图";

line := new tg_Polyradar();

//赋值指标轴数据

indicator := array(

('name':'射击','max':110),

('name':'游泳','max':110),

('name':'篮球','max':110),

('name':'足球','max':110),

('name':'跑步','max':110),

('name':'举重','max':110)

);

//赋值雷达图画图数据

args := array(

('name':'一班','value':array(90, 80, 85, 85, 95, 95)),

('name':'二班','value':array(85, 65, 65, 90, 100, 70)),

('name':'三班','value':array(70, 60, 99, 50, 90, 80))

);

line.graph_data := args;

line.indicator := indicator;

line.parent := axs;

//设置图例属性

lg := new tg_legend();

lg.parent := axs;

//设置图例位置

lg.postion := array(-0.11,0.7);

lg.links := array(line);

end

fg;

End


7.4.5 树形图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

Caption := "树图";

fg := new tg_WinControl(self);

fg.Caption := "树图";

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.figure := fg.figure;

axs.title.text := "树图";

//设置属性图属性

line := new tg_Polytree();

line.parent := axs;

line.lineinfo.color := 0x0000ff;

line.markinfo.bkcolor := 0x00ff00;

line.markinfo.color := 0x0000ff;

line.mark_mode := true; //设置显示节点

line.markinfo.size := 5; //设置节点大小

line.node_space_x := 100; //设置节点间隔宽度

line.show_text := false; //设置不展示节点文本

line.graph_data := array('name':'111','show': true,'children':(

('name':'222','children':(('name':'333','children':()))), ('name':'555','children':()),

('name':'666','show': false,'children':()))

);

end

fg;

End


7.4.6 旭日图范例

uses tslvcl,utvclgraphics,utvclgraphicsext;

app := initializeapplication();

app.createform(class(tfm),fm);

fm.show();

app.run();

type tfm = class(tvcform)

function create(aowner);

begin

inherited;

caption := '旭日图';

width := 800;

Height := 800;

fg := new tg_WinControl(self);

fg.parent := self;

fg.Align := alClient;

//////////设置坐标轴属性////////////////////////

axs := new tg_axes();

axs.box := true;

axs.figure := fg.figure;

axs.title.text :="旭日图";

//设置旭日图绘图数据，注意集合索引必须一致，而且区分大小写

args := array(

'name': '组织',

'children': (

(

'name': '总经理办公室',

'children': (

(

'name': '财务部',

"itemstyle":("color":0xff00ff),

'value': 15,

'children': (

('name': '会计', 'value': 2),

(

'name': '财务主管',

'value': 5,

'children': (

('name': '财务专员', 'value': 2)

)

),

('name': '财务助理', 'value': 4)

)

),

('name': '市场部', 'children': (('name': '市场经理', 'value': 4))),

(

'name': '人力资源部',

'value': 10,

'children': (

('name': '人事经理', 'value': 5, 'itemstyle': ('color':90)),

('name': '招聘专员', 'value': 1)

)

)

)

),

(

'name': '技术部',

'children': (

(

'name': '研发部',

'children': (

('name': '项目经理', 'value': 3),

(

'name': '开发工程师',

'value': 4,

'children': (('name': '实习生', 'value': 2))

)

)

)

)

),

(

'name': '销售部',

'children': (

(

'name': '销售经理',

'children': (

('name': '销售代表', 'value': 1),

('name': '销售助理', 'value': 2)

)

)

)

)

)

);

line := new tg_Polysunburst();

line.graph_data := args;

line.parent := axs;

end

fg;

end