基于GridView控件构建嵌入式数据库SQLite3客户端的实现方法

(整期优先)网络出版时间:2009-08-18
/ 3

基于GridView控件构建嵌入式数据库SQLite3客户端的实现方法

李新春吴士力

李新春吴士力(南京交通职业技术学院信息工程系)

摘要:本文提出了在MiniGUI中使用GridView网格控件构建嵌入式数据库SQLite3客户端的编程实现方法。在该客户端中可以访问SQLite3中存储的各种文本数据,从而为基于MiniGUI的嵌入式GUI系统提供一个界面友好、操作方便的图形数据管理接口。该接口直接为涉及数据管理领域的嵌入式应用提供了有力的支持。

关键词:MiniGUIGridViewSQLite3

0引言

随着嵌入式系统在军事、工业、医用、家电、汽车等领域的应用不断扩大和飞速发展。具有和微机软件平台类似的图形化操作界面和数据管理功能也逐渐成为嵌入式系统的基本功能要求。比如手机需要以图形化界面的方式访问和显示存储在电话薄中的相关号码内容。数控机床需要以图形化界面的方式显示存储在数据库中的各项工艺数据等。但由于嵌入式系统具有很强的针对性,所以其硬件计算资源是非常有限的。为此,嵌入式系统对图形化系统和数据库系统有好高的运行性能要求。本文介绍的使用MiniGUI网格控件GridView构建嵌入式数据库SQLite3客户端的实现方法,不仅能够满足嵌入式系统对运行性能的要求,还提供了界面友好、操作方便的图形数据管理接口。因此具有很高的实用价值和应用前景。

1MiniGUI简介

MiniGUI是北京飞漫软件技术有限公司发布的轻量级嵌入式图形系统(GUI)。MiniGUI具有体积小、运行效率高、可配置、移植性好的优点。在硬件平台方面,MiniGUI支持Intelx86、ARM、PowerPC、MIPS等体系结构。在软件平台方面,MiniGUI支持Linux、eCos、VxWorks、uC/OS-II等操作系统。

MiniGUI具有完善的GUI架构(包括窗口系统和消息驱动机制),并提供了丰富的图形控件。不但扩大了嵌入式GUI系统的应用领域范围,也大大提高了MiniGUI应用开发的效率。如今,MiniGUI已经被广泛应用于工业控制、仪器仪表、消费电子、通讯设备等领域。

网格控件GridView的图形界面是一个表格形式。表格由表头(包括行表头和列表头)和单元格组成。其中,行表头通常用于描述每一行数据的行数,列表头通常用于描述每一列数据的逻辑意义。使用鼠标拖动表头可以调整每一行的高度或者列的宽度,表格中显示不下的数据可以通过滚动条进行滚动显示。GridView的表格界面适用于各种数据报表。

由于MiniGUI的配置文件默认没有打开对GridView的支持,所以在使用“./configure”命令生成Makefile文件时,需要打开“--enable-extctrlgridview”选项。

网格控件GridView由MiniGUI的扩展库mgext提供。所以在编译使用GridView控件的MiniGUI程序时,需要增加“-lmgext”选项。

2SQLite3介绍

SQLite3是一款轻量级的开源嵌入式数据库。SQLite3具有体积小、运行性能高的优点,能在只有几百K的内存中运行,而且运行性能普遍比Mysql、PostgreSQL等开源数据库要高。SQLite3支持事务的ACID特性,具有较高的稳定性。

SQLite3支持ANSISQL92中的大多数标准,提供了对子查询、视图、触发器等机制的支持。因此,SQLite3可以满足绝大多数嵌入式系统的数据管理需求。此外,为了保证SQLite3应用程序的开发效率,SQLite3为C、Java、PHP、Python、Tcl等多种语言提供了丰富的API接口。

由于MiniGUI是基于C语言平台的GUI系统,所以MiniGUI程序是通过CAPI接口来访问SQLite3数据库的。SQLite3提供了将近80多个CAPI,提供了丰富的数据库访问功能。其中,构建SQLite3客户端需要使用的最基本的CAPI有以下几个。①sqlite3_open:该接口的作用是打开SQLite3数据库连接。②sqlite3_get_table:该接口的作用是执行SQL查询语句。③sqlite3_free_table:该接口的作用是释放SQL查询结果。④sqlite3_close:该接口的作用是关闭SQLite3数据库连接。

为了节省有限的内存资源,sqlite3_open和sqlite3_close,sqlite3_get_table和sqlite3_free_table必须成对使用。

3SQLite3客户端的编程实现

SQLite3客户端的编程实现思路是在MiniGUI程序中调用SQLite3的CAPI接口获得文本数据,然后通过网格控件GridView进行显示。

3.1创建网格控件GridView为了提高创建网格控件GridView的效率,本论文在对话框模板中进行了定义。具体代码实现如下所示:

{CTRL_GRIDVIEW,/*GridView控件的控件类名*/

WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|WS_BORDER|WS_EX_NONE,/*GridView控件的界面显示风格*/

10,10,300,200,/*GridView控件在显示屏上的位置,分别是控件的起始x和y坐标以及长度和宽度*/

IDC_GRIDVIEW,/*GridView控件的实例对象名,用于标识具体的GridView控件*/

NULL,

(DWORD)&gvdata/*GRIDVIEWDATA结构体的指针*/},

