第二章 创建对话框 (可变形对话框) |
发布: 2008-05-29 22:17 |
可变形对话框我们已经知道了如何创建总是显示相同的物件的对话框。某些情况下,需要创建可以变形的对话框。两种常用的可变形对话框是扩展对话框和多页对话框。这个两种对话框都可以在Qt中实现,不管是手写代码还是使用Qt Designer。 可扩展对话框通常提供一个简单的外观,但是包含一个开关按钮允许用户在对话框简单外观和可扩展外观之间转换。可扩展对话框一般用在同时适用于普通用户和高级用户的应用中,默认隐藏高级选项功能,当用户明确指定的时候再显示出来。在本节中,我们要用 Qt 设计师来创建图 2.10 中的可扩展对话框。 Figure 2.10. The Sort dialog with simple and extended appearances
这个对话框是一个spreadsheet应用程序中的排序对话框,在这个对话框中用户可以选择一列或多列进行排序。对话框的简单外观允许用户输入一个排序关键字,扩展外观提供了额外的两个排序关键字。一个附加的按钮允许用户在简单外观和扩展外观之间转换。 我们将用Qt Designer创建物件和它的扩展外观,并在运行时按需要隐藏第二和第三个关键字。物件看起来很复杂,但是在Qt Designer实现起来却是相当容易的。窍门就是先做主关键字部分,然后复制它两次来获取第二和第三关键字:
Figure 2.11. Laying out the group box's children in a grid
如果一个布局不是很合适或者如果你犯了一个错误,你可以点击 Edit|Undo 或者 Form|Break Layout,然后重新布局物件再次尝试。 现在我们将添加第二和第三主键的分组框:
Figure 2.12. Laying out the form's children in a grid
结果的网格布局有两列和四行, 重命名窗体 "SortDialog" 设置窗口的标题为 "Sort"。设置子物件的名字为 Figure 2.13 显示的那样: Figure 2.13. Naming the form's widgets
点击 Edit|Edit Tab Order。从上到下依次点击每个下拉列表框,然后点击右边的OK、Cancel和More按钮。单击Edit|Eeit Widgets 离开tab顺序模式。 现在我们已经创建了窗体,我们准备设置一些信号/槽连接使它可用。Qt Designer 允许我们在同一窗体的物件之间建立连接。我们需要创建两个连接。 单击 Edit|Edit Signals/Slots 进入 Qt Designer的连接模式。窗体物件之间的蓝色箭头代表了物件之间的连接。因为我们选择了 "Dialog with Buttons Right" 模板, OK 和 Cancel 按钮已经连接到 QDialog's accept() 和 reject() 槽上。连接也在 Qt Designer'的signal/slot 编辑器窗口列出来了。 要在两个物件之间建立一个连接,点击 sender 物件并拖拽红色箭头线widget and drag the red arrow line to the receiver widget, 然后释放。这会弹出一个对话框允许你选择要建立连接信号和槽。 Figure 2.14. Connecting the form's widgets
第一个连接建立在More按钮和第二个分组框之间。拖拽红色箭头线在这两个物件之间,然后选择 toggled(bool) 作为信号 setVisible(bool) 作为槽。默认,Qt Designer 不在槽的列表中列出 setVisible(bool) ,但是如果你打开Show all signals and slots 选项它就会显示。 Figure 2.15. Qt Designer's connection editor
第二个连接在More按钮的toggled(bool) 信号和 tertiaryGroupBox的 setVisible(bool) 槽之间建立。一旦连接建立点击 Edit|Edit Widgets 离开连接模式。 在一个目录名为sort中以 sortdialog.ui 保存对话框。向窗体添加代码,我们将使用在上一部分中Go-to-Cell对话框中用到的相同的多重继承的方式。 首先,创建一个 sortdialog.h 文件,内容如下: #ifndef SORTDIALOG_H #define SORTDIALOG_H #include <QDialog> #include "ui_sortdialog.h" class SortDialog : public QDialog, public Ui::SortDialog { Q_OBJECT public: SortDialog(QWidget *parent = 0); void setColumnRange(QChar first, QChar last); }; #endif
然后创建 sortdialog.cpp: 1 #include <QtGui> 2 #include "sortdialog.h" 3 SortDialog::SortDialog(QWidget *parent) 4 : QDialog(parent) 5 { 6 setupUi(this); 7 secondaryGroupBox->hide(); 8 tertiaryGroupBox->hide(); 9 layout()->setSizeConstraint(QLayout::SetFixedSize); 10 setColumnRange('A', 'Z'); 11 } 12 void SortDialog::setColumnRange(QChar first, QChar last) 13 { 14 primaryColumnCombo->clear(); 15 secondaryColumnCombo->clear(); 16 tertiaryColumnCombo->clear(); 17 secondaryColumnCombo->addItem(tr("None")); 18 tertiaryColumnCombo->addItem(tr("None")); 19 primaryColumnCombo->setMinimumSize( 20 secondaryColumnCombo->sizeHint()); 21 QChar ch = first; 22 while (ch <= last) { 23 primaryColumnCombo->addItem(QString(ch)); 24 secondaryColumnCombo->addItem(QString(ch)); 25 tertiaryColumnCombo->addItem(QString(ch)); 26 ch = ch.unicode() + 1; 27 } 28 }
构造函数隐藏对话框的第二和第三部分。它还设置窗体布局的 sizeConstraint 属性为 QLayout::SetFixedSize,使得对话框对用户不可改变大小。当子物件显示或隐藏时,布局将接管更改大小的回应,然后自动更改对话框的大小,确保对话框总是以合适的大小显示。 setColumnRange() 槽根据spreadsheet选择的列来初始化下拉列表的内容。我们在下拉列表中插入一个 "None" 项 in the comboboxes for the (optional) secondary and tertiary keys.
行 19 和 20 暗示了一种微妙的布局思想。 QWidget::sizeHint() 函数返回一个物件的理想大小,这是布局系统所期望的。这就解释了为什么不同的物件或者包含不同内容的相似的物件可能被布局系统赋予不同的尺寸了。 对于下拉列表框,这意味着包含内容”None”的第二和第三下拉框会大于只包含一个字母的第一个下拉框。为了避免这种矛盾,我们把第一个下拉框的最小尺寸设置为第二个下拉框的理想尺寸了。 这里有一个 main() 测试函数设置包含了列'C' 到 'F' 范围然后显示对话框: #include <QApplication> #include "sortdialog.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); SortDialog *dialog = new SortDialog; dialog->setColumnRange('C', 'F'); dialog->show(); return app.exec(); }
到这里我们就全部完成了可扩展对话框。就像例子中展示的那样,设计一个可扩展对话框并不比设计一个普通对话框困难多少:我们所需要做的就是一个开关按钮,一些额外的信号槽连接,和一个不可变的布局。在生产级应用程序,用按钮控制高级扩展内容的显示是很普通的一件事情 >>> 仅当基础对话框可见并且是高级模式时 <<< 仅当扩展显示时。这在Qt中可很容易的当点击QPushButton时调用setText()实现。 其他常用的可变形对话框,多页对话框用Qt创建甚至更简单,不管是手写代码还是使用Qt Designer。这些对话框可以使用很多不同的方法创建。
QStackedWidget 类描述在 第 6 章 中(布局管理).
|
原文: http://qtchina.tk/?q=node/112 |
Powered by zexport
|