• 第二章 创建对话框


    1、子类化QDialog

    第一个例子是完全使用C++编写的Find对话框。

    finddialog.h:

     1 #ifndef FINDDIALOG_H
     2 #define FINDDIALOG_H
     3 
     4 #include <QDialog>
     5 
     6 class QCheckBox;
     7 class QLabel;
     8 class QLineEdit;
     9 class QPushButton;
    10 
    11 class FindDialog : public QDialog
    12 {
    13     Q_OBJECT
    14 public:
    15     FindDialog(QWidget *parent = 0);
    16 signals:
    17     void findNext(const QString &str, Qt::CaseSensitivity cs);
    18     void findPrevious(const QString &str, Qt::CaseSensitivity cs);
    19 private slots:
    20     void findClicked();
    21     void enableFindButton(const QString &text);
    22 private:
    23     QLabel *label;
    24     QLineEdit *lineEdit;
    25     QCheckBox *caseCheckBox;
    26     QCheckBox *backwardCheckBox;
    27     QPushButton *findButton;
    28     QPushButton *closeButton;
    29 };
    30 
    31 #endif // FINDDIALOG_H

    头部的预编译指令是为了防止对这个头文件的多重包含

    对于定义了信号与槽的类来说在类定义的开始处的Q_OBJECT宏都是必须的,它给出了一些函数的声明

    FindDialog类的构造函数是典型的Qt窗口部件类的定义方式。parent参数指定了它的父窗口部件。该参数的默认值是一个空指针,意味着该对话框没有父对象。

    signals关键字实际上是一个宏,C++预处理器会在编译程序找到它之前把它转换成标准C++代码。我的疑问是为什么槽的声明是私有的

    finddialog.cpp:

     1 #include <QtGui>
     2 #include <QLabel>
     3 #include <QCheckBox>
     4 #include <QLineEdit>
     5 #include <QPushButton>
     6 #include <QHBoxLayout>
     7 #include <QVBoxLayout>
     8 #include "finddialog.h"
     9 
    10 FindDialog::FindDialog(QWidget *parent)
    11     :QDialog(parent)
    12 {
    13     label = new QLabel(tr("Find &what:"));
    14     lineEdit = new QLineEdit;
    15     label->setBuddy(lineEdit);
    16 
    17     caseCheckBox = new QCheckBox(tr("Match &case"));
    18     backwardCheckBox = new QCheckBox(tr("Search &backward"));
    19 
    20     findButton = new QPushButton(tr("&Find"));
    21     findButton->setDefault(true);
    22     findButton->setEnabled(false);
    23 
    24     closeButton = new QPushButton("Close");
    25     connect(lineEdit, SIGNAL(textChanged(const QString &)),
    26             this, SLOT(enableFindButton(const QString &)));
    27     connect(findButton, SIGNAL(clicked()),
    28             this, SLOT(findClicked()));
    29     connect(closeButton, SIGNAL(clicked()),
    30             this, SLOT(close()));
    31 
    32     QHBoxLayout *topLeftLayout = new QHBoxLayout;
    33     topLeftLayout->addWidget(label);
    34     topLeftLayout->addWidget(lineEdit);
    35 
    36     QVBoxLayout *leftLayout = new QVBoxLayout;
    37     leftLayout->addLayout(topLeftLayout);
    38     leftLayout->addWidget(caseCheckBox);
    39     leftLayout->addWidget(backwardCheckBox);
    40 
    41     QVBoxLayout *rightLayout = new QVBoxLayout;
    42     rightLayout->addWidget(findButton);
    43     rightLayout->addWidget(closeButton);
    44     rightLayout->addStretch();
    45 
    46     QHBoxLayout *mainLayout = new QHBoxLayout;
    47     mainLayout->addLayout(leftLayout);
    48     mainLayout->addLayout(rightLayout);
    49     setLayout(mainLayout);
    50 
    51     setWindowTitle(tr("Find"));
    52     setFixedHeight(sizeHint().height());
    53 }
    54 
    55 void FindDialog::findClicked()
    56 {
    57     QString text = lineEdit->text();
    58     Qt::CaseSensitivity cs =
    59             caseCheckBox->isChecked() ? Qt::CaseSensitive
    60                                       : Qt::CaseInsensitive;
    61     if(backwardCheckBox->isChecked())
    62     {
    63         emit findPrevious(text, cs);
    64     }
    65     else
    66     {
    67         emit findNext(text, cs);
    68     }
    69 }
    70 
    71 void FindDialog::enableFindButton(const QString &text)
    72 {
    73     findButton->setEnabled(!text.isEmpty());
    74 }

    在字符串周围的tr函数调用时把它们翻译成其他语言的标记,即使现在没有需要将程序翻译成其它语言,但是这样做也是有好处的。

    在部件的text字符创中使用了符号“&”表示快捷键,使用alt+“&”后的第一个字母可以实现快捷的选中该部件。

    所谓buddy,就是一个窗口部件,它可以再按下标签的快捷键时接受焦点输入。

    setDefault让Find按钮称为默认按钮,默认按钮即当用户按下回车时能够按下对应的键。

    omit是Qt中的关键字,它会被C++预处理器转换成标准C++代码。

    main.cpp:

     1 #include <QApplication>
     2 #include "finddialog.h"
     3 
     4 int main(int argc, char** argv)
     5 {
     6     QApplication app(argc, argv);
     7     FindDialog *dialog = new FindDialog;
     8     dialog->show();
     9     return app.exec();
    10 }

    运行效果:

    2、深入介绍槽与信号

    信号与槽是Qt编程的基础。它可以让编程人员将这些互不了解的对象绑定在一起。

    槽和普通的C++函数几乎是一样的,可以使虚函数、可以被重载、可以使公有的、保护的、私有的。并且也可以被其他C++成员函数直接调用,还有它们的参数可以使任意类型,唯一不同的是:槽还可以和信号连接在一起,在这种情况下,每当发射这个信号的时候,就会自动调用这个槽。

    connect(sender, SIGNAL(signal), receiver,SLOT(slot));

    这里的sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名。实际上,SIGNAL和SLOT宏会把它们的参数转换成相应的字符串。

    • 一个信号可以连接多个槽

    在发射这个信号的时候会以不确定的顺序一个接一个的调用这些槽

    • 多个信号可以连接同一个槽

    无论发射哪一个信号都会调用这个槽

    • 一个信号可以与另外一个信号连接

    当发射第一个信号的时候也会发射第二个信号

    • 连接可以被移除

    这种情况很少用

    注意:要把信号连接到槽,它们的参数必须具有相同的顺序和相同的类型。例外:如果信号比连接的槽的参数多,那么后面多余的参数将被忽略。

    3、快速设计对话框

    这一节会使用Qt Designer来可视化的设计一个对话框。

    操作步骤就是使用Qt Designer来设计需要的对话框,然后保存为.ui的格式。

    在编译的时候会将.ui格式的文件转换为C++并且存储在ui_name.h和ui_name.cpp中。

    生成的类没有任何基类,当在程序中使用它时,可以创建一个QDialog类的对象,然后把它传递给setupUi()函数。

    现在定义一个新的类继承自QDialog和Ui::GoToCellDialog类(我填写的Ui文件生成的类名)。

    gotocelldialog.h:

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

    该类继承自两个类:QDialog、Ui::GoToCellDialog

    gotocelldialog.cpp:

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

    实现文件中绑定了需要绑定的信号与槽。

    对编辑框的输入进行了验证,使用正则表达式的方法来验证。

    accept()槽可以讲对话框返回的结果变量设置为QDialog::Accepted,其值为1、而reject()槽会把对话框的值设置为QDialog::Rejected,其值为0。可以根据对话框的返回值来判断是否点击了OK按钮。

    main.cpp:

     1 #include <QApplication>
     2 
     3 #include "gotocelldialog.h"
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     QApplication a(argc, argv);
     8 
     9     GotoCellDialog *dialog = new GotoCellDialog;
    10     dialog->show();
    11 
    12     return a.exec();
    13 }

    实例化一个该类的对象并显示出来。

    使用QDialogButtonBox来制作这个对话框,以使它在MAC平台上显得更加圆润。

    4、

  • 相关阅读:
    前端学习笔记之闭包——看了一张图终于明白啥是闭包了
    前端学习笔记之闭包——看了一张图终于明白啥是闭包了
    前端学习笔记之闭包——看了一张图终于明白啥是闭包了
    前端学习笔记之闭包——看了一张图终于明白啥是闭包了
    Unity碰撞检测
    Unity碰撞检测
    Unity碰撞检测
    Unity碰撞检测
    关于JavaScript中事件的一些重要说明
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/lit10050528/p/3872811.html
Copyright © 2020-2023  润新知