可变形状的对话框(Shape-Changing Dialog)

2.4 可变形状的对话框(Shape-Changing Dialog)
 
我们已经知道了如何创建运行的时候控件固定的对话框了。但是有时,我们需要能改变形状的对话框。两种最常用的可变形状的对话框是可扩展对话框和多页对话框。这两种对话框的Qt实现既可以通过手写代码也可以使用Qt Designer。
 
可扩展对话框通常外观简单,但是提供一个切换按钮来切换对话框的普通外观和扩展外观。这种对话框通常是用来迎合普通用户和高级用户,除非用户要求显示,否则高级选项是隐藏的。在这一节中,我们将使用Qt Designer来创建一个可扩展对话框,如图2.11。
 
<!--[if !vml]--><!--[endif]-->

 
图2.11. 排序对话框的普通外观和扩展外观
 
 
上图中的对话框是电子表格应用程序的排序对话框,用户可以选中一行或多行来进行排序。普通外观下,用户可以输入一个排序关键字,而扩展外观下提供了两个额外关键字。按钮more让用户能在普通外观和高级外观下进行切换。
 
我们将用Qt Designer创建一个外观扩展了的对话框,然后在运行时隐藏它的第二和第三关键字部分。这个对话框看起来很复杂,但是用Qt Designer实现起来相当容易。方法是先完成一个关键字部分,然后通过复制两次来得到第二关键字和第三关键字部分:
 
1. 单击File|New Form,然后选择”Dialog without Buttons”模板。
 
2. 创建一个OK按钮,把它拖到窗体的右上方。改变它的objectName为”okButton”,并且设置它
default属性为”true”。
   
3. 创建一个Cancel按钮,拖动它到OK按钮下边。改变它的objectName为”cancelButton”。
   
4. 创建一个vertical spacer,拖动它到Cancel按钮下边,然后创建按钮More,然后拖动它到
    vertical spacer下边。改变More按钮的objectName为”moreButton”,设置它的text属性为”
    &More”,设置checkable属性为”true”。
   
5. 选中OK按钮,然后按住shift键再分别选中Cancel按钮、vertical spacer以及More按钮,单击
    Form|Lay out Vertically。

  
6. 创建一个group box,两个label,两个combobox和一个horizontal spacer,然后将它们放在体
    的任意位置。
   
7. 拖动group box的右下角,改变它的大小,让它更大些。然后移动其它控件到group box中,并将

    这些控件的布局大致如图2.12(a)那样。
   
8. 拖动第二个combobox的边缘来使它的宽度为第一个combobox的两倍。
   
9. 设置group box的title属性为”&Primary Key”,设置第一个label的text属性为”Column:”,
    第二个label的text属性为”Order:”。
   
10. 右击第一个combobox,在弹出菜单中选择Edit Items,会弹出一个Qt Designer的combobox编辑
    器。创建一个空项。
   
11. 右击第二个combobox,也选择Edit Items,创建一个”Ascending”项和一个”Descending”项。
   
12. 选中group box,然后单击Form|Lay Out in a Grid。再次选中group box,单击Form|Adust Size。最后的显示结果如图2.12(b)。
   
   
<!--[if !vml]--><!--[endif]-->

 
图2.12 对group box中的控件使用表格布局管理器

 
 
如果一个布局管理器不能正确的起作用,或者是你设计时错了,你总是可以单击Edit|Undo或Form|Break Layout来重新定位控件的位置,然后再次设置布局管理器。
 
现在我们将添加第二和第三关键字的group box。
 
1. 调整对话框大小,是它能容纳其余部分。
 
2. 按住Ctrl键(在Mac中是Alt键),然后选中并拖动原窗体顶部的第一个关键字的group box来复制一
个group box(包括它里边的控件)。拖动这个复制来的group box到原group box下面,再次按住
Ctrl(Alt),重复刚刚的步骤来创建第三个group box,并拖动到group box下面。

 
3. 改变第二和第三个对话框的title属性为”&Secondary Key”和”&Tertiary Key”。
 
4. 创建一个vertical spacer并将它放到第一个关键字group box和第二个关键字group box之间。
 
5. 将窗体中的控件排列成如图2.13(a)那样的表格一样的风格。
 
6. 选中窗体来取消对选中控件的选择,单击Form|Lay Out in a Grid。现在向左上拖动窗体的右下角,

尽可能的缩小窗体。窗体现在应该和图2.13(b)。
 
7. 设置两个vertical spacer的sizeHint属性为[20,0]。
 
 
<!--[if !vml]--><!--[endif]-->

 
图2.13. 对窗体控件使用表格管理器
 
 
这个的表格管理器有四行两列,总共八个格子。第一个关键字group box、最左边的vertical spacer、第二关键字group box以及第三关键字group box都各自独占一个格子。包含OK按钮、Cancel按钮和More按钮的vertical layout占了两个格子。
 
