Qt例子:对话框

这是《C GUI Qt4编程》第二版中的一个例子(P18~P22),实现了一个对话框:当文本框中输入合适的字符串,OK按钮会自动使能,如下图所示。书中的做法对于初学者来说不是太清晰,我完全按照例子却没有让OK按钮奏效。本文是该例子的一个梳理。

        

开发环境:1. Win7 + Qt Creator

     2. Ubuntu12.04 + Qt Creator

本文是在Win7下建立空项目,先用设计器划出图,逐步添加各种文件。Ubuntu下则是直接拷贝了cpp,h和ui文件,用命令qmake -project生成pro项目文件,再qmake gotocell.pro生成Makefile,最后make生成目标文件和可执行文件。

Windows下的开发步骤:

1. 在“编辑”空白区单击右键——>新建项目——>其他项目——>空的Qt项目——>命名gotocell,则自动生出gotocell.pro文件

2. 在项目目录上单击右键——>添加新文件——>Qt——>Qt设计师界面类——>Dialog without Buttons——>命名gotocelldialog.ui

3. 将该Dialog对象命名为GoToCellDialog,拖放Label,LineEdit,2个Pushbutton,并在属性栏里改名,将objectName的值依次改为label,lineEdit,okButton,cancelButton,将Text改为&Cell Location:,OK,Cancel,将label,lineEdit,cancelButton勾选enabled

4. 单击界面上的Cell Location:并按下Ctrl再单击输入框以便同时选中这2个控件,点击下图红框里的“编辑伙伴”,这样当按快捷键Ctrl+C时,输入框会自动获得焦点

5. 以Ctrl的方法,同时选中Cell Location和输入框,点击下图红框里的“水平布局”,使二者在同一水平线上。对OK和Cancel也“水平布局”

6. 单击窗体中的空白使整个大框选中,点击“垂直布局”

7. 点击“调整大小”,自由调整整个对话框大小

8. 点击“编辑Tab顺序”,则在每个可接受焦点的控件上出现带蓝色巨型的数字,按照所想顺序单击每个控件,可调整Tab顺序。到此为止界面就完成了。

9. 在项目目录上单击右键——>添加新文件——>C++——>C++源文件——>命名为main.cpp,代码如下所示,去掉7,15行,去掉第6,12,13,14行注释

 1 //main.cpp
 2 
 3 #include <QApplication>
 4 #include <QDialog>
 5 
 6 //#include "ui_gotocelldialog.h"
 7 #include "gotocelldialog.h"
 8 
 9 int main(int argc, char *argv[])
10 {
11     QApplication app(argc, argv);
12     //Ui::GoToCellDialog ui;
13     //QDialog *dialog = new QDialog;
14     //ui.setupUi(dialog);
15     GoToCellDialog *dialog = new GoToCellDialog;
16     dialog->show();
17 
18     return app.exec();
19 }

10. 点击“运行”,则自动生成文件ui_gotocelldialog.h,内容如下所示:

  1 /********************************************************************************
  2 ** Form generated from reading UI file 'gotocelldialog.ui'
  3 **
  4 ** Created: Mon Aug 20 00:22:30 2012
  5 **      by: Qt User Interface Compiler version 4.8.1
  6 **
  7 ** WARNING! All changes made in this file will be lost when recompiling UI file!
  8 ********************************************************************************/
  9 
 10 #ifndef UI_GOTOCELLDIALOG_H
 11 #define UI_GOTOCELLDIALOG_H
 12 
 13 #include <QtCore/QVariant>
 14 #include <QtGui/QAction>
 15 #include <QtGui/QApplication>
 16 #include <QtGui/QButtonGroup>
 17 #include <QtGui/QDialog>
 18 #include <QtGui/QHBoxLayout>
 19 #include <QtGui/QHeaderView>
 20 #include <QtGui/QLabel>
 21 #include <QtGui/QLineEdit>
 22 #include <QtGui/QPushButton>
 23 #include <QtGui/QSpacerItem>
 24 #include <QtGui/QVBoxLayout>
 25 
 26 QT_BEGIN_NAMESPACE
 27 
 28 class Ui_GoToCellDialog
 29 {
 30 public:
 31     QVBoxLayout *verticalLayout;
 32     QHBoxLayout *horizontalLayout;
 33     QLabel *label;
 34     QLineEdit *lineEdit;
 35     QHBoxLayout *horizontalLayout_2;
 36     QSpacerItem *horizontalSpacer;
 37     QPushButton *okButton;
 38     QPushButton *cancelButton;
 39 
 40     void setupUi(QDialog *GoToCellDialog)
 41     {
 42         if (GoToCellDialog->objectName().isEmpty())
 43             GoToCellDialog->setObjectName(QString::fromUtf8("GoToCellDialog"));
 44         GoToCellDialog->resize(310, 119);
 45         verticalLayout = new QVBoxLayout(GoToCellDialog);
 46         verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
 47         horizontalLayout = new QHBoxLayout();
 48         horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
 49         label = new QLabel(GoToCellDialog);
 50         label->setObjectName(QString::fromUtf8("label"));
 51 
 52         horizontalLayout->addWidget(label);
 53 
 54         lineEdit = new QLineEdit(GoToCellDialog);
 55         lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
 56 
 57         horizontalLayout->addWidget(lineEdit);
 58 
 59 
 60         verticalLayout->addLayout(horizontalLayout);
 61 
 62         horizontalLayout_2 = new QHBoxLayout();
 63         horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
 64         horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
 65 
 66         horizontalLayout_2->addItem(horizontalSpacer);
 67 
 68         okButton = new QPushButton(GoToCellDialog);
 69         okButton->setObjectName(QString::fromUtf8("okButton"));
 70         okButton->setEnabled(false);
 71         okButton->setDefault(true);
 72 
 73         horizontalLayout_2->addWidget(okButton);
 74 
 75         cancelButton = new QPushButton(GoToCellDialog);
 76         cancelButton->setObjectName(QString::fromUtf8("cancelButton"));
 77 
 78         horizontalLayout_2->addWidget(cancelButton);
 79 
 80 
 81         verticalLayout->addLayout(horizontalLayout_2);
 82 
 83 #ifndef QT_NO_SHORTCUT
 84         label->setBuddy(lineEdit);
 85 #endif // QT_NO_SHORTCUT
 86 
 87         retranslateUi(GoToCellDialog);
 88 
 89         QMetaObject::connectSlotsByName(GoToCellDialog);
 90     } // setupUi
 91 
 92     void retranslateUi(QDialog *GoToCellDialog)
 93     {
 94         GoToCellDialog->setWindowTitle(QApplication::translate("GoToCellDialog", "Go to Cell", 0, QApplication::UnicodeUTF8));
 95         label->setText(QApplication::translate("GoToCellDialog", "&Cell Location:", 0, QApplication::UnicodeUTF8));
 96         okButton->setText(QApplication::translate("GoToCellDialog", "OK", 0, QApplication::UnicodeUTF8));
 97         cancelButton->setText(QApplication::translate("GoToCellDialog", "Cancel", 0, QApplication::UnicodeUTF8));
 98     } // retranslateUi
 99 
100 };
101 
102 namespace Ui {
103     class GoToCellDialog: public Ui_GoToCellDialog {};
104 } // namespace Ui
105 
106 QT_END_NAMESPACE
107 
108 #endif // UI_GOTOCELLDIALOG_H

