Qt中的对话框

  对话框是GUI程序和用户进行简短交互的顶层窗口,所谓顶层窗口即始终在主窗口之上显示。QDialog是Qt所有类型的对话框窗口的基类,它继承于QWidget,是一种容器类型组件。

这里写图片描述

  QWidget是所有窗口类的抽象,它也可以生成对话框,但是对话框是常见的窗口组件,若每次要使用对话框,都利用QWidget来生成并设置相关参数,显然十分繁琐。所以Qt为我们封装了另外一个子类QDialog,专门用于生成对话框。

1. 模态和非模态对话框

  对话框归为两大类,即模态对话框于非模态对话框。
  模态对话框(QDialog::exec())
  阻塞型的对话框,显示后无法与父窗口进行交互。如word文档中修改源文件内容后直接关闭窗口弹出的对话框:
这里写图片描述
  非模态对话框(QDialog::show())
  非阻塞型的对话框,显示后还可以与父窗口进行交互。如word文档的替换操作:
这里写图片描述

  模态对话框:
  (1) 定义一个主窗口,窗口内有一个按钮:

//Widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QApplication>
#include <QWidget>
#include <QPushButton>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT            //表要类要使用信号与槽机制
protected:
    QPushButton Btn;    //按钮
protected slots:
    void Btn_Clicked(); //槽,用于响应按钮按下操作
public:
    Widget(QWidget *parent = 0); //parent默认参数为0,表默认是容器类父窗口
    ~Widget();
};

#endif // WIDGET_H

//Widget.cpp
#include "Widget.h"
#include "Dialog.h"

//Widget的构造函数,Btn初始化为其Widget的功能类字子组件
Widget::Widget(QWidget *parent) : QWidget(parent), Btn(this)
{
    Btn.resize(80, 30);
    Btn.move(40, 40);
    Btn.setText("btn");

    resize(240, 100);
    setWindowTitle("hello");
    connect(&Btn, SIGNAL(clicked()), this, SLOT(Btn_Clicked()));
}

Widget::~Widget()
{
}

//Widget内按钮的响应槽,该按钮按下后Winget会弹出对话框(Dialog)
void Widget::Btn_Clicked()
{
    qDebug() << "Btn_Clicked()";
    Dialog d(this);     //Dialog是对话框类,见下
    int ret = d.exec(); //exec()表明d是个模态对话框,用户不操作该对话框,会阻塞于此。
                        //exec()返回对话框的运行结果
    if (ret == Dialog::Accepted)
    {
        qDebug() << "Accepted";
    }
    else if (ret == Dialog::Rejected)
    {
        qDebug() << "Rejected";
    }
}

  (2) 定义一个对话框,框内有两个按钮

//Dialog.h
#ifndef DIALOG_H
#define DIALOG_H

#include <QWidget>
#include <QDebug>
#include <QPushButton>
#include <QtGui/QDialog>

class Dialog : public QDialog
{
    Q_OBJECT
protected:
    QPushButton Btn1;   //对话框内按钮1
    QPushButton Btn2;   //对话框内按钮2
protected slots:
    void Btn1_Clicked();    //按钮1的槽
    void Btn2_Clicked();    //按钮2的槽
public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
};

#endif // DIALOG_H

#include "Dialog.h"

//Dialog类的构造函数,初始化列表指定两个按钮的父窗口都为Dialog
Dialog::Dialog(QWidget *parent) : QDialog(parent), Btn1(this), Btn2(this)
{
    //初始化按钮1
    Btn1.setText("Btn1");
    Btn1.move(20, 20);
    Btn1.resize(100, 30);

    //初始化按钮2
    Btn2.setText("Btn2");
    Btn2.move(140, 20);
    Btn2.resize(100, 30);

    //初始化对话框的大小以及设置其名字
    this->resize(260, 70);
    this->setWindowTitle("Dialog");

    //信号与槽的映射
    connect(&Btn1, SIGNAL(clicked()), this, SLOT(Btn1_Clicked()));
    connect(&Btn2, SIGNAL(clicked()), this, SLOT(Btn2_Clicked()));
}

