可改变形状的对话框
最常见的可改变形状的对话框有两种:扩展对话框和多页对话框。在Qt中,不论是纯粹使用代码还是使用Qt设计师,都可以实现这两种对话框。
扩展对话框
扩展对话框通常只显示简单的外观,但是它还有一个切换按钮,可以让用户在
对话框的简单外观和扩展外观之间来回切换。扩展对话框通常用于试图同时满足普通用户和高级用户需要的应用程序中,这种应用程序通常会隐藏那些高级选项,除非用户明确要求看到它们。
这个对话框是一个用于电子制表软件应用程序的排序对话框(Sort对话框) ,在这个对话框中,用户可以选择一列或多列进行排序。在这个简单外观中,允许用户输人一个单一的排序键,而在扩展外观下,还额外提供了两个排序键。More按钮允许用户在简单外观和扩展外观之间切换。
设计界面
1、添加新文件->文件和类中选择Qt->Qt 设计师界面类->Dialog without Buttons->类名“SortDialog”。
然后删除下面这个
2、重新创建OK按钮并拖放到窗体的右上角。将它的objectName修改成“okButton”,并将它的default属性设置为“true”。
3、重新创建Cancel按钮并拖放到OK按钮下方。将它的objectName修改成“cancelButton”。
4、创建一个垂直分隔符并拖放到Cancel按钮下方,然后再创建一个More按钮。并将它放在垂直分隔符的下方。将More按钮的objectName修改为“moreButton”,text属性设置为“&More”,checkable属性设置为ture。
5、单击OK按钮,按下Ctrl键再单击Cancel按钮、垂直分隔符和More按钮,然后单击垂直布局。
6、创建一个群组框(GroupBox)、两个标签(QLabel)、两个组合框(Combo Box)以及一个水平分隔符(Horizontal Spacer),然后把它们放到窗体上的任意位置。
7、拖动群组框右下角使它变大一些。然后把其他窗口部件移到群组框中,拖动第二个组合框的右边缘使它的宽度大约为第一个组合框的两倍。
8、将群组框的title属性设置为“&Primary Key”,第一个标签的text属性设置为“Column:”,第二个标签的text属性设置为“Order:”。
9、右键单击第一个组合框,选择编辑项目,添加一个文本项“None”,右键单击第二个组合框,选择编辑项目,添加两个文本项“Ascending”和“Descending”,
10、单击群组框,然后单击栅格布局(快捷键Ctrl+G)。再次点击群组框,单击调整大小(Ctrl+J)。此时将会产生一个如图所示的布局。
11、按下Ctrl键(Mac按下Alt键),然后单击并拖动Primary Key群组框,将第一个群组框的内容再生成两个群组框。
12、将它们的title属性分别修改为“&Secondary Key”和“&Tertiary Key”。
13、创建一个垂直分隔符,放在第一个群组框和第二个群组框之间。
14、将这些窗口部件如下图排列成网格状。单击窗体,取消对任意选中窗口部件的选择,单击栅格布局(Ctrl+G)。
15、单击编辑->Edit Tab Order,从窗体最上面到最下面依次单击每个组合框,然后单击窗体右侧的OK、Cancel和More按钮。单击编辑->Edit Widgets离开Tab键顺序设置模式。
16、单击编辑->Edit Signals/Slots,进入Qt设计师的设置连接模式。窗体中各个窗口部件之间的连接用蓝色箭头表示。
要在两个窗口部件之间建立连接,可以单击作为发射器的窗口部件并且拖动所产生的红色箭头线到作为接收器的窗口部件上,然后松开鼠标按键。这时会弹出一个对话框,可以从中选择建立连接的信号和槽。
要建立的第一个连接位于okButton按钮和窗体的accept()槽之间。把从okButton按钮开始的红色箭头线拖动
到窗体的空白区域,然后松开按键,这样会弹出如下图所示的设置连接对话框。从该对话框中选择clicked()作为信号,选择accept()作为槽,然后单击OK按钮。
17、对于第二个连接,把从cancelButton按钮开始的红色箭头线拖动到窗体的空白区域,然后在设置连接对话框中连接按钮的clicked( )信号和窗体的reject()槽。
要建立的第三个连接位于moreButton按钮和secondaryGroupBox群组框之间。在这两个窗口部件之间拖动红色箭头线,然后选择toggled(bool)作为信号,选择setVisible(bool)作为槽。 默认情况下,setVisible(bool)槽不会显示在Qt设计师的槽列表中,但如果选中了“显示从QWidget继承的信号和槽”选项,就可以看到这个槽了。
18、第四个也是最后一个要建立的连接是moreButton按钮的toggled( bool)信号和tertiaryGroupBox群组框的setVisible(bool)槽之间的连接。这些连接一旦完成,就可以单击编辑->Edit Widgets而离开创建连接模式。
sortdialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SortDialog</class>
<widget class="QDialog" name="SortDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>336</width>
<height>363</height>
</rect>
</property>
<property name="windowTitle">
<string>Sort</string>
</property>
<layout class="QGridLayout" name="layout">
<item row="0" column="0">
<widget class="QGroupBox" name="primaryGroupBox">
<property name="title">
<string>&Primary Key</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Column:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="primaryColumnCombo">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>28</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="primaryOrderCombo">
<item>
<property name="text">
<string>Ascending</string>
</property>
</item>
<item>
<property name="text">
<string>Descending</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Order:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="okButton">
<property name="text">
<string>OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="moreButton">
<property name="text">
<string>More</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="secondaryGroupBox">
<property name="title">
<string>&Secondary Key</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Column:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="secondaryColumnCombo">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>28</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Order:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="secondaryOrderCombo">
<item>
<property name="text">
<string>Ascending</string>
</property>
</item>
<item>
<property name="text">
<string>Descending</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="tertiaryGroupBox">
<property name="title">
<string>&Tertiary Key</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Column:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="tertiaryColumnCombo">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>28</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Order:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="tertiaryOrderCombo">
<item>
<property name="text">
<string>Ascending</string>
</property>
</item>
<item>
<property name="text">
<string>Descending</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>SortDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>258</x>
<y>31</y>
</hint>
<hint type="destinationlabel">
<x>112</x>
<y>137</y>
</hint>
</hints>
</connection>
<connection>
<sender>cancelButton</sender>
<signal>clicked()</signal>
<receiver>SortDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>283</x>
<y>65</y>
</hint>
<hint type="destinationlabel">
<x>167</x>
<y>152</y>
</hint>
</hints>
</connection>
<connection>
<sender>moreButton</sender>
<signal>toggled(bool)</signal>
<receiver>secondaryGroupBox</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>259</x>
<y>183</y>
</hint>
<hint type="destinationlabel">
<x>205</x>
<y>248</y>
</hint>
</hints>
</connection>
<connection>
<sender>moreButton</sender>
<signal>toggled(bool)</signal>
<receiver>tertiaryGroupBox</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>182</y>
</hint>
<hint type="destinationlabel">
<x>206</x>
<y>340</y>
</hint>
</hints>
</connection>
</connections>
</ui>
SortDialog.h
#ifndef SORTDIALOG_H
#define SORTDIALOG_H
#include <QDialog>
namespace Ui {
class SortDialog;
}
class SortDialog : public QDialog
{
Q_OBJECT
public:
explicit SortDialog(QWidget *parent = 0);
~SortDialog();
void setColumnRange(QChar first, QChar last);
private:
Ui::SortDialog *ui;
};
#endif // SORTDIALOG_H
void setColumnRange(QChar first, QChar last);
根据电子制表软件中选择的列初始化这些组合框的内容,在可选的第二键和第三键的组合框选项中插入了“None”选项。
SortDialog.cpp
#include <QtWidgets>
#include "sortdialog.h"
#include "ui_sortdialog.h"
#include <QDebug>
SortDialog::SortDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SortDialog)
{
ui->setupUi(this);
//构造函数中隐藏了对话框中第二键和第三键这两个部分
ui->secondaryGroupBox->hide();
ui->tertiaryGroupBox->hide();
//这里书上没有修改对话框栅格布局layoutName为layout,直接使用会报错,记得在ui中修改
ui->layout->setSizeConstraint(QLayout::SetFixedSize);
//这样一来,布局就会负责对话框重新定义大小的职责,并且也会在显示或者隐藏子窗口部件的时候自动重新定义这个对话框的大小,从而可以确保对话框总是能以最佳的尺寸显示出来。
setColumnRange('A', 'Z');//组合框中内容设置为A到Z
}
void SortDialog::setColumnRange(QChar first, QChar last)
{
ui->primaryColumnCombo->clear();
ui->secondaryColumnCombo->clear();
ui->tertiaryColumnCombo->clear();
ui->secondaryColumnCombo->addItem(tr("None"));
ui->tertiaryColumnCombo->addItem(tr("None"));
//这里我的ui文件第一次出了问题,不知道错在哪里总是无法实现一致性效果,最后把样例的ui文件拿过来就没问题了。重新做了一遍可能是创建新的群组框时出现了错误
ui->primaryColumnCombo->setMinimumSize(ui->secondaryColumnCombo->sizeHint());
QChar ch = first;
while (ch <= last) {
ui->primaryColumnCombo->addItem(QString(ch));
ui->secondaryColumnCombo->addItem(QString(ch));
ui->tertiaryColumnCombo->addItem(QString(ch));
ch = ch.unicode() + 1;
}
}
SortDialog::~SortDialog()
{
delete ui;
}
构造函数中隐藏了对话框中第二键和第三键这两个部分,把窗体布局(布局名改为layout)的SizeConstraint设置为QLayout::SetFixedSize,这样使用户不能再重新修改这个对话框的窗体大小。这里书上没有修改对话框栅格布局layoutName为layout,直接使用会报错,记得在ui中修改。这样一来,布局就会负责对话框重新定义大小的职责,并且也会在显示或者隐藏子窗口部件的时候自动重新定义这个对话框的大小,从而可以确保对话框总是能以最佳的尺寸显示出来。
sizeHint()函数可以返回布局系统试图认同的"理想"大小。这也解释了为什么不同的窗口部件或者具有不同内容的类似窗口部件通常会被布局系统分配给不同的尺寸大小。对于这些组合框,这里指的是第二键组合框和第三键组合框,由于它们包含了一个”None”选项。所以它们要比只包含了一个单字符项目的主键组合框显得宽一些。为了避免这种不一致性,需要把主键组合框的最小大小设置成第二键组合框的理想大小。
main.cpp
#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();
}