现在运行程序,出现的对话框可以工作,但是没有想要的功能:OK失效,Cancel什么都做不了,输入框可接受任何文本。

要想让对话框具有适当的工呢个,最简捷的作法是创建一个新类,让该类同时从QDialog和Ui::GoToCellDialog中继承,由它来实现缺失的功能。命名惯例是将该类与uic所生成的类具有相同的名字,没有Ui前缀。

11. 在项目目录上单击右键——>添加新文件——>C++——>C++头文件——>命名为gotocelldialog.h,代码如下所示

 1 //gotocelldialog.h
 2 
 3 #ifndef GOTOCELLDIALOG_H
 4 #define GOTOCELLDIALOG_H
 5 
 6 #include <QDialog>
 7 #include "ui_gotocelldialog.h"
 8 
 9 class GoToCellDialog : public QDialog, public Ui::GoToCellDialog
10 {
11     Q_OBJECT
12 public:
13     GoToCellDialog(QWidget *parent = 0);
14 private slots:
15     void on_lineEidt_textChanged();
16 };
17 
18 #endif // GOTOCELLDIALOG_H

12. 在项目目录上单击右键——>添加新文件——>C++——>C++源文件——>命名为gotocelldialog.cpp,代码如下所示

 1 //gotocelldialog.cpp
 2 
 3 #include <QtGui>
 4 #include "gotocelldialog.h"
 5 
 6 GoToCellDialog::GoToCellDialog(QWidget *parent) : QDialog(parent)
 7 {
 8     setupUi(this);
 9     QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
10     lineEdit->setValidator(new QRegExpValidator(regExp, this));
11 
12     //connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
13     //connect(okButton, SIGNAL(clicked()), this, SLOT(on_lineEidt_textChanged()));
14     connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(on_lineEidt_textChanged()));
15     connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
16 }
17 
18 void GoToCellDialog::on_lineEidt_textChanged()
19 {
20     okButton->setEnabled(lineEdit->hasAcceptableInput());
21 }

代码注解:

setupUi()初始化窗体,由于使用了多重继承,可一直直接访问Ui::GoToCellDialog中的成员。创建了用户接口后,setupUi()还会自动将符合on_objectName_signalName()命名惯例的任意槽与相应的objectName的signalName()信号连接到一起。本例中意味着setuoUi()将建立如下所示的信号槽连接关系:

connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(on_lineEidt_textChanged()));

Qt有3个内置检验器类:QIntValidator,QDoubleValidator,QRegExpValidator。代码QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");的意思是允许一个大写或小写字母,后面跟着一个范围为1-9的数字,后面再跟0个、1个或2个0-9的数字。

13. 重写main.cpp,如第一段代码所示。

按照书上的方法,注释掉gotocelldialog.cpp里的14和13行,去掉12行注释,则正确输入后OK还是不起作用。书上的说法:accept()和reject()这两个槽都可以关闭对话框,但accept()槽可以讲对话框返回的结果变量设置为QDialog::Accepted(其值等于1),reject()槽会把对话框的值设置为QDialog::Rejected(其值等于0),当使用这个对话框的时候,可以利用这个结果变量判断客户是否单击了OK按钮从而执行相应的动作。

原文地址:https://www.cnblogs.com/qyddbear/p/2647305.html