Dialog::~Dialog()
{    
}

//按钮1的槽
void Dialog::Btn1_Clicked()
{
    qDebug() << "Btn1_Clicked()";
    done(Accepted);
}

//按钮2的槽
void Dialog::Btn2_Clicked()
{
    qDebug() << "Btn2_Clicked()";
    done(Rejected);
}

  (3) main函数

//main.cpp
#include "Dialog.h"
#include "Widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    w.show();

    return a.exec();
}

  只有模态对话框才有返回值的概念,返回值用于表示对话框和用户的交互结果。函数:

void QDialog::done(int);

  用于关闭对话框并将参数i作为与用户的交互结果,发回给exec()的调用处。i的取值可为Accepted、Rejected或其其他int型数据,Accepted、Rejected是在QDialog类中定义的枚举类型,前者表示用户操作成功,后者表示操作失败。

  非模态对话框:
  在栈中创建模态对话框是常用的方式,而非模态对话框由于其显示函数是非阻塞的,所以需要在堆中创建。Widget::Btn_Clicked()函数改写为:

void Widget::Btn_Clicked()
{
    qDebug() << "Btn_Clicked()";

    Dialog* d = new Dialog();
    d->setAttribute(Qt::WA_DeleteOnClose);
    d->show();

    qDebug() << "Btn_Clicked() exit!";
}

  show()函数是非阻塞的,对话框Dialog对象d若是在栈中生成那函数退出后对话框也随之消失,所以非模态对话框需在堆中动态生成,这样该函数退出后对话框仍能显示,但是却也出现了新的问题:指针d执行动态生成的空间,一旦该函数退出后,d指针将失效,这也就意味着其他函数无法释放该堆空间,造成内存泄漏。因此Qt提供了“对话框被用户关闭后就释放给对话框占据的堆空间”的操作:

d->setAttribute(Qt::WA_DeleteOnClose);

  Qt对话框的模态/非模态是通过对话框的属性变量modal确定的,modal是个bool类型的变量,默认情况下是false,即非模态,所以调用show()函数显示对话框时是非模态的;调用exec()函数显示时,它将忽略modal的属性值的设置并将对话框设置为模态对话框。

  除了模态、非模态,还有一种混合特性的对话框,即通过QDialog::setModal()函数设置modal变量为true,那么该对话框将变成:对话框在堆中分配,同时用show()显示的前提下,同时又是模态对话框。

QDialog* dialog = new QDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
dialog->show();

2. Qt中定义的常用对话框

  Qt提供了一些可复用的常用对话框类,这些类都继承自QDialog类,有描述提示型消息的QMessageBox、描述文件相关的QFileDialog、描述打印机选择的QPrintDialog,描述颜色选择的QColorDialog等等。

  对于这些对话框类的使用,都遵循如下规则:

//1. 定义对话框
Dialogxxx d(this);

//2. 设置对话框属性,如对话框标题、文字显示
d.setxxx(xxx);

//3. 判断对话框被用户操作后的返回值,
if (d.exec() == Dialogxxx::xxx)
{
    //执行相关操作
}

  下面是上述Qt实现好的对话框类的使用,它们定义在Widget类型的父类窗口类中的按钮槽函数中。

2.1 消息对话框

  消息对话框主要用于为用户提示消息,强制用户进行选择:

//提示用户消息
#include <QMessageBox>

//强制用户选择
QMessageBox msg(this);              //创建对话框
msg.setWindowTitle("xxxx");         //设置对话框标题
msg.setText("customMsgBtnClicked"); //设置对话框的提示信息
msg.setIcon(QMessageBox::Warning);  //设置对话框的图标
//设置对话框的按钮
msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::YesToAll);  

QMessageBox msg(this);
msg.setText("this is a message dialog!");
msg.exec();

  运行结果:
