vst实例(2) 创建VST

这篇具有很好参考价值的文章主要介绍了vst实例(2) 创建VST。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前面我们知道,创建一个虚拟树,应该首先告知VST节点数据的大小(即nodedatasize),其实在创建树结构时,这一点并不是必须的,而是如果你需要让VST的每一个节点能指向一定的数据,从而在执行树的操作时,能用到这些数据,那么你最适合的方法是定义一个结构类型(record),然后让node.data指向这个record。

实际上,我们也可以不使用node的data属性,而使用node.index或level属性来指向数据(例如指向数组的数据),VST提供的原始例子程序minima就是这样的。但是,如果不适用指针指向数据的话,完全体现不出VST的优势,而且排序、图标、定制绘制单元格等等都将难以实现。

严格来说,创建VST只需要做三步:

(1)告知VST根节点的数量(rootnodecount)。

(2)告知VST子孙节点的数量(chilenodecount)。

(3)告知VST的单元格显示文本(CELLTEXT)。

如果需要让VST的node指针指向某些数据的话,可以在第三条前告诉NODE的数据指针。

一、创建

1、设置根节点数

我们的程序目标是创建一个二级树,所以创建VST就是告知根节点的数量以及每一个节点的子节点的数量,因此我们创建VST节点的第一步就是在适当的位置告诉程序rootnodecount的数量。

创建树的根节点的过程,我们通过写一个过程(procedure)来实现:

procedure TForm2.createvst;
begin
   QRY1.Open('select * from codes where site_code in '+
             '(select distinct fir_code from codes where single_runway_ad>-1 )'+
             ' and single_runway_ad=-1');
   //firedac默认初始只读取50行数据,此函数强制让QRY1完全读取table数据
   //如果不执行此行,则recordcount将最大只有50;
   QRY1.FetchAll;
   //设置根节点数为有机场的情报区数,因为根节点指向的是情报区。
   vst.RootNodeCount:=qry1.RecordCount;
   QRY1.Close;
end;

2、初始化节点

在设置根节点数后,程序接下来的操作是触发事件oninitnode,因此我们为oninitnode写代码如下:

procedure TForm2.vstInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
 //GetNodeLevel函数用于返回当前节点所在的层级,从0开始,根节点的level是0
 case Sender.GetNodeLevel(node) of
   0:
   begin
     //设置根节点的节点高度为36;
     Sender.NodeHeight[node]:=36;
     //根节点的节点选框类型为ctTriStateCheckBox
     sender.CheckType[node]:=ctTriStateCheckBox;
     Sender.CheckState[node]:=TCheckState(1);
     if QRY1.Active then//当QRY1处于关闭状态时,下面的读取数据过程可能会产生错误
     // GetNodeData将取出节点指向的数据
     //下面的代码将填充数据
     with pcodes(Sender.GetNodeData(node))^ do
     begin
       icao:=QRY1.FieldByName('site_code').AsString;
       names:=QRY1.FieldByName('name_loc').AsString;
       CODETYPE:='FIR';
       //在这里告诉VST,这个节点需要有子节点
       //这行语句将触发事件oninitchildren
       Sender.HasChildren[node]:=True;
       //每增加一个节点会触发一次oninitnode,
       //因此如果不降qry1指向的数据往下移的话,所有根节点的数据将是完全一样的。
       QRY1.Next;
      end;
   end;
   1:
   begin
     //设置子节点的nodeheight=32,比根节点略低。
     sender.NodeHeight[Node]:=32;
     //子节点的节点选框类型为ctCheckBox
     sender.CheckType[node]:=ctCheckBox;
     //在添加每一个子节点的时候也会触发一次oninitnode事件,下面的代码是为子节点填充数据
     if not QRY2.Active then Exit;  //这行语句也是为防错处理
     with pcodes(Sender.GetNodeData(node))^ do
     begin
       icao:=QRY2.FieldByName('site_code').AsString;
       names:=QRY2.FieldByName('name_loc').AsString;
       IATA:=QRY2.FieldByName('py_code').AsString;
       if QRY2.FieldByName('single_runway_ad').AsString.Trim='0' then
         rwy_style:='多跑道'
       else
         rwy_style:='单跑道';

       if QRY2.FieldByName('main_alt_ad').AsString.Trim='0' then
         apt_type:='备用'
       else
         apt_type:='主用';
       CODETYPE:='AIRPORT';
       QRY2.Next;
     end;
   end;
 end;
