在0.5中,引入了一个新的布局类 - class place,该类提供了一个更加简便的方法来实现窗口的布局。class place是将于之绑定的窗口根据设计划分为几个区域,然后将子控件加入到各个区域中。本篇用一个示例来讲解class place的基本用法,然后再介绍place的详细规则。
开始示例
现在,创建一个用于验证用户账号的登录界面。这个程序看起来如下图所示:
首先,为了达到这个布局效果,我们需要将窗口划分成几个区域(Field)。其中一个划分方法如下图所示:
class place是以一个divide-text的字符串参数来划分Field的。因此先需要确定divide-text(其详细的语法参见第二部分的介绍)
红色矩形框的divide-text看起来应该像这样
<>
Root-Field的子Field默认是以水平方向排列,因此这里三个Field以水平方式排列。红色框位于窗口中间,并占据窗口80%的宽度,我们指定它的weight属性为80%。现在,如你所见,红色框中的子框是以垂直方式排列,因此我们需要指定红色方框为vertical。
橙色矩形框的divide-text看起来应该像这样
<>
橙色框也是位于窗口中间,并占据窗口70%的高度,并且,它也需要被指定为vertical。
绿色和蓝色矩形框的divide-text
绿色框中的控件以垂直方式排列,蓝色框中的按钮以水平方式排列,因此只需要为绿色框指定vertical属性。这里,蓝色框中的按钮以水平方式排列,换句话说就是,蓝色框的高度与按钮的高度相同,因此我们指定蓝色框的weight为25个像素。这两个Field在稍后会被引用,并且向它们插入控件,因此我们需要为它们每个提供一个用于查询的名字。
最后将这些divide-text组合在一起。
<>
现在,我们开始编码
#include
#include
#include
#include
int main()
{
using namespace nana::gui;
//定义文本框和按钮
form fm;
textbox usr(fm), pswd(fm);
button login(fm), cancel(fm);
usr.tip_string(STR("User:")).multi_lines(false);
pswd.tip_string(STR("Password:")).multi_lines(false).mask('*');
login.caption(STR("Login"));
cancel.caption(STR("Cancel"));
//为窗口定义一个place对象
place plc(fm);
//将窗口划分为多个Field
plc.div("<>><>><>");
//插入控件
//textboxs Field是以垂直方式排列, 它会自动调节控件的Y轴坐标和高度。
//用户框和密码框都是单行文本框,因此我们应该为它们指定固定的高度。
plc.field("textboxs")<
这里还有另一个例子:创建一个GUI的计算器
Divide-Text语法
Divide-Text用于将窗口划分为多个Field(区域),各个Field将对与之关联的窗口进行布局。
定义一个Field
<>
定义嵌套的Field
<<>>
Root Field
每个class place包含一个隐式的Root Field(根区域),所有通过Divide-Text定义的Field都是Root Field的子Field
为Field指定属性
名字:为Field指定一个名字
定义了一个名为id_you_specified的Field,然后可以通过place_object.field("id_you_specified")来引用该Field
vertical:指定Field的子Field以垂直方式布局。如果该属性未被指定,那么子Field则以水平的方式排列。例如
place plc(fm);
plc.div("");
plc.field("abc")<
如果我们将下面这样
plc.div("
替换为
plc.div("
然后我们就会获得这样的布局
weight:表示一个Field的高度或宽度,这个取决于其父Field指定排列方式。
指定以像素指定weight
如果窗口的宽度为1000像素,那么Field abc就是800像素,而def就是200像素。
如果窗口的宽度为1000像素,那么Field abc就是200像素,def为600像素,ghi则为200像素。
grid [X, Y]:指定Field以网格的方式排列其子Field
该Field被划分为3 X 2的网格
place plc(fm);
plc.div("");
plc.field("abc")<
gap:为网格Field指定每个子Field之间的间隙像素