第二章 创建对话框

这篇博客介绍了如何在Qt中创建和自定义对话框,包括子类化QDialog、理解信号槽机制、使用Qt Designer以及实现特殊形状的对话框。内容涵盖从基本的头文件编写到UI设计,适合Qt初学者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习过程中的笔记,用于分享和自己以后查看复习,不免会遇到错误欢迎指正。

一、子类化QDialog

先上代码

finddialog.h

#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include <QDialog>
#include <QLabel>
#include <QCheckBox>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>

class FindDialog : public QDialog
{
    Q_OBJECT

public:
    FindDialog(QWidget *parent = 0);

signals:
    void findNext(const QString &str, Qt::CaseSensitivity cs);
    void findPrevious(const QString &str, Qt::CaseSensitivity cs);

private slots:
    void findClicked();
    void enableFindButton(const QString &text);

private:
    QLabel *label;
    QLineEdit *lineEdit;
    QCheckBox *caseCheckBox;
    QCheckBox *backwardCheckBox;
    QPushButton *findButton;
    QPushButton *closeButton;
};
#endif
宏    Q_OBJECT
如果需要使用自己定义的信号槽那么就必须要这个宏定义,放在类定义的开始处。

signals:
private slots:

就是类中对自己定义的信号槽的说明,同时他也可以作为普通的函数使用,不一定非要用做信号槽。

Qt::CaseSensitivity
enum CaseSensitivity {CaseInsensitive, CaseSensitive };
是一个枚举类型,他的意思是是否区分大小写,用的好像不多诶,也就这里看到过。


finddialog.cpp
#include <QtGui>
#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent)
    : QDialog(parent)
{
    label = new QLabel(tr("Find &what:"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

    caseCheckBox = new QCheckBox(tr("Match &case"));
    backwardCheckBox = new QCheckBox(tr("Search &backward"));

    findButton = new QPushButton(tr("&Find"));
    findButton->setDefault(true);
    findButton->setEnabled(false);

    closeButton = new QPushButton(tr("Close"));

    connect(lineEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(enableFindButton(const QString &)));
    connect(findButton, SIGNAL(clicked()),
            this, SLOT(findClicked()));
    connect(closeButton, SIGNAL(clicked()),
            this, SLOT(close()));

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    Qt::CaseSensitivity cs =
            caseCheckBox->isChecked() ? Qt::CaseSensitive
                                      : Qt::CaseInsensitive;
    if (backwardCheckBox->isChecked()) {
        emit findPrevious(text, cs);
    } else {
        emit findNext(text, cs);
    }
}

void FindDialog::enableFindButton(const QString &text)
{
    findButton->setEnabled(!text.isEmpty());
}

label = new QLabel(tr("Find &what:"));
在字符串周围使用tr()函数调用是把它们翻译成其他语言的标记,在可见字符串周围使用它是个好习惯,后面翻译和国际化会在谈到。
在字符串内使用‘&’来表示快捷键,该符号可以用来控制焦点。

emit findPrevious(text, cs);
emit是Qt的关键字,可以在需要的时候发送自定义的信号,会被C++预处理器转换成标准的C++代码,据说这个宏定义只是给人看的,会被编译器忽略诶。?

main.cpp
#include <QApplication>
#include "finddialog.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    FindDialog *dialog = new FindDialog;
    dialog->show();
    return app.exec();
}

main里面就不说了,一个类的使用而已。


二、信号槽解析

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

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

一个信号可以连接另一个信号;

链接可以移除(比较少用,因为删除对象时会自动移除所有连接);


自定义信号槽需要Q_OBJECT这个宏哦~

Qt的moc工具用于生成Q_OBJECT声明的所有信号槽的实现。

其实,不需要管里面是怎么实现的,用就对了!


三、Qt Designer的使用

设计师的使用还是看书吧,操作比较简单,关键是属性的设计和美工样式表咯。

设计师的.ui文件是一种基于XML的文件格式,在工程中是可以看到设计师生成的C++的代码的。如果不会用代码画控件,可以用设计师设计后看代码是怎么做的 。


四、改变形状的对话框

主要有 扩展对话框和多页对话框,代码和设计师都能实现。

效果图:


ui布局如下



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

#include <QtGui>
#include "sortdialog.h"

SortDialog::SortDialog(QWidget *parent)
    : QDialog(parent)
{
    setupUi(this);
    secondaryGroupBox->hide();
    tertiaryGroupBox->hide();
    layout()->setSizeConstraint(QLayout::SetFixedSize);
    setColumnRange('A', 'Z');
}

void SortDialog::setColumnRange(QChar first, QChar last)
{
    primaryColumnCombo->clear();
    secondaryColumnCombo->clear();
    tertiaryColumnCombo->clear();

    secondaryColumnCombo->addItem(tr("None"));
    tertiaryColumnCombo->addItem(tr("None"));

    primaryColumnCombo->setMinimumSize(
            secondaryColumnCombo->sizeHint());

    QChar ch = first;
    while (ch <= last) {
        primaryColumnCombo->addItem(QString(ch));
        secondaryColumnCombo->addItem(QString(ch));
        tertiaryColumnCombo->addItem(QString(ch));
        ch = ch.unicode() + 1;
    }
}

 setupUi(this);
用了ui的都要在构造里setupUi哦 ~~~
构造函数隐藏了对话框的第二键和第三键两个部分。

而且

layout()->setSizeConstraint(QLayout::SetFixedSize);
这就设置了用户不能手动修改窗口大小,大小只会随着布局内容变化而改变,也就实现了窗口的动态变化。


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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值