end;

3、设置子节点数

在设置rootnodecount时,会调用根节点数量次数的oninitnode事件,而在设置根节点数据时,我们有一行语句:Sender.HasChildren[node]:=True,每次遇到这个语句,程序会触发oninitchildren事件,我们在oninitchildren事件中打开QRY2,并设置子节点数。代码如下:

procedure TForm2.vstInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
  var ChildCount: Cardinal);
begin
  with pcodes(Sender.GetNodeData(node))^ do
  begin
    QRY2.open('select * from codes where fir_code=:FIR and single_runway_ad<>-1',[icao]);
    QRY2.FetchAll;
  end;
  ChildCount:=QRY2.RecordCount;
end;

事实上,我们在oninitchildren事件中给VST赋予子节点的数量时,每个子节点的创建时也会调用一次oninitnode事件。

在执行oninitnode事件时,我们除了赋值外,通常设置节点状态、选择框类型等等也在这里实现。

综合上面的语句,我们可以得出VST的基础创建逻辑是:

告诉VST节点数(无论是根节点还是子节点)→每一个节点调用一次oninitnode事件。

4、另一种创建树结构的方法

实际上,我们可以重写上面的代码如下:

VAR  ND:PVIRTUALNODE;
……
QRY1.First;
   while not QRY1.Eof do
   begin
     nd:=vst.AddChild(nil);
     with pcodes(vst.GetNodeData(nd))^ do
     begin
       //根节点的获取数据语句
       qry2.Open('相关的SQL语句');
       while not QRY2.Eof do
       begin
         with pcodes(vst.GetNodeData(vst.AddChild(nd)))^ do
         begin
           //获取机场数据的语句
         end;
         QRY2.Next;
       end;
     end;
     QRY1.Next;
   end;

上面的语句中我们使用了添加节点的函数:

function AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode;

功能是为父节点创建最后一个子节点,如果parent为nil,则创建根节点。Userdata通常可以省略。

需要注意的是,如果使用上面的语句,则需要取消oninitchildren事件的代码,并且如果在上面的语句中进行了赋值,还应该取消oninitnode事件中的相应设置。

那么,是不是觉得上面的语句更简单,逻辑更清晰呢?从逻辑上来讲确实如此,但是,从效率上来讲,使用addchild语句来创建和添加节点,则程序的执行效率会低很多,因为addchild语句的实际执行效果是:如果parent=nil,则执行的是rootnodecount:=rootnodecount+1;如果parent非空,则执行的是childcount:= ChildCount+1.

当然如果只是如此,效率并不会低多少,实际上,按照我们的原始的设定,则是一次性的获得数据后,在一次性的绘制VST,并显示VST,而addchild语句则是每次执行addchild后,直接执行全过程,最终的执行效率会低许多,机器较慢的情况下,甚至可能在数据量大的情况下出现抖动。

5、设置celltext

好了,言归正传,让我们继续创建VST。

我们创建VST实际上只剩下最后一项工作了——告诉每行每列应该显示什么数据,则需要在ongettext事件中写代码,此程序的代码如下:

procedure TForm2.vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
begin
  with pcodes(Sender.GetNodeData(node))^ do
  begin
    case Column of
      0:CellText:=icao;
      1:CellText:=iata;
      2:CellText:=CODETYPE;
      3:CellText:=names;
      4:CellText:=rwy_style;
      5:CellText:=apt_type;
    end;
  end;
end;

至此,创建VST完成,先欣赏下我们的执行结果吧。

vst实例(2) 创建VST

 文章来源地址https://www.toymoban.com/news/detail-463245.html