为了能对GridView控件的数据显示方法进行有效控制,需要定义以下结构体变量:

staticGRIDCELLScellsel;/*该结构体用于设置单元格的范围*/

staticGRIDCELLDATAcelldata;/*该结构体用于设置单元格的属性*/

staticGRIDCELLDATAHEADERheader;/*该结构体用于设置表头的属性*/

staticGRIDCELLDATATEXTcelltext;/*该结构体用于设置单元格的文本数据显示属性*/

staticGRIDVIEWDATAgvdata;/*该结构体用于设置网格控件的行列数以及行列高度的信息*/

在嵌入式应用系统中,一般需要根据实际的数据库结果集动态调整GridView的行列数。因此在实例化GridView前,首先需要读取当前需要显示的结果集,以获得行列数。具体代码实现如下所示:

sqlite3*db=NULL;

char*errmsg=NULL;

char**azResult;

intrc,nrow,ncolumn;

rc=sqlite3_open("database.db",&db);

sqlite3_get_table(db,"select*fromtable",&azResult,&nrow,&ncolumn,&errmsg);

调用sqlite3_get_table接口后,结果集的行列数被保存到了nrow和ncolumn变量中。

3.2在GridView中显示SQLite3数据在关系数据库中,表中的每一列都有明确的意义,以满足最基本的1NF范式。所以在使用GridView显示SQLite3数据时,需要初始化每一项列表头。列表头的数据即可以预先存储在数组中,也可以动态从数据库中读取。在实际应用中,列表头的值一般是预先设定的。本论文把列表头的每一项数据存放在数组header中。具体代码实现如下所示:

{staticchar*header[]={"姓名","性别","年龄","籍贯"};

for(j=1;j<=ncolumn;j++)

header.buff=header[j-1];

header.len_buff=-1;

celldata.content=&header;

celldata.mask=GVITEM_MAINCONTENT;

celldata.style=GV_TYPE_HEADER;

cellsel.row=0;

cellsel.column=j;

cellsel.width=1;

cellsel.height=1;

SendMessage(hGridView,GRIDM_ADDCOLUMN,j,0);

/*发送GRIDM_ADDCOLUMN消息,用以增加新列*/

SendMessage(hGridView,GRIDM_SETCELLPROPERTY,(WPARAM)&cellsel,(LPARAM)&celldata);

/*发送GRIDM_SETCELLPROPERTY消息,用以设置单元格属性*/}

完成对GridView列表头的初始化后,就可以显示从SQLite3中查询获得的具体数据了。由于关系数据库表是二维的,所以通过二重循环来控制GridView显示数据的过程。具体代码实现如下所示:

sprintf(sqlbuff,"select*fromtable);

sqlite3_get_table(db,sqlbuff,&azResult,&nrow,&ncolumn,&errmsg);

/*sqlite3_get_table接口把查询获得的结果集写入二维数组azResult中*/

for(i=1;i<=nrow;i++)

{SendMessage(hGridView,GRIDM_ADDROW,i,0);

/*发送GRIDM_ADDROW消息,用以增加新行*/

for(j=0;j<ncolumn;j++)

{celltext.buff=azResult[i*ncolumn+j];

/*依次把存储在二维数组azResult中的每项数据赋给GridView的每个单元格*/

celltext.len_buff=-1;

celldata.content=&celltext;

celldata.mask=GVITEM_MAINCONTENT;

celldata.style=GV_TYPE_TEXT;

cellsel.row=i;

cellsel.column=j+1;

cellsel.width=1;

cellsel.height=1;

SendMessage(hGridView,GRIDM_SETCELLPROPERTY,(WPARAM)&cellsel,(LPARAM)&celldata);}

上述代码把SQLite3数据库中的table表中的所有数据全部在GridView中进行了显示。其界面如图1所示:

4结束语

本论文通过GridView的网格界面直观清晰的显示了客户需要查询的文本数据,圆满的完成了本论文的目标。在使用GridView控件时,需要注意一下两点:①由于GridView控件常用于显示大量的数据,所以尤其需要控制GridView控件的创建和使用效率。否则会发生因滥用内存而造成内存溢出的问题。②GridView控件的结构必须严格按照数据结果集的结构进行设计,否则会造成MiniGUI程序运行时错误。

参考文献:

[1]刘小春,柴育梅,张彦丽.SQLite嵌入式数据库的应用研究.电脑知识与技术.2006第S1期.

[2]张斌,罗桂娥.MiniGUI连接SQLite数据库的编程实现[J].微计算机信息.2007.

[3]北京飞漫软件技术有限公司.MiniGUI编程指南[Z].http://www.minigui.com.2004.

[4]王先春,蔡剑建华等.基于ARM_Linux的嵌入式图形系统研究[J].微计算机信息,2007,4-2:13-15.

[5]杨水清.ARM嵌入式Linux系统开发技术详解.北京:电子工业出版社.2008.