(8)uniGUI for C++ builder下UniTreeView控件如何使用?
(同一个世界,同一个梦想,交流学习C++Builder XE10,传承c++builder的魅力!欢迎各地朋友加入我的QQ群484979943,进群密码“BCB”,同时也请将该群号广为宣传,希望能够广集各方高手,共同进步。)
说明:
1、uniGUI的安装请参考《 (1)uniGUI for C++ builder网站开发之uniGUI控件安装和你好世界》
http://blog.****.net/dlboy2018/article/details/79263520
2、项目创建配置请参考《(2)uniGUI for C++ builder网站开发之ORACLE数据库访问与操作》http://blog.****.net/dlboy2018/article/details/79329047
3、TreeView控件在VCL和uniGUI下的编程有一些区别,VCL下有Add、AddChild、AddChildFirst、AddChildObject、AddChildObjectFirst、AddFirst、AddNode、AddObject、AddObjectFirst添加节点的功能函数,但是在UniGui下只有Add、AddChild、AddChildObject、AddNode四个添加节点的函数.
UniTreeView控件主要常用于软件项目的功能菜单,本例通过开发一个列举不同电影公司的电影资讯为例,详细说明如何联动数据库,创建二级树节点和数据结构。实现目标如下图所示:
一、创建数据源
本例使用oracle数据库,创建两个表,corp_info表存储电影公司信息,film_info表存储电影信息。
1、corp_info表
ALTER TABLE SYSTEM.CORP_INFO
DROP PRIMARY KEY CASCADE;
DROP TABLE SYSTEM.CORP_INFO CASCADE CONSTRAINTS;
CREATE TABLE SYSTEM.CORP_INFO
(
CORP_NO VARCHAR2(10 BYTE),
CORP_NAME VARCHAR2(30 BYTE)
)
TABLESPACE SYSTEM
RESULT_CACHE (MODE DEFAULT)
PCTUSED 40
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX SYSTEM.CORP_INFO_PK ON SYSTEM.CORP_INFO
(CORP_NO)
LOGGING
TABLESPACE SYSTEM
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE SYSTEM.CORP_INFO ADD (
CONSTRAINT CORP_INFO_PK
PRIMARY KEY
(CORP_NO)
USING INDEX SYSTEM.CORP_INFO_PK
ENABLE VALIDATE);
2、film_info表
ALTER TABLE SYSTEM.FILM_INFO
DROP PRIMARY KEY CASCADE;
DROP TABLE SYSTEM.FILM_INFO CASCADE CONSTRAINTS;
CREATE TABLE SYSTEM.FILM_INFO
(
FILM_NO VARCHAR2(10 BYTE),
FILM_NAME VARCHAR2(30 BYTE),
CORP_NO VARCHAR2(10 BYTE),
CORP_NAME VARCHAR2(30 BYTE)
)
TABLESPACE SYSTEM
RESULT_CACHE (MODE DEFAULT)
PCTUSED 40
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX SYSTEM.FILM_INFO_PK ON SYSTEM.FILM_INFO
(CORP_NO, FILM_NO)
LOGGING
TABLESPACE SYSTEM
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE SYSTEM.FILM_INFO ADD (
CONSTRAINT FILM_INFO_PK
PRIMARY KEY
(CORP_NO, FILM_NO)
USING INDEX SYSTEM.FILM_INFO_PK
ENABLE VALIDATE);
二、创建项目
File->New->Other
请参考开头说明的两篇博客添加Include Path 和Library Path,取消Link with Dynamic RTL和Link with runtime packages。
三、功能实现
1、在MainModule窗口添加数据库访问控件UniConnection1和数据库驱动控件OracleUniProvider1
UniConnection1的ProviderName选择oracle,loginPrompt选择false
MainModule.h文件中定义public变量
//---------------------------------------------------------------------------
#ifndef MainModuleH
#define MainModuleH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <UniGUIMainModule.hpp>
#include "DBAccess.hpp"
#include "OracleUniProvider.hpp"
#include "Uni.hpp"
#include "UniProvider.hpp"
#include <Data.DB.hpp>
//---------------------------------------------------------------------------
class TUniMainModule : public TUniGUIMainModule
{
__published: // IDE-managed Components
TUniConnection *UniConnection1;
TOracleUniProvider *OracleUniProvider1;
void __fastcall UniGUIMainModuleCreate(TObject *Sender);
private: // User declarations
public: // User declarations
AnsiString dbIp;
AnsiString dbSid;
AnsiString dbUser;
AnsiString dbPass;
AnsiString dbPort,mySql,rowId;
__fastcall TUniMainModule(TComponent* Owner, TComponent* AUniApplication);
};
//---------------------------------------------------------------------------
TUniMainModule *UniMainModule(void);
//---------------------------------------------------------------------------
#endif
在MainModule的OnCreate事件中添加链接数据库代码
//---------------------------------------------------------------------------
void __fastcall TUniMainModule::UniGUIMainModuleCreate(TObject *Sender)
{
////连接数据库
dbIp="192.168.1.88";
dbPort="1521";
dbUser="system";
dbPass="oracle";
dbSid="ORCL";
UniConnection1->Disconnect();
UniConnection1->ProviderName="Oracle";
UniConnection1->SpecificOptions->Add("direct=true");
//UniConnection1->SpecificOptions->Add("Charset=ZHS16GBK");
UniConnection1->Username=dbUser;
UniConnection1->Password=dbPass;
UniConnection1->Server=dbIp+":"+dbPort+":"+dbSid;
try
{
UniConnection1->Connect();
}
catch(...)
{
Uniguidialogs::ShowMessage("连接数据库["+dbIp+"]失败!");
}
}
//---------------------------------------------------------------------------
2、MainForm窗口如下图摆放控件
添加一个UniTreeView控件、三个UniLabel控件、三个UniEdit控件、一个UniButton控件、两个UniQuery控件。
UniQuery1、UniQuery2的Connection属性设置为UniMainModule.UniConnection1
UniTreeView1控件的AutoExpand属性设置为true
在Main.cpp开头定义树节点数据的数据结构
//---------------------------------------------------------------------------
#include <vcl.h>
#include <uniGUIVars.hpp>
#pragma hdrstop
AnsiString sNodeText,pNodeText;
typedef struct MyRec
{
AnsiString nodeNo;//节点数据:编号
AnsiString nodeName;//节点数据:名称
} TMyRec;
typedef TMyRec* PMyRec;
PMyRec MyRecPtr;
#include "Main.h"
#include "MainModule.h"
//---------------------------------------------------------------------------
在UniTreeView1控件的OnClick事件中添加如下代码,实现单击树节点获取节点数据
void __fastcall TMainForm::UniTreeView1Click(TObject *Sender)
{
MyRecPtr = new TMyRec;
TUniTreeNode *pos;
if(UniTreeView1->Selected->Level>=0)
{
pos=UniTreeView1->Selected;
UniEdit1->Text=PMyRec(pos->Data)->nodeNo;//显示节点对应的数据nodeNo
UniEdit2->Text=PMyRec(pos->Data)->nodeName;//显示节点对应的数据nodeName;
}
//
if(UniTreeView1->Selected->Level==2 )
{
//显示节点层级关系
UniEdit3->Text=UniTreeView1->Selected->Parent->Text
+"->"
+UniTreeView1->Selected->Text;
}
else
{
UniEdit3->Text="";
}
}
UniButton1按钮用来加载树结构,在其OnClick事件中添加如下代码(该代码也可以添加在MainForm的OnShow事件中):
void __fastcall TMainForm::UniButton1Click(TObject *Sender)
{
////创建功能菜单
//创建根
MyRecPtr = new TMyRec;
UniTreeView1->Items->Clear();
MyRecPtr->nodeNo="00";
MyRecPtr->nodeName="我的影讯";
TUniTreeNode *pos=UniTreeView1->Items->AddChildObject(NULL, "我的影讯" ,MyRecPtr);
//组建根目录下第一层节点
UniQuery1->Close();
UniQuery1->SQL->Clear();
UniQuery1->SQL->Add("select * from corp_info order by corp_no");
UniQuery1->Open();
while(!UniQuery1->Eof)
{
MyRecPtr = new TMyRec; //创建一个节点数据存储变量
MyRecPtr->nodeNo=UniQuery1->FieldByName("corp_no")->AsString;//存储节点对应的数据:编号
MyRecPtr->nodeName=UniQuery1->FieldByName("corp_name")->AsString;//存储节点对应的数据:名称
pos=UniTreeView1->Items->AddChildObject(pos,UniQuery1->FieldByName("corp_name")->AsString,MyRecPtr);
UniQuery2->Close();
UniQuery2->SQL->Clear();
UniQuery2->SQL->Add("select * from film_info where corp_no=:w1 ");
UniQuery2->ParamByName("w1")->Value=UniQuery1->FieldByName("corp_no")->AsInteger;
UniQuery2->Open();
while(!UniQuery2->Eof)
{
MyRecPtr = new TMyRec; //创建一个节点数据存储变量
MyRecPtr->nodeNo=UniQuery2->FieldByName("film_no")->AsString;//存储节点对应的数据:编号
MyRecPtr->nodeName=UniQuery2->FieldByName("film_name")->AsString;//存储节点对应的数据:名称
pos=UniTreeView1->Items->AddChildObject(pos,UniQuery2->FieldByName("film_name")->AsString,MyRecPtr);
pos=pos->Parent;//指向父节点
UniQuery2->Next();
}
pos=pos->Parent;//指向父节点
UniQuery1->Next();
}
pos->Expand(true);//节点展开,不管用
}
至此,一个基于ORACLE表数据,动态创建树结构,并在树节点单击事件中获取节点内容和节点数据的案例就圆满实现了。在IE浏览器中输入http://127.0.0.1:8077就可以观看效果了。
源代码下载:http://download.****.net/download/dlboy2018/10268509
20180903追加:上例子通过点击一个按钮来实现树结构的创建与展现,实际应用中如果你想自动创建树结构并且自动展现,可以把树创建代码添加到Form窗口的OnBeforeShow事件中,如果想自动展开,请在在UniTreeView控件的OnLoaded中添加UniTreeView1->FullExpand();(注意:该语句如果添加在创建树结构的OnBeforeShow事件中创建树结构后没有作用)