到了这里,关于vst实例(2) 创建VST的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 01、创建型-单例模式--只有一个实例

      单例模式是设计模式中最简单但又最常用的的设计模式之一,是很多人学的第一个设计模式。引用百度百科的定义:单例模式创建的类在当前进程中,保证一个类只会被实例化一次,并提供了全局访问点,使用的时候通过单例提供的方法来获取实例。在确保线程安全的前

    2024年04月27日
    浏览(36)
  • OpenStack云计算(十)——OpenStack虚拟机实例管理,增加一个计算节点并进行实例冷迁移,增加一个计算节点的步骤,实例冷迁移的操作方法

    本实训任务对实验环境要求较高,而且过程比较复杂,涉及的步骤非常多,有一定难度,可根据需要选做。可以考虑改为直接观看相关的微课视频 增加一个计算节点并进行实例冷迁移 熟悉增加一个计算节点的步骤。 熟悉实例冷迁移的操作方法。 (1)复习使用Packstack安装器

    2024年04月28日
    浏览(46)
  • Docker快速创建一个单机版的Jenkins实例

     目录 一、创建 Jenkins 实例 二、Pipeline 项目 三、总结 谈到 CI/CD,那便少不了这里面的佼佼者 Jenkins,正如 Jenkins 官网说的一样:“Build great things at any scale”,构建伟大,无所不能! 话不多说, 该篇文章将会带你使用 Docker 快速创建一个单机版的 Jenkins 实例以及创建一个简单

    2024年02月05日
    浏览(44)
  • Azure创建第一个虚拟机

    首先,登录到 Azure 门户 (https://portal.azure.com/)。 在 Azure 门户右上角,点击“虚拟机”按钮,并点击创建,创建Azure虚拟机。 在虚拟机创建页面中,选择所需的基本配置,包括虚拟机名称、操作系统类型和版本、虚拟机大小、管理员用户名和密码等。 名词和概念: 虚拟机名称

    2024年02月13日
    浏览(41)
  • 简介:在这篇教程中,我们将使用React.js框架创建一个简单的聊天机器人的前端界面,并利用Dialogflo

    作者:禅与计算机程序设计艺术 介绍及动机 聊天机器人(Chatbot)一直是互联网领域中的热门话题。而很多聊天机器人的功能都依赖于人工智能(AI)技术。越来越多的企业希望拥有自己的聊天机器人系统,从而提升自己的竞争力。为此,业界也出现了很多基于开源技术或云

    2024年02月06日
    浏览(59)
  • Centos创建一个Python虚拟环境

      在 CentOS 上创建一个 Python 虚拟环境,可以使用 virtualenv 工具。以下是创建和激活虚拟环境的基本步骤:   如果还没有安装 virtualenv,可以使用以下命令安装:   请注意,这里假设使用的是 Python 3。如果使用的是 Python 2,请使用 python-virtualenv 而不是 python3-virtualenv 。

    2024年01月20日
    浏览(44)
  • 在VMware中如何创建一个虚拟机

    在VMware中创建虚拟机之前要先安装VMware和下载一个镜像,没有安装和下载的可以点击下面链接有详细的教学 VMware下载及安装(附带下载地址) centos所有版本下载地址 下载 和安装好了我们就开始接下来的步骤啦 打开安装好的VMware软件,最好使用管理员身份运行防止后面读取

    2024年02月07日
    浏览(45)
  • 使用Pycharm为项目创建一个虚拟环境

    前言:        虚拟环境主要是用于为特定项目创建一个独有的解释器环境,安装项目所需三方包指定版本,防止全局解释器中的包版本项目不兼容。         Pycharm版本:2023.1 一、创建虚拟环境 1.在项目目录下创建一个文件夹  2.点击Pycharm右下角的添加本地解释器 3.在位

    2024年02月15日
    浏览(38)
  • anaconda创建一个新的虚拟环境

    1、打开anaconda prompt 2、输入命令创建新的环境: python版本可以自行更改 记得写y进行下一步 3、激活环境: 4、退出环境: 5、再次输入conda env list命令就可以检查虚拟环境是否创建成功。 到此这篇关于anaconda创建一个新的虚拟环境的详细操作指南的文章就介绍到这了,希望各

    2024年02月13日
    浏览(42)
  • axios全局封装取消请求,你可以创建一个 Axios 实例,并为该实例配置默认的 CancelToken

    可以在你的应用中使用这个封装过的 Axios 实例,并通过调用 instance.cancelAll() 方法来取消所有未完成的请求。

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包