在窗体的右下角留有另个空的格子。如果在你的窗体中不是那样的,取消布局管理器,重新设置控件的位置,重新布局。
 
将窗体重命名为”SorDialog”,改变窗体的标题为”Sort”。如图2.14那样设置窗体子控件的名字。
 
<!--[if !vml]--><!--[endif]-->

 
图2.14. 命名窗体中的控件
 
单击Edit|Edit Tab Order,从窗体顶部到窗体底部依次点击每一个combobox,然后点击右边的OK按钮、Cancel按钮和More按钮。单击Edit|Edit Widgets来裂变tab顺序模式。
 
现在窗体已经设计好了,下来我们通过建立信号和槽的连接来实现它的功能。Qt Designer允许我们为同一窗体中的控件间建立连接。我们需要建立两个连接。
 
单击Edit|Edit Signals/Slots来进入Qt Designer的连接模式。连接是由窗体控件间的蓝色箭头表示的,如图2.15,这些关系也将列在Qt Designer的信号/槽编辑窗口中。要建立两个控件间的连接,只需选中击发送控件并拖动红色箭头线到接受控件上,然后释放。此时会弹出一个选择要连接的信号和槽的对话框。
 
<!--[if !vml]--><!--[endif]-->

 
图2.15. 连接窗体中的控件
 
第一个建立的是okButton和窗体accept()槽的连接。从okButton拖动红色箭头线到窗体的空白处,然后释放,弹出的配置连接对话框如图2.16。选择cliecked()作为信号,accept()作为槽,然后单击OK按钮。
 
<!--[if !vml]--><!--[endif]-->

 
图2.16. Qt Designer的连接编辑器
 
下来是第二个连接,从cancelButton拖动红色箭头线到窗体的空白处,然后在配置连接对话框中连接按钮的clicked()信号到窗体的reject()槽。
 
第三个要建立的是moreButton和secondaryGroupBox的连接。在这个两个控件间拖动红色箭头线,然后选择toggled(bool)作为信号,setVisible(bool)作为槽。默认情况下,Qt Designer不会在槽列表中列出setVisible(bool),但是你可以选择Show all signals shots选项来显示它。

 
第四个也是最后一个连接是moreButton的toggled(bool)信号和tertiaryGroupBox的setVisible(bool)间的连接。当所有连接都完成后,单击Edit|Edit Widgets来离开连接模式。
 
保存这个对话框为sortdialog.ui,保存到名为sort的目录下。我们将使用多重继承的方法来为窗体添加代码,就像前一节的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()槽是用来初始化以电子表格中被选中列为基础的combobox的内容的。我们为第二和第三关键字(可选的)的combobox插入一个”None”项。
 
第19和20行展示了一个精细的布局方法。Qwidget::sizeHint()函数返回的是控件的"理想"大小,这正是布局系统想要的。这也解释了为什么拥有不同内容的不同或相似的控件,可能会被布局管理系统设置为不同的大小。对于这些combobox,这就意味着包含”None”项的第二和第三个combobox,最终要比包含只有一个字母的第一个combobox大。为了避免这种不一致,我们将第一个combobox大小的最小值设为了第二个combobox大小的理想值。
 
下来是一个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();

}
 
 
这就完成了整个可扩展对话框。这个例子说明,一个可扩展对话框不比普通的对话框难设计多少。所有我们需要的只是一个切换按钮,一些额外的信号和槽的连接,以及一个不能改变大小的布局管理器。在编写应用程序过程中,用一个按钮来控制对话框的扩展是很常见的,当对话框是基本状态时,按钮上的文字是Advanced>>>,而当对话框为扩展状态时,按钮上的文字是Advanced<<<。这在Qt中可以通过在单击按钮时调用QPushButton的setText()来轻松实现。
 
另一种常见的可改变形状的对话框是多页对话框,它在Qt中甚至更容易创建,不管是写代码还是使用Qt Designer。这种对话框有多种不同实现方式。
 
● QTabWidget可以显示在自身右部。它提供了一个tab栏来控制内部的QStackedWidget。
 
● QListWidget和QStackedWidget可以被一起使用,QListWidget的当前项,通过连接QListWidget::currentRowChanged()信号和QStackedWidget::setCurrentIndex()槽,决定显示哪个QStackedWidget页面。
 
● QTreeWidget可以和QStackedWidget一起在使用,它的使用方法和QListWidget类似。
 
我们将在第6章介绍QStackedWidget。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/larrytone/archive/2008/07/08/2625553.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值