# 9.4 一些更深入的话题
下面的这些提示可以让你创建的对话框看上去更专业.
键盘导航
尽量给你的对话框上的控件的标签增加"&"前导符,在某些平台(特别明显的是在windows和GTK+平台上),这将使得用户可以通过键盘在控件之间移动.
总是给你的对话框提供一个取消操作,最好是使用Escape键来执行这个操作.如果你的对话框有一个标识符为wxID_CANCEL的按钮,那么默认情况下它的处理函数将在用户按下Escape键的时候被执行,因此,如果你有一个单纯用来关闭对话框的按钮,最好将它的标识符定义为wxID_CANCEL.
提供一个默认按钮(通常为OK按钮),你可以通过wxButton::SetDefault函数指定一个默认按钮,这个按钮的处理函数将在用户按下回车键的时候被调用.
数据和用户界面分离
为了简化例子,我们在PersonalRecordDialog中采用了把数据存放在对话框内部的方法.然而,一个更好的设计应该是让用户数据和对话框分离,在构造函数中进行赋值操作,这样的话你就可以更方便的传递一组数据给这个对话框的构造函数,以及在用户确认修改的时候(按下OK按钮的时候)从对话框获取一整组数据.这也是大多数标准对话框采用的方法.作为一个练习,你可以使用PersonalRecordData类作为 PersonalRecordDialog的数据成员重写PersonalRecordDialog的代码,以使得对话框的构造函数采用 PersonalRecordData的引用作为参数,而对话框的Getdata函数则返回其内部数据的引用.
一般说来,你应该尽可能的将界面功能和非界面功能分开.这通常会让你的代码显得更紧凑.不要害怕增加新的类,它会让你的设计更优雅,也不要惧怕在类中使用复制或者赋值之类的操作,如果一个对象能够很容易的被赋值和赋值,应用程序可以少些很多底层的赋值代码.
除非你的对话框提供了一个类似"Apply"功能的按钮,否则,在对话框被取消之后,所有内部的数据应该保持原样.使用数据和界面分离的原则也使得实现这一点变得相对容易,因为通常在这种情况下,你只是操作数据的一份拷贝而不是数据本身.
布局
如果你的对话框看上去好像显得有些拥挤或者说有些丑陋,可能是因为你没有给予足够的空白区间.你可以尝试单独使用一个布局控件来增加一个大的边界区域,就象我们在例子中作的那样,在一组控件和另外一组控件之间增加空白,或者使用wxStaticBoxSizer和wxStaticLine 将逻辑上处于两组的控件区隔开.使用wxGridSizer和wxFlexGridSizer布局控件来对齐控件及它们对应的标签以便它们的位置显得不那么零乱.在基于布局控件的布局中,还可以使用空白区域来实现对齐.比如,通常OK,Cancel按钮和Help按钮应该被设置为右对齐,你可以通过在水平 wxBoxSizer的水平方向上增加一个可以缩放的(缩放因子不为负数的)空白区域,然后再增加这些按钮,以便在对话框的水平大小发生改变时实现按钮的右对齐.
尽可能的让你的对话框的边框是可以改变大小的,通常windows系统上的对话框的大小是不能被改变的,但是这样做实在是有些无厘头. 在一个大的对话框上使用很少的控件通常都令用户感到沮丧.在wxWidgets下通过布局控件创建可变大小的对话框是非常简单的事情,你应该尽可能的使用布局控件以便你的对话框可以自适应字体和语言以及对话框大小的改变.当然,你要小心的选择那些可以随着对话框大小的改变而改变大小的控件,例如,多行文本框控件就是一个不错的选择,它的大小随着对话框的大小一起增长可以给用户更多实用的空间,另外,你还可以考虑把增加的空间分给空白区域以实现对齐.注意我们这里说的控件增大,不是只的缩放控件或者是让控件的文本变的更大,而仅仅是指的增加控件的宽度和高度.参考第7章以得到更多关于布局控件的知识.
如果你发现你的对话框上放置了太多的控件,你应该考虑增加面板,并且使用wxNotebook, wxListbook或wxChoicebook来进行分页.使用太多菜单来打开很多互不相干的对话框通常是非常令用户感到不爽的,用分页控件,用户自己选择查看哪个页面,这样就显得方便多了.同时在面板里使用滚动条也是应该被避免的(除非你又充足的原因).这一方面是因为不是所有的平台都支持滚动控件, 另外一方面,这也会给用户一个印象:你对控件布局并没有进行充分的设计.如果你有很多的属性需要用户编辑,你可以考虑使用基于wxGrid的属性编辑器或者其它的第三方控件(参考wxPropertyGrid,在附录E,"wxWidgets的第三方工具"中有提到这个控件).
美学
标签的大小写要保持一致.不要给对话框设置自定义的颜色和字体,这有时候会让你的用户感到抓狂而且也使得你的应用程序看上去有些特立独行 (贬义),和系统当前的风格或者你的应用程序中的其它对话框不一致.要在各个平台都取得不错的效果,最好让wxWidgets自己决定对话框的颜色或者字体.取而代之的,你可以把精力花费在设计一些新颖而紧凑的小图片上,并且在合适的位置使用wxStaticBitmap控件显式它.
对话框的替代品
最后,对于那些非模式的解决方案,你应该好好考虑是否要使用一个对话框,也许在应用程序的主窗口中使用TAB控件会是更好的选择. 尽管我们前面所说的大部分原则都适用于非模式的对框框,但是它们确实有一些不同之处,比如你需要额外考虑布局(通常这种窗口拥有原少于它的大小的控件)以及数据同步(对于非模式窗口来说,它在显示的时候不能以独占的方式访问它的数据了).
- 第一章 介绍
- 1.1 为什么要使用wxWidgets?
- 1.2 wxWidgets的历史
- 1.3 wxWidgets社区
- 1.4 wxWidgets和面向对象编程
- 1.5 wxWidgets的体系结构
- 1.6 许可协议
- 第一章小结
- 第二章 开始使用
- 2.1 一个小例子
- 2.2 应用程序类
- 2.3 Frame窗口类
- 2.4 事件处理函数
- 2.5 Frame窗口的构造函数
- 2.6 完整的例子
- 2.7 wxWidgets程序一般执行过程
- 2.8 编译和运行程序
- 第二章小结
- 第三章 事件处理
- 3.1 事件驱动编程
- 3.2 事件表和事件处理过程
- 3.3 过滤某个事件
- 3.4 挂载事件表
- 3.5 动态事件处理方法
- 3.6 窗口标识符
- 3.7 自定义事件
- 第三章小结
- 第四章 窗口的基础知识
- 4.1 窗口解析
- 4.2 窗口类概览
- 4.3 基础窗口类
- 4.4 顶层窗口
- 4.5 容器窗口
- 4.6 非静态控件
- 4.7 静态控件
- 4.8 菜单
- 4.9 控制条
- 第四章小结
- 第五章绘画和打印
- 5.1 理解设备上下文
- 5.2 绘画工具
- 5.3 设备上下文中的绘画函数
- 5.4 使用打印框架
- 5.5 使用wxGLCanvas绘制三维图形
- 第五章小节
- 第六章处理用户输入
- 6.1 鼠标输入
- 6.2 处理键盘事件
- 6.3 处理游戏手柄事件
- 第六章小结
- 第七章使用布局控件进行窗口布局
- 7.1 窗口布局基础
- 7.2 窗口布局控件
- 7.3 使用布局控件进行编程
- 7.4 更多关于布局的话题
- 第七章小结
- 第八章使用标准对话框
- 8.1信息对话框
- 8.2 文件和目录对话框
- 8.3 选择和选项对话框
- 8.4 输入对话框
- 8.5 打印对话框
- 第八章小结
- 第九章创建定制的对话框
- 9.1 创建定制对话框的步骤
- 9.2 一个例子:PersonalRecordDialog
- 9.3 在小型设备上调整你的对话框
- 9.4 一些更深入的话题
- 9.5 使用wxWidgets资源文件
- 第九章小结
- 第十章使用图像编程
- 10.1 wxWidgets中图片相关的类
- 10.2 使用wxBitmap编程
- 10.3 使用wxIcon编程
- 10.4 使用wxCursor编程
- 10.5 使用wxImage编程
- 10.6 图片列表和图标集
- 10.7 自定义wxWidgets提供的小图片
- 第十章小结
- 第十一章剪贴板和拖放操作
- 11.1 数据对象
- 11.2 使用剪贴板
- 11.3 实现拖放操作
- 第十一章小结
- 第十二章高级窗口控件
- 12.1 wxTreeCtrl
- 12.2 wxListCtrl
- 12.3 wxWizard
- 12.4 wxHtmlWindow
- 12.5 wxGrid
- 12.6 wxTaskBarIcon
- 12.7 编写自定义的控件
- 第十二章小结
- 第十三章数据结构类
- 13.1 为什么没有使用STL?
- 13.2 字符串类型
- 13.3 wxArray
- 13.4 wxList和wxNode
- 13.5 wxHashMap
- 13.6 存储和使用日期和时间
- 13.7 其它常用的数据类型
- 第十三章小结
- 第十四章文件和流操作
- 14.1 文件类和函数
- 14.2 流操作相关类
- 第十四章小结
- 第十五章内存管理,调试和错误处理
- 15.1 内存管理基础
- 15.2 检测内存泄漏和其它错误
- 15.3 构建自防御的程序
- 15.4 错误报告
- 15.5 提供运行期类型信息
- 15.6 使用wxModule
- 15.7 加载动态链接库
- 15.8 异常处理
- 15.9 调试提示
- 第十五章小结
- 第十六章编写国际化程序
- 16.1 国际化介绍
- 16.2 从翻译说起
- 16.3 字符编码和Unicode
- 16.4 数字和日期
- 16.5 其它媒介
- 16.6 一个小例子
- 第十六章小结
- 第十七章编写多线程程序
- 17.1 什么时候使用多线程,什么时候不要使用
- 17.2 使用wxThread
- 17.3 用于线程同步的对象
- 17.4 多线程的替代方案
- 第十七章小结
- 第十八章使用wxSocket编程
- 18.1 Socket类和功能概览
- 18.2 Socket及其基本处理介绍
- 18.3 Socket标记
- 18.4 使用Socket流
- 18.5 替代wxSocket
- 第十八章小结
- 第十九章使用文档/视图框架
- 19.1 文档/视图基础
- 19.2 文档/视图框架的其它能力
- 19.3 实现Undo/Redo的策略
- 第十九章小结
- 第二十章完善你的应用程序
- 20.1 单个实例和多个实例
- 20.2 更改事件处理机制
- 20.3 降低闪烁
- 20.4 实现联机帮助
- 20.5 解析命令行参数
- 20.6 存储应用程序资源
- 20.7 调用别的应用程序
- 20.8 管理应用程序设置
- 20.9 应用程序安装
- 20.10 遵循用户界面设计规范
- 20.11 全书小结