您现在的位置:主页 > 葡京娱乐网上网址 > Qt自定义对话框及调用方法(无师自通)

Qt自定义对话框及调用方法(无师自通)

2019-07-01 22:19

在一个应用程序设计中,为了实现一些特定的功能,必领设计自定义对话框。

自定义对话框的设计一般从 QDialog 继承,并且可以采用UI设计器可视化地设计对话框。对话框的调用一般包括创建对话框、传递数据给对话框、显示对话框获取输入、判断对话框单击按钮的返回类型、获取对话框输入数据等过程。

本节将通过实例 samp6_2 来详细介绍这些原理。图 1 是实例 samp6_2 的主窗口,及其设置表格行列数的对话框。


实例 samp6_2 主窗口及其设置表格行列数的对话框


图 1 实例 samp6_2 主窗口及其设置表格行列数的对话框


主窗口采用 QTableView 和 QStandardltemModel、QltemSelectionModel 构成一个通用的数据表格编辑器,设计了 3 个对话框,分别具有不同的功能,并且展示对话框不同调用方式的特点:

设置表格行列数对话框 QWDialogSize
该对话框每次动态创建,以模态方式显示(必须关闭此对话框才可以返回主窗口操作),对话框关闭后获取返回值,用于设置主窗口的表格行数和列数,并且删除对话框对象,释放内存。

这种对话框创建和调用方式适用于比较简单,不需要从主窗口传递大量数据做初始化的对话框,调用后删除对话框对象可以节约内存。

设置表头标题对话框 QWDialogHeaders
图 2 是设置表格表头标题的对话框,该对话框在父窗口(本例中就是主窗口)存续期间只创建一次,创建时传递表格表头字符串列表给对话框,在对话框里编辑表头标题后,主窗口获取编辑之后的表头标题。


设置表格表头标题对话框


图 2 设置表格表头标题对话框


注意,对话框以模态方式显示,关闭后只是隐藏,并不删除对象,下次再调用时只是打开己创建的对话框对象。

这种创建和调用方式适用于比较复杂的对话框,需要从父窗口传递大量数据做对话框初始化。下次调用时不需要重复初始化,能提高对话框调用速度,但是会一直占用内存,直到父窗口删除时,对话框才从内存中删除。

单元格定位与文字设置对话框QWDialogLocate
图 3 是单元格定位和文字设置对话框,该对话框以非模态方式调用,显示对话框时还可以对主窗口进行操作,对话框只是浮动在窗口上方。在对话框里可以定位主窗口表格的某个单元格 并设置其文字内容,在主窗口上的表格中单击鼠标时,单元格的行号、列号也会更新在对话框中。对话框关闭后将自动删除,释放内存。


浮动于主窗口上方的对话框,可交互操作


图 3 浮动于主窗口上方的对话框,可交互操作


这种对话框适用于主窗口与对话框需要交互操作的情况,例如用于查找和替换操作的对话框。

对话框 QWDialogSize 的创建和使用 创建对话框QWDialogSize 实例主窗口从 QMainWindow 继承,主窗口用一个 QTableView 组件作为界面中心组件,设计几个 Action 用于创建主工具栏按钮。主窗口采用 QStandardItemModel 作为数据模型,QItemSelectionModel 作为选择模型,界面和主窗口 Model/View 结构的设计前面已经讲过,本节不再详述。

在项目主窗口建立后,要创建如图 1 所示的设置表格行列数的对话框,单击 Qt Creator 的菜单项 File->New File or Project,选择 Qt 类别下的 “Qt Designer Form Class”,创建可视化设计的对话框类。在随后出现的向导里,选择窗口模板为 Dialog without Buttons,并设置自定义对话框的类名。

设置创建的对话框类名称为 QWDialogSize,系统自动生成 qwdialogsize.h、qwdialogsize.cpp 和 qwdialogsize.ui 3 个文件。

QWDialogSize 对话框的界面设计在 UI 设计器里进行,放置界面组件并设置好布局。
对话框的调用和返回值 设计 QWDialogSize 对话框的界面时,在上面放置了两个 QPushButton 按钮,并分别命名为 btnOK 和 btnCancel,分别是“确定”和“取消”按钮,用于获取对话框运行时用户的选择。那么,如何获得用户操作的返回值呢?

