如何用Gambas开发组件
前言
以下所有信息均适用于 Gambas 3。
Gambas组件是用C、C++或者直接用Gambas写成的共享库,用于向Gambas解释器中加入新的类。
一个用Gambas编写的组件是一个具有下列特殊特征的普通Gambas工程:
-
在项目属性对话框的“常规”选项卡中,“项目类型”组合框设置为“组件”
-
然后会出现一个名为“信息”的新选项卡
它必须填写以下详细信息:
-
组件的进度(即是否稳定)。
-
所需的功能。
-
所需的组件。
-
排除的组件
-
一些项目的类是 导出 的。
-
作为 控件 的导出类必须声明一些特殊的公共常量,这些常量将告诉 IDE 管理控件所需的所有信息。
很多gambas官方组件已经用gambas编写了,你可以使用它们作为示例。这些组件的源代码位于
/comp/src
源存档的目录中。
以下是这些组件的列表:
请注意,一些用 C/C++ 编写的组件也有一部分是用 gambas 编写的:
gambas 部分的源代码位于这些组件的源目录内。例如
gb.qt4 的 gambas 部分位于:
/gb.qt4/src
.
输出类
一个组件的目标是为Gambas解释器提供新的类。
你希望提供的类必须被从你的工程中
exported ,否则你的组件的用户将会看不到它们。
要标记一个类为
exported ,仅仅添加Gambas关键字
EXPORT在类源代码文件的开始。
如果一个输出类的某个方法或者属性返回在你组件中声明的另一个类的一个对象,那么这另一个类也应该作为输出类。否则,用户将不能保存一个对它的引用,除非用户使用
Object数据类型。
如果一个输出类继承自你的组件声明的另一个类,那么这另一个类也必须是输出类。
否则,在解释器加载组件时会发生错误。
隐藏的输出类
如果有一些不想让用户看到的输出类,通过用下划线作为它们名字的首字符就可以来隐藏它们。
示例,可以在
gb.desktop源代码中看到很多不会被明白看到的输出类。
这一点,可以取代仅仅存在于C/C++编写的组件中的“虚类”的概念。
控件
控件是会出现在IDE控件工具箱中的特殊的输出类。
控件通常是显示某些东西以及和用户实现交互的图形化控件。
但是也可以是正常的类,没有显示,就像
Timer控件。在这种情况下,它们被称为 “虚拟” 控件。
GUI组件(
gb.qt4或
gb.gtk)提供两个类,你应该将其作为你自己创建的控件的父类:
UserControl和UserContainer事实上是
Container 类的子类。
这样,可以通过混合已经存在的控件或容器来创建新控件或新容器。
此外,控件需要声明一些特殊的隐含常数,它们被IDE用于管理控件:
Constant
|
Type
|
Default
|
Description
|
_IsControl
|
Boolean
|
FALSE
|
This property must be set to TRUE, so that an exported class becomes a control.
|
_IsContainer
|
Boolean
|
FALSE
|
If a control is a container, i.e. if you can put other controls inside in the IDE form editor.
|
_IsMultiContainer
|
Boolean
|
FALSE
|
If a control is a multiple container, like a TabStrip.
|
_IsVirtual
|
Boolean
|
FALSE
|
If a control is virtual, i.e. just a normal class that you can put in the form editor, like the Timer or Printer class.
|
_IsForm
|
Boolean
|
FALSE
|
If a control is actually a form, i.e. the top-level container of all controls of the same family.
|
_Family
|
String
|
"*"
|
The family of the control, i.e. the kind of top-level object where you will be able to put the control.
For example: "Form" for a form control, "Report" for a control report, and "*" for a control that can be put anywhere.
|
_Group
|
String
|
_Family
|
The IDE toolbox tab name where the control will be put. By default, the family name will be used, or the "Special" group if the control has no family.
|
_Similar
|
String
|
""
|
A comma separated list of similarity groups. The IDE form editor will allow the control to be replaced by any other control sharing the same similarity groups.
A similarity group is normally a control name.
|
_Properties
|
String
|
""
|
The list of control properties. See below.
|
_DefaultEvent
|
String
|
""
|
The control default event. See below.
|
_DefaultSize
|
String
|
""
|
The control default size. See below.
|
_DefaultArrangement
|
String
|
""
|
The automatic arrangement if the control is a container and if it arranges its children automatically.
See below.
|
_DrawWith
|
String
|
""
|
The real GUI control used for drawing the control inside the form editor. See below
|
Only the
_IsControl
and the
_Properties
constants are mandatory.
这些隐藏的常量和其他任何常量一样都是继承的。因此,只要它们之间存在一些继承关系,就不必在每个控件中实际声明它们。
_Properties
常数
该常数是最重要的,而且是必须的。描述所有将出现在IDE的控件属性表中的属性的类型、缺省值和其他依赖于属性类型的信息。
语法
该指定常数是一个符合下面格式的字符串:
PUBLIC CONST _Properties AS String = " [ * , ] Property1 , Property2 , ... "
每个属性符合下面的语法:
[-] Name [ { Kind [ Arguments ] } ] = Default
-
Name 是属性的名称。当然,属性必须在控件源代码中被声明和实现。
-
Kind 是属性的种类,是比属性数据类型更精确的描述。例如,"Color"意味着属性是一个整数,但是IDE属性表会打开一个颜色选择器来定义它的值。如果没有定义,属性的种类是它的数据类型。
-
Arguments 是依赖于_Kind_值的可选参数。
-
Default 是属性的缺省值。语法依赖于属性种类。
第一个属性可以是一个星号,意味着控件自动获得它的父类在
Property1 常数中所有的属性声明。
在这种情况下,一个属性名称可以用减号开头,这意味着该属性必须被从其父类继承来的列表中移除。
属性种类
这是目前支持的_Kind_的不同值:
属性种类
|
说明
|
参数
|
Color
|
描述颜色的一个整数。
IDE将弹出一个颜色选择器来编辑该属性的值。
|
|
Font
|
一个字体。
IDE将弹出一个字体选择器来编辑该属性的值。
|
Font [ :Fixed ]
用=Font:Fixed=可以仅仅允许固定字体。
|
Path
|
一个文件路径。
IDE将弹出一个文件选择器来编辑该属性的值。
|
|
Picture
|
一个位于工程目录的图片,或一个库存的图标。
IDE将弹出一个图片选择器来编辑该属性的值。
|
|
Range
|
一个有最大值和最小值限制的整数值。
IDE将使用一个SpinBox控件来编辑该属性的值。
|
Range:Minimum;Maximum
|
Default 值必须符合属性的数据类型。对于布尔属性,能指定"True"或"False"作为缺省值。
在定义(或不定义)一个属性的
Default 值时,必须小心。
-
首先,如果不指定,缺省值是关联于属性数据类型的缺省值(Boolean属性是FALSE,数值属性是0...)。
-
其次,缺省值必须是关联于属性实现。
因为当在IDE窗体编辑器中设置一个属性为它的缺省值,在运行时没有代码来初始化该属性。
常数列表
对于使属性值进入相同类的预定义常数列表的属性,可以指定一个类代替一个属性种类作为常数的一个可选列表。
下面是语法:
属性种类
|
说明
|
参数
|
Class name
|
一个常数的列表。
IDE将使用一个ComboBox控件来编辑
该属性的值,
并用指定的常数填充它。
|
Class . ( * | Constant1 ; Constant2 ; ... ) [ = Default ]
如果用星号代替常数列表,那么会使用指定类的所有常数。
|
如果指定, Default 的值必须是常量其中一个的名称,而非真值!
示例
示例,
Control._Properties 的值是:
X{Position},Y{Position},Width{Dimension},Height{Dimension},Visible=True,Enabled=True,Font{Font},
Background{Color}=-1,Foreground{Color}=-1,Tag,
Mouse{Mouse.Default;Blank;Arrow;Cross;Wait;Text;SizeAll;SizeH;SizeV;SizeN;SizeS;SizeW;SizeE;SizeNWSE;SizeNESW;SplitH;SplitV;Pointing}=Default,
ToolTip,Drop,Expand,Ignore
它被其他所有的控件和容器继承。
这是
ListBox._Properties 的值:
*,List,Mode{Select.*}=Single,Sorted
其他特殊常数
_DefaultEvent
常数
该常数是一个描述控件缺省事件的字符串。
该缺省事件用于在IDE窗体编辑器中双击控件。
示例:
PUBLIC CONST _DefaultEvent AS String = "Click"
该常数是可选的,但是总是应该声明。
_DefaultSize
常数
该常数是一个字符串,描述控件被从工具箱拖动到窗体编辑器时的缺省尺寸。
它是宽度和高度,是
Desktop.Scale的倍数,用逗号分隔。
示例:
PUBLIC CONST _DefaultSize AS String = "36,36"
该常数是可选的。如果没有声明,IDE将尝试使其最佳。
_DrawWith
常数
该常数是一个字符串,用于告诉IDE哪一个控件应该被用来绘制在窗体编辑器上。
作为缺省,作为
gb.qt4、
/wiki/comp/gb.qt.ext、
gb.form和
gb.form.mdi成员的控件采用将Design属性设置为真来进行示例绘制。
如果控件不是上述组件的成员,那么IDE将绘制一个内有控件图标和控件名称的框架。
通过定义该常数,IDE将不使用
DrawingArea,除了你指定的控件。
示例:
PUBLIC CONST _DrawWith AS String = "TextBox"
_Arrangement
常数
该常数是一个整数值,描述IDE在将窗体保存到磁盘之前在容器中排列子控件的强制排列类型。
值是
Arrange 类常数的整数值之一。
示例:
PUBLIC CONST _DefaultArrangement AS Integer = "V" ' Arrange.Vertical
该常数仅仅被用于容器控件,而且是可选的。如果不定义,强制不排列。
控件图标
每个控件必须有一个用于在IDE控件工具箱中显示的图标。
要提供你的组件控件的图标,必须在你的工程的根目录下创建一个
/control
目录,并在里面为每一个控件图标放置一个PNG文件。
In Gambas 3, the control
directory must be created inside the .hidden
directory. This is the "Project" section in the development environment project treeview.
控件图标的名称必须是*小写*的控件类名称和=.png=扩展名。
示例:
$ cd gb.db.form
$ cd .hidden/control
$ ls
databrowser.png datacombo.png datacontrol.png datasource.png datatree.png dataview.png
关于组件的公用信息
关于组件的更多信息在工程的属性对话框的“提供”和“需要”标签页中。
注意,当工程不是一个组件时这些标签页不可见。
“提供”信息
在这个标签页里,有一个所有输出类的列表。
对每一个类,必须指定:
-
在“类型”列中,是否为控件,以及什么种类的控件。
-
在“组”列中,IDE工具箱中控件图标将要被插入的标签页的名字。
这是不同类类型的列表:
类型
|
说明
|
Class
|
一个不是控件的普通类。
|
Control
|
一个不是容器的控件。
|
Virtual
|
一个“虚拟”控件,也就是说,一个普通的类,但是在窗体编辑器中可以被放置于窗体。
例如,Timer控件。
|
Container
|
一个容器控件。这样,IDE窗体编辑器可以把其他控件放置其中。
|
MultiContainer
|
一个行为像TabStrip的容器。这意味着它分配它的子控件在不同的子容器中,
在某一时刻仅有这些子控件组中的一组可见。
|
Form
|
目前没有使用。在Gambas 3中,它用来说明一个事实上实现一些可用IDE编辑的窗体种类的容器。
|
“需要”信息
在这个标签页中,列出你的组件所依赖的所有其他组件。
在“特征”部分有4个选择框,每个对应一个由一个或多个组件提供的特征。
当你的组件需要指定的不依赖于特定组件的特征时,使用该部分。
如果确实需要一些特定的组件,可以在标签页的“组件”部分中选择它们。
在属性对话框的“组件”标签页选择的组件与在“需要”标签页中指定的组件毫无关系。
它们仅仅用于为了调试目的而从IDE运行组件工程。
调试、安装和打包组件
调试
为了调试你的组件,你可以直接照原样使用和运行它的工程!
工程的启动类和在工程属性对话框的“组件”标签页中选中的组件,在你的组件安装和被其他工程使用时将根本不会干扰你的组件的行为。
打包
IDE可以生成你的组件的二进制包,操作和任何其他普通的工程一样。 (Ctrl-Alt-I).
仅仅需要规定较少的选项:例如,组件没有菜单条目。
二进制包将全局安装组件,并且可以像由Gambas提供的其他官方组件一样使用。
The name of the installation package will be composed as
gambas3-<vendor prefix>-<project name>
, so the name of your project must not include
the vendor prefix and the
gambas3
prefix.
For example, to create the package for the
gambas3-mycompany-foo
component, your project must be named
foo
, and
mycompany
must
be specified as
vendor prefix in the packager wizard.
目前,打包程序中有一个缺陷,没有考虑组件工程版本对生成包依赖关系的影响。
所以,你必须设置你的组件工程的版本为当前Gambas的版本!
Installing
To install a component, an installation package supported by the target distribution must be created and applied. Currently these target distributions are supported by the packager wizard:
-
Archlinux
-
Autotools
-
Debian
-
Fedora / RedHat / CentOS
-
Mageia
-
OpenSUSE
-
Slackware
-
Ubuntu / Kubuntu / Mint
结束语
我试图找到最简单的方法来用IDE开发组件。它还不够完美,但是如果你对这个问题有什么看法和疑问,请用给我发邮件!
注意,这些内容在Gambas 3中将必然发生改变。
当然,如果想修改或扩充这篇文章,非常欢迎。