这里写图片描述

2.2 文件对话框

  在GUI程序中,打开文件和保存文件的时候都会弹出对话框,

//GUI程序要打开系统上的文件
#include <QFileDialog>

QFileDialog d(this);                        //创建对话框
d.setAcceptMode(QFileDialog::AcceptOpen);   //设置该对话框的模式为打开
d.setFileMode(QFileDialog::ExistingFiles);  //选择打开的是文件,ExistingFiles表可选择多文件,
                                            //ExistingFile则表示只能选择一个文件,目录则是QFileDialog::Directory
d.setFilter("TEXT(*.txt)");                 //以文件格式过滤掉文件

if (d.exec() == QFileDialog::Accepted)      //执行成功
{
    QStringList fs = d.selectedFiles();     //打印用户选择的结果

    for (int i = 0; i < fs.count(); i++)
    {
        qDebug() << fs[i];
    }
}

  运行结果:
这里写图片描述

//GUI程序要保存文件
QFileDialog d(this);
d.setAcceptMode(QFileDialog::AcceptSave);
//d.setFilter("c(*.c)");

if (d.exec() == QFileDialog::Accepted)
{
    QStringList fs = d.selectedFiles();

    for (int i = 0; i < fs.count(); i++)
    {
        qDebug() << fs[i];
    }
}

  运行:
这里写图片描述

2.3 颜色对话框
#include <QColorDialog>
QColorDialog d(this);
d.setWindowTitle("color editor");

if (d.exec() == QColorDialog::Accepted)
{
    QColor color = d.selectedColor();
    qDebug() << color;
    qDebug() << color.red();
    qDebug() << color.green();
    qDebug() << color.blue();
}

  运行:
这里写图片描述

  setCurrentColor()函数用于设置当前的颜色值:

d.setCurrentColor(QColor(100, 100, 100));

  QColor类用于表现颜色值,该类有一个构造函数:

QColor ( int r, int g, int b, int a = 255 )
2.4 输入对话框

  输入对话框QInputDialog类,用于需要临时进行数据输入的场合:

QInputDialog d(this);
d.setWindowTitle("input dat");
d.setLabelText("ple input dat");
d.setInputMode(QInputDialog::IntInput);  //TextInput输入文本,DoubleInput输入double类型
if (d.exec() == QInputDialog::Accepted)
    qDebug() << d.intValue();           //TextValue、doubleValue

  运行:
这里写图片描述

2.5 字体对话框

  QFontDialog类用于选择字体的对话框:

#include <QFontDialog>
QFontDialog f(this);
f.setWindowTitle("font select");
f.setCurrentFont(QFont(QFont("gargi", 10, QFont::Bold)));   //设置弹出的对话框的选择的字体

if (f.exec() == QFontDialog::Accepted)
{
    qDebug() << f.selectedFont();
}

运行:
这里写图片描述

2.6 进度对话框

  QProgressDialog类用于显示进度信息,不需要判断exec()函数的返回值:

#include <QProgressDialog>
QProgressDialog d(this);
d.setWindowTitle("load");

//设置范围值
d.setMinimum(0);
d.setMaximum(100);

//设置进度数值
d.setValue(96);

//设置提示信息
d.setLabelText("xxxxxxxx");

d.exec();

运行:
这里写图片描述

2.7 打印对话框

  QPrinter类封装了打印设备驱动及其参数,利用该类尅以相同的方式使用系统的不同的打印设备打印。

#include <QPrintDialog>
#include <QTextDocument>
#include <QPrinter>

QPrintDialog d(this);
d.setWindowTitle("print test");

if (d.exec() == QPrintDialog::Accepted)
{
    QPrinter *p = d.printer();
    QTextDocument td;

    //可以通过打印机打印,这里是打印到文本文件
    td.setPlainText("print test!!");    //待打印的文本
    p->setOutputFileName("./tt.txt");   //打印到此文件
    td.print(p);
}

运行:
这里写图片描述

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值