在信号与槽编辑器里,将 btnOK 的 clicked() 信号与对话框的 accept() 槽关联,将 btnCancel 的 clicked() 信号与对话框的reject()槽关联即可,如图 4 所示。


对话框设计时“确定”和 “取消”按钮的信号与槽关联


图 4 对话框设计时“确定”和 “取消”按钮的信号与槽关联


单击“确定”按钮会执行 accept() 槽(或在代码里调用 accept() 槽函数也是一样的),这会关闭对话框(默认情况下,对话框只是被隐藏,并不被删除),并返回 QDialog::Accepted 作为 exec() 函数的返回值。

单击“取消”按钮会执行 reject() 槽函数,也会关闭对话框,并返回 QDialog::Rejected 作为 exec() 函数的返回值。

完成后的 QWDialogSize 的类完整定义如下: class QWDialogSize : public QDialog { Q_OBJECT public: explicit QWDialogSize(QWidget *parent = 0); ~QWDialogSize(); int rowCount();//获取对话框输入的行数 int columnCount();//获取对话框输入的列数 void setRowColumn(int row, int column); //初始对话框上两个SpinBox的值 private slots: private: Ui::QWDialogSize *ui; }; 在 QWDialogSize 的类定义中定义 3 个 public 函数,用于与对话框调用者的数据交互。因为窗体上的组件都是私有成员,外界不能直接访问界面组件,只能通过接口函数访问。

下面是类的接口函数实现代码。在析构函数中弹出一个消息提示对话框,以便观察对话框是何时被删除的。
QWDialogSize::~QWDialogSize、 { QMessageBox::information (this,"提示","设置表格行列数对话框被删除"); delete ui; } int QWDialogSize::rowCount() { //用于主窗口调用获得行数的输入值 return ui->spinBoxRow->value(); } int QWDialogSize::columnCount() {//用于主窗口调用获得列数的输入值 return ui->spinBoxColumn->value(); } void QWDialogSize::setRowColumn(int row, int column) { //初始化数据显示 ui->spinBoxRow->setValue(row); ui->spinBoxColumn->setValue(column); } 下面是主窗口中的“设置行数列数”工具栏按钮的响应代码,用于创建、显示对话框,并读取对话框上设置的行数、列数。
void MainWindow::on_actTab_SetSize_triggered() { //模态对话框,动态创建,用过后删除 QWDialogSize *dlgTableSize=new QWDialogSize(this); Qt::WindowFlags flags=dlgTableSize->windowFlags(); dlgTableSize->setWindowFlags(flags | Qt::MSWindowsFixedSizeDialogHint); dlgTableSize->setRowColumn(theModel->rowCount(),theModel->columnCount ()); int ret=dlgTableSize->exec () ;// 以模态方式显示对话框 if (ret==QDialog::Accepted) { //OK按钮被按下,获取对话框上的输入,设置行数和列数 int cols=dlgTableSize->columnCount(); theModel->setColumnCount(cols); int rows=dlgTableSize->rowCount(); theModel->setRowCount(rows); } delete dlgTableSize; } 从代码中可以看到,每次单击此工具栏按钮时,对话框都被重新创建。创建后用 QDialog 的 setWindowFlags() 函数将对话框设置为固定大小,然后调用对话框的自定义函数 setRowColumn(),将主窗口数据模型 theModd 的现有的行数和列数显示到对话框上的两个 SpinBox 组件里。

调用对话框的 exec() 函数,以模态显示的方式显示对话框。模态显示方式下,用户只能在对话框上操作,不能操作主窗口,主程序也在此处等待 exec() 函数的返回结果。

当用户单击“确定”按钮关闭对话框后,exec() 返回结果为 QDialogxAccepted,主程序获得此返回结果后,通过对话框的自定义函数 columnCount() 和 rowCount() 获得对话框上新输入的列数和行数,然后设置为数据模型的列数和行数。

最后使用 delete 删除创建的对话框对象,释放内存。所以,关闭对话框时,会出现 QWDialogSize 析构函数里的消息提示对话框。