跳转至

可调整大小的小部件

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/resizable-widgets

24260 评价本文:

尚无评分

可调整大小的小部件

匿名 2014年3月13日,星期四

在开发小部件时,准确定位它们并设置合适的大小通常很棘手。即使对于经验丰富的程序员来说,也需要进行大量的试错。当尺寸调整代码与小部件的创建代码混杂在一起时,代码会迅速变得混乱且难以阅读;这在开发跨平台小部件时尤其如此,因为不同平台可能需要不同的大小。

以下是一个未包含任何尺寸定义的小部件代码示例:

base = WIDGET_BASE(/COLUMN, TITLE='请进行一些选择', $
  /BASE_ALIGN_LEFT, /TLB_SIZE_EVENTS)
features_label = WIDGET_LABEL(base, VALUE='勾选所有适用项:')
features_base = WIDGET_BASE(base, /ROW, /NONEXCLUSIVE, UNAME='features_base')
glasses = WIDGET_BUTTON(features_base, VALUE='戴眼镜', UNAME='glasses')
moustache = WIDGET_BUTTON(features_base, VALUE='有胡须', UNAME='moustache')
over6ft = WIDGET_BUTTON(features_base, VALUE='身高超过6英尺', UNAME='over6ft')

haircolor_label = WIDGET_LABEL(base, VALUE='选择头发颜色:')
haircolor_base = WIDGET_BASE(base, /ROW, /EXCLUSIVE, UNAME='haircolor_base')
black = WIDGET_BUTTON(haircolor_base, VALUE='黑色', UNAME='black')
brown = WIDGET_BUTTON(haircolor_base, VALUE='棕色', UNAME='brown')
blond = WIDGET_BUTTON(haircolor_base, VALUE='金色', UNAME='blond')
red = WIDGET_BUTTON(haircolor_base, VALUE='红色', UNAME='red')

descrip_label = WIDGET_LABEL(base, VALUE='描述你自己:')
descrip = WIDGET_TEXT(base, /EDITABLE, UNAME='descrip')

bottom_base = WIDGET_BASE(base, /ROW, UNAME='bottom_base')
help_base = WIDGET_BASE(bottom_base, /ROW, UNAME='help_base')
help = WIDGET_BUTTON(help_base, VALUE='帮助', UNAME='help')
space = WIDGET_BASE(bottom_base, UNAME='space')
commit_base = WIDGET_BASE(bottom_base, /ROW, UNAME='commit_base', /GRID_LAYOUT)
ok = WIDGET_BUTTON(commit_base, VALUE='确定', UNAME='ok')
cancel = WIDGET_BUTTON(commit_base, VALUE='取消', UNAME='cancel')

在小部件上调用 WIDGET_CONTROL, base, /REALIZE 后,其外观如下(在 Windows 7 上):

看起来并不算太差。然而,“确定”和“取消”按钮没有位于它们通常所在的位置——右下角,并且文本框相当小。

创建一个具有所需尺寸和布局的小部件的一个技巧是编写一个单独的程序,而不是修改上述代码。运行上述代码后,只需在实现(realize)基小部件之前调用这个新程序,并传入所需的尺寸即可。

为什么要在一个单独的程序中进行?这个程序不仅用于设置原始尺寸,还可以在用户拖动边缘或角落时用于调整小部件及其所有组件的大小。允许用户调整小部件大小将提供更好的用户体验。在此示例中,用户输入的文本可能超过文本框的宽度,而能够加宽它可以让用户一次查看所有文本,而不是使用箭头键在其中导航。

以下是一个可用于调整此示例小部件尺寸的程序示例:

PRO example_widget_adjust_size, base, new_size
  COMPILE_OPT IDL2

  ; 不允许将小部件调整得比原始尺寸更小。
  WIDGET_CONTROL, base, GET_UVALUE=orig_size
  IF new_size[0] LT orig_size[0] THEN new_size[0] = orig_size[0]
  IF new_size[1] LT orig_size[1] THEN new_size[1] = orig_size[1]

  ; 确定需要减去的内边距。
  base_geom = WIDGET_INFO(base, /GEOMETRY)
  xpad = base_geom.xpad
  ypad = base_geom.ypad

  ; 文本框两侧都有内边距,因此减去两倍的 xpad。
  descrip_width = new_size[0] - 2*xpad
  descrip = WIDGET_INFO(base, FIND_BY_UNAME='descrip')
  WIDGET_CONTROL, descrip, SCR_XSIZE=descrip_width

  ; 确定帮助、确定和取消按钮的大小。底部基小部件内包含三个基小部件,因此减去4倍的 xpad。
  commit_base = WIDGET_INFO(base, FIND_BY_UNAME='commit_base')
  commit_geom = WIDGET_INFO(commit_base, /GEOMETRY)
  help_base = WIDGET_INFO(base, FIND_BY_UNAME='help_base')
  help_geom = WIDGET_INFO(help_base, /GEOMETRY)
  space_width = new_size[0] - commit_geom.xsize - help_geom.xsize - 4*xpad
  space = WIDGET_INFO(base, FIND_BY_UNAME='space')
  WIDGET_CONTROL, space, XSIZE=space_width

END

现在主程序需要定义一个尺寸,并将其与小部件基一起传递到此程序中。选择原始尺寸有两种选择:开发者可以根据认为合适的尺寸选择一个固定的原始尺寸,或者通过对每个组件项调用带有 /GEOMETRYWIDGET_INFO 并累加 x 和 y 尺寸来计算原始尺寸。出于示例目的,将使用固定尺寸。当使用固定的原始尺寸时,最好在 motif 小部件上设置的尺寸比在 Windows 上稍大一些,因为 motif 小部件使用更大的文本。

以下是设置原始尺寸所需的代码,应将其添加在 REALIZE 调用之前:

  IF !VERSION.OS_FAMILY EQ 'Windows' THEN BEGIN
    orig_size = [300, 180]
  ENDIF ELSE BEGIN
    orig_size = [350, 200]
  ENDELSE

  ; 将原始尺寸存储在 UVALUE 中以进行跟踪。
  WIDGET_CONTROL, base, SET_UVALUE=orig_size

  example_widget_adjust_size, base, orig_size

如果开发者决定更改原始尺寸,只需更新此处即可。以下是新的外观:

允许用户调整小部件大小的功能现在就可以实现了。小部件的事件处理器可以捕获使用 WIDGET_BASE 结构的大小事件,并将新尺寸传递给调整大小的程序。

  IF TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_BASE' THEN BEGIN
    example_widget_adjust_size, event.top, [event.x, event.y]
  ENDIF

现在用户可以扩展小部件,文本框和按钮会自动调整:

在此示例中,标签、复选框和单选按钮在小部件调整大小时不会改变,但此技术可以应用于任何小部件,无论大小如何,以提供可调整大小的小部件。

大数据的承诺 使用 Landsat 8 质量评估波段