第 5 章 主窗口及对话框

5.1 主窗口区域划分

QMainWindow是Qt框架带来的一个预定义的主窗口类。所谓主窗口,就是一个普通意义上的应用程序最顶层的窗口。例如对于浏览器而言,主窗口就是这个浏览器窗口。回想一下,经典的主窗口通常由一个标题栏、一个菜单栏、若干工具栏等组成。在这些子组件之间则是用户的工作区。事实上QMainWindow正式这样的一种布局。
        参看上图,主窗口的最上面是Window Title,也就是标题栏,通常用于显示标题和控制按钮,例如最大化、最小化和关闭等。通常,各个图形界面框架都会使用操作系统本地代码来生成一个窗口。所以在Windows平台上,标题栏是Windows风格的。如果你不喜欢本地样式,例如你希望使用QQ这种标题栏,则需要自己将标题栏绘制出来,这种技术称为DirectUI,也就是无句柄绘制,这不在本书的讨论范围内。Window Title下面是Menu Bar,也就是菜单栏,用于显示菜单。穿户口最底部是Status Bar,称为状态栏。当鼠标划过某些组件时,可以在状态栏显示某些信息,例如浏览器中,鼠标滑过带有链接的文字,会在底部看到连接的实际URL地址。
        除去上面说的区域,中间部分以矩形区域表示。可以看出,最外层称为Tool Bar Area,用于显示工具条区域,之所以用矩形表示,是因为Qt的主窗口支持多个工具条,同时可以将工具条拖放到不同的位置,因此这里说的是Area。可以把几个工具条并排显示在上部,也可以将其分别放置(例如一个考上,一个靠右)。在工具条内部是Dock Widget Area,这是停靠窗口的显示区域。所谓停靠窗口,就像Photoshop、AutoCAD的工具箱一样,可以停留在主窗口的四周,也可以浮动显示。主窗口最中间称为Centerl Widget,就是程序的工具去,通常会将程序最主要的工作区域放置在这里,类似于Word的稿纸等。
        对于一般的Qt应用程序,我们所需要做的就是编写主窗口代码,主要是向其中添加各种组件,例如菜单、工具栏等,当然最重要的就是在工作去处理我们的任务。
        通常程序的主串口会继承自QMainWindow,以便获得QMainWindow提供的各种便利的函数。这也是选择QMainWindow为基类时Qt Creator向导生成的代码所做的工作。

5.2 菜单、工具栏和状态栏

        Qt有菜单类,但是没有专门的菜单类,只是使用QAction类抽象出公共的动作,这些动作可以代表菜单项、工具栏按钮或者快捷键命令。这些命令可以显示在菜单中,作为一个菜单项出现,当用户单击该菜单项,就发出了响应的信动作也可以显示在工具栏,作为一个工具栏按钮出现,当用户单机这个按钮,也可以发出同样的信号。可以将动作与相关的槽函数连接起来,遮阳挡信号发出时就可以执行响应的操作。注意,无论是出现在菜单栏还是工具栏,只要对应同一个动作,当用户选择之后,所执行的操作都是一样的。
        在定义了一个QAction对象之后,如果将其添加到菜单,如果将其添加到工具栏,就显示为一个工具按钮。用户通过单机菜单项、单击工具栏按钮或使用快捷键来激活这个动作。

5.2.1 手工添加菜单及工具栏

【例5-1】添加文件打开菜单及工具栏按钮

第一步:建立一个基于QMainWindow类的应用程序。创建时取消UI界面文件
第二步,在工程目录下建立img目录,将“打开”位图文件open.jpg放入其中,在Qt Creator中利用新建菜单中地Qt->Qt资源文件rc.qrc,在资源文件rc.qrc中加入img子目录中的位图open.jpg.
第三步,修改mainwindow.h,添加QAction对象指针及槽函数如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT


public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void open();
private:
    QAction *openAction;
};

#endif // MAINWINDOW_H

第4步 修改mainwindow.cpp中的MainWindow构造函数

#include "mainwindow.h"
//添加几个头文件
#include<QAction>
#include<QMenuBar>
#include<QMessageBox>
#include<QStatusBar>
#include<QToolBar>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle(tr("Main Window"));
    //定义QActiton
    openAction=new QAction(QIcon(":/img/open.jpg"),tr("&Open.."),this);
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open an existing file"));
    connect(openAction,&QAction::triggered,this,&MainWindow::open);
    //添加菜单
    QMenu *file=menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);
    //添加工具栏按钮
    QToolBar*toolBar=addToolBar(tr("&File"));
    toolBar->addAction(openAction);
    //设置状态栏信息
    QStatusBar*status=statusBar();
    status->addAction(openAction);
}

MainWindow::~MainWindow()
{

}

这里的setShortcuts(QKeySequence::Open)使用了QKeySequence类定义的快捷方式(实际上就是Ctrl+O键),也可以使用等价的setShortcut(tr("Ctrl+O"))语句。
第五步,在mainwindow.cpp中添加open数,当单机打开菜单或相应的工具栏按钮时,open函数被调用,弹出一个信息框

当鼠标移动到工具栏Open按钮时,会显示提问,同时在状态栏中会显示“Open an existing file”,当鼠标位于Open 菜单项上面时,状态栏也会显示同样的信息。
        有些时候,需要在窗体截面设置弹出式菜单。将下面两句放在MainWindow构造函数中,可以实现在右击后弹出文件菜单:
this->addAction(openAction);
this->setContextMenuPolicy(Qt::ActionsCon\\textMenu);
对Qt中创建菜单和工具栏需要的步骤总结如下
(1)建立动作(Action)
(2)创建菜单并使它与一个动作关联
(3)创建工具并使它与一个动作关联
menuBar()->addMenu()执行时会生成一个QMenu对象且返回它的指针。QMEnu加入一个QAction,就可以对事件进行反映了。addToolBar函数生成工具栏指针,statusBar函数生成状态栏指针,一个QAction可以被多个地方使用。

5.2.2 用设计器添加菜单和工具栏

【例5-2】利用Qt Desiner添加文件打开菜单以及工具栏按钮
第一步,建立一个基于QMainWindow类的应用程序。创建过程中,注意要勾选UI界面文件。
第二步,在设计器中单击第一个菜单第3步,在工程目录下建立img目录,将“打开”位图文件open.jpg放入其中.在Qt Creator中利用新建菜单中的Qt>Qt 资源文件加入一个资源文件rc.qrc中加入img子目录中的位图open.jpg.
第4步,在中央窗口下部的Action编辑器子窗口中的项目action——Open上双击,就打开下图的编辑动作对话框        在Shortcut文本框中按下Ctrl+O键可以设定菜单项的快捷方式。另外,通过其中图标项目的下拉按钮可以为菜单项添加一个图标,图标的来源可以使位图文件或资源。这里选择刚才添加的资源。
        第5步,在'Action编辑器'的action_Open项目下按下鼠标,拖动到设计窗体的工具栏中,在松开鼠标,这样就添加了一个工具按钮。

第6步,单击Action编辑器的action_Open项目,在右侧部件属性栏目中修改statusTip属性的内容信息,这样就在状态栏中加入了提示信息,当鼠标移到工具栏按钮上时,状态栏就显示该信息:

第7步,右击‘Action编辑器’的action_Open项目,在弹出的菜单中选择转到槽,就会出现以下所示的信号选择窗口:

并选择我们的triggered对象。

第8步,在mainwindow.cpp文件头部添加包含文件:

#include<QMessageBox>

在mainwindow.cpp文件修改槽函数on_action_Open_trigged:
 

void MainWindow::on_actionOPEN_triggered()
{
QMessageBox::information(this,tr("information"),tr("Open"));
}

编译运行,可以得到一个和手工创建的窗体(包含菜单、工具栏、状态栏)一样的窗体程序。

5.3 对话框基础知识

对话框是GUI        程序中不可或缺的组成部分。很多不能或不适合放入主窗口的功能设置组件一般都放到对话框中设置。对话框通常会是一个顶层窗口,出现在程序的最上层,用于实现短期任务或者简洁的用户交互。尽管微软公司的Ribbon截面的出现在一定程度上减少了对话框的使用几率,但在某些场合还是很有必要的。其次,即使在最新版本的Office中,任然可以发现不少对话框。

5.3.1 模态和非模态对话框

对话框分为模态对话框和非模态对话框。所谓模态对话框,就是会阻塞同一应用程序中其他窗口的输入。模态对话框很常见,例如微软公司的Word软件中的‘打开文件’对话框,当‘打开文件’对话框出现时,用户不能对除此对话框之外的窗口部分进行操作。与此相反的就是非模态对话框,例如Word中的‘查找和替换’对话框,用户可以在显示该对话框的同时继续对内容进行编辑。
        Qt支持模态对话框和非模态对话框。Qt对话框有两种级别的模态:应用程序级别的模态和窗口级别的模态,默认是应用级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先与对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是允许用户与程序中的其他窗口交互。例如,一个程序可同时编辑多个文档,每个文档都是用一个独立的窗口打开。如果使用应用程序级别的模态对话框进行一些操作,所有文档窗口都会被阻塞。有时创久级别的模态要比原来那种一下子阻塞整个程序要方便。
        Qt使用QDialog::exec实现应用程序级别的模态对话框,使用QDialog::open实现窗口级别的模态对话框,使用QDialog::show实现非模态对话框。有关窗口级别的模态对话框这里不做进一步介绍,感兴趣的读者可以查看相关文档。下文中提到的模态对话框均指应用程序级别的模态对话框。

【例5-2】一个简单地模态对话框

第一步,建立一个QMainWindow类型的主窗口程序。创建时取消UI设计界面。在mainwindow.h中添加下面的代码:
 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void setting();
private:
    QAction*setAction;
};

#endif // MAINWINDOW_H

并且在mainwindows.cpp中添加包含头文件以及构造函数,以及槽函数

#include "mainwindow.h"
#include<QAction>
#include<QMenuBar>
#include<QToolBar>
#include<QStatusBar>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //定义QAction
    setAction =new QAction(QIcon(":/img/setting.jpg"),tr("选项"),this);
    setAction->setStatusTip(tr("环境设定"));
    connect(setAction,&QAction::triggered,this,&MainWindow::setting);
    //添加菜单
    QMenu*tool=menuBar()->addMenu(tr("工具"));
    tool->addAction(setAction);
    //添加工具栏按钮
    QToolBar*toolBar=addToolBar(tr("工具"));
    toolBar->addAction(setAction);
    //设置状态栏信息
    QStatusBar*status=statusBar();
    status->addAction(setAction);
    resize(300,300)
}

MainWindow::~MainWindow()
{

}
 void MainWindow::setting()
 {
     
     
 }

第2步,在工程目录建立目录img,放入位图文件setting.jpg.在本项目中添加Qt资源文件rc.qrc,将位图setting.jpg作为资源加入本项目。
第3步,在菜单中选择“新建文件或项目,选择Qt->"Qt设计器页面类",如下所示。

选择含有底部按钮的Dialog,单机下一步按钮,建立myDialog类。

在myDialog的UI设计界面中,修改windowTitle为"环境设置对话框"
第4步,在主窗体mainwindow.cpp文件中包含myDialog.h头文件
 

#include"mydialog.h"
修改mainwindow.cpp中的setting函数

 void MainWindow::setting()
 {

myDialog dialog(this);
dialog.exec();
 }

编译运行,首先出现以下左边主窗口,再用菜单或工具栏可以启动右侧对话框:
上面的示例中调用了exec将对话框显示出来,因此这是一个模态对话框。当对话框出现时,不能与主窗口进行任何交互,知道关闭了该对话框。
        下面尝试将例5-3的setting函数中的exec修改为show,看看能否实现非模态对话框:
 

void MainWindow::setting()
 {

myDialog dialog(this);
//dialog.exec();
dialog.show();
 }

编译运行,对话框竟然一闪而过,这是因为show函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意,dialog是建立在粘上的,show函数但会,MainWindow::setting函数结束,作为局部变量的dialog超出作用域被析构,因此对话框消失了。知道了原因就好改了,下面将dialog改成堆上建立,就没有这个问题了:

 void MainWindow::setting()
 {

//myDialog dialog(this);
//dialog.exec();
//dialog.show();
     myDialog *dialog=new myDialog(this);
     dialog->show();
 }

这样非模态对话框就实现了。在对话框出现的时候人可以与主窗口进行交互,因此可以利用主窗体的命令启动多个相同的对话框。
        总结一下,要构建非模态对话框,一般是通过对话框类指针实现,首先是使用new方法创建对话框,然后用show函数显示对话框即可。
        关于系统的堆和栈补充一点知识:
        (1)栈区(statck).由编译器自动分配和释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
        (2)堆区(heap).一般由程序员分配和释放,若程序员不释放,程序结束是可能由操作系统回收。注意,它与数据结构中的堆是两回事,分配方式类似于链表。
        上面用new方法建立的对话框,由于程序员没有主动释放空间,所以对话框会一直存在。知道之程序结束时,由于对话框是主窗口的子窗口,所以会一直释放空间。

5.3.2 通过对话框传递数据

        对话框与主窗口之间的数据交互相当重要。对话框氛围模态和非模态两种。下面将以这两种为例,分别进行阐述。
        模态对话框使用了exec函数将其显示出来。exec函数的真正含义是开启一个新的时间循环(第7章回详细介绍事件的概念)。所谓事件循环,可以理解为一个无限循环。Qt在开启了事件循环之后,系统发出的各种事件才能够被程序监听到。既然是无限循环,让然是开启了事件循环的地方,代码就会被阻塞,后面的语句也不会执行。因此,对于使用exec显示的模态对话框,可以在exec函数之后直接从对话框对象获取数据。
        实际上exec是有返回值的,其返回值是QDialog::Accepted或QDialog::Rejected,也就是用户单击了确定或取消按钮后的返回值。一般可使用类似下面的代码获取数据。

myDialog *dialog=new myDialog(this);
if(dialog->exec()==QDialog::Accepted)
{
...//一般在此处取得对话框数据
}else
{
..单击//单击取消按钮后,在此处执行一些操作
}

为了取得对话框的数据,可在对话框类中增加一些函数,返回这些值
【例5-4】从模态对话框中取得数据
本例以5-3为基础,继续做下面的工作
第一步,在5-3的对话框UI设计器中添加一些控件

这些控件极其对象名塑性(ObjectName)罗列如下
1 行编辑器(工程目录)--lineEdit
2 单选按钮(VC6.6)radioButton
3 单选按钮(VC2012)radioButton_2
4 单选按钮(g++)radioButton_3
5 列表框(配色方案)listWidget
6 复选框(自动缩进)checkbox
7复选框(代码补全)checkbox_2
第二步,修改mydialog.h中的myDialog类定义:
 

#ifndef MYDIALOG_H
#define MYDIALOG_H

#include <QDialog>

namespace Ui {
class myDialog;
}

class myDialog : public QDialog
{
    Q_OBJECT

public:
    explicit myDialog(QWidget *parent = 0);
    ~myDialog();
    QString getProjectPath();//获得工程目录
    QString getCompiler();//获得编译器信息
    QString getColorPlan();//获取颜色方案
    bool getIndent();//是否缩进
    bool getAutoComplete();//是否代码自动补全

private:
    Ui::myDialog *ui;
};

#endif // MYDIALOG_H

第3步,在mydialog.cpp中获取下面的函数实现:
 

#include "mydialog.h"
#include "ui_mydialog.h"

myDialog::myDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::myDialog)
{
    ui->setupUi(this);
}

myDialog::~myDialog()
{
    delete ui;
}
QString myDialog::getProjectPath()
{
    QString s=ui->lineEdit->text();
    return s;

}
QString myDialog::getCompiler()
{
    if(ui->radioButton->isChecked())
    {
        return QString("VC++6.0");
    }else if(ui->radioButton_2->isChecked())
    {
        return QString("VC++2012");
    }else
    {
        return QString("g++");
    }


}
QString myDialog::getColorPlan()
{
    QListWidgetItem*it=ui->listWidget->currentItem();
    return it->next();
}
bool myDialog::getAutoComplete()
{
    if(ui->checkBox_2->isChecked())
        return true;
    else
        return false;

}
bool myDialog::getIndent()
{
    if(ui->checkBox->isChecked())
        return true;
    else
        return false;

}

第四步,在mainwindow.h中添加包含文件
 

#include<QLabel>
在mainwindow.h的类累不添加成员:
 QLabel*label;
在mainwindow.cpp文件中MainWindow类构造尾部添加下面的代码:
label=new QLabel("",this);    
label->setGeometry(0,60,300,140);
第五步,在mainwindow.cpp文件中修改槽函数

 void MainWindow::setting()
 {

//myDialog dialog(this);
//dialog.exec();
//dialog.show();
//     myDialog *dialog=new myDialog(this);
//     dialog->show();
     myDialog dialog(this);
     if(dialog.exec()==QDialog::accept())
     {
         QString s;
         s="工程目录:"+dialog.getProjectPath()+"\n";
         s=s+"编译环境:"+dialog.getCompiler()+"\n";
         s=s+"高亮显示"+dialog.getColorPlan()+"\n";
         if(dialog.getIndent())
             s=s+"智能缩进:是\n";
         else
              s=s+"智能缩进:否\n";
         if(dialog.getAutoComplete())
              s=s+"代码补全:是\n";
         else
              s=s+"代码补全:否\n";
         label->setText(s);
     }
编译运行,单击工具按钮打开“环境设置对话框”,如下图这里当dialog.exec为QDialog::Accepted时,通过dialog类中的一些公共方法(名为get***的函数)得到用户的输入值。
        上面是用模态对话框获取输入数据,下面考虑用非模态对话框实现同样的功能。首先想到的方法自然是修改例5-4中菜单项的响应函数setting,将函数组红的对话框创建为非模态对话框,这种思路虽然正确,但是在修改代码的时候初学者往往会犯下面的错误:

//错误代码1:
void MainWindow::setting()
{
myDialog*dialog=new myDialog(this);
if(dialog->show()==QDialog::Accepted)//错误
{
...
}
}

这里的show()函数没哟赴安徽智,他是void类型的函数,它的作用仅仅是将对话框显示出来,而参数QDialog::Accepted实质上是一个整数,两者不能相等。这种语法错误,无法编译通过
 

//错误代码2
void MainWindow::setting()
{
myDialog*dialog=new myDialog(this);
dialog->show();
QString s("工程目录:");
s+=dialog->getProjectPath()+"\n";
...//将对话框的内容放入字符串s
label->setText(s);
}

这种情况编译可以通过,但是程序执行dialog->show()函数并显示对话框后,不会暂停在该语句,而是立刻执行后续语句。因此当用户刚刚看见对话框是,对话框里的默认内容就已经备货区并放入字符串s,而后s被显示在主窗体中。这是setting函数已经执行完毕,但用户这是才有时间慢慢修改对话框中的内容。当修改完成后,用户在单机“确定”按钮时,程序不会有任何响应。
        正确的做法是:建立对话框和主窗体之间的信号与槽函数机制。当在对话框执行某个操作(例如按下按钮)后,将对话框中的信息放到信息中心发送出去,主窗体的槽函数接收这一信号并做出相应处理,这样就实现了信息从对话框向主窗体传递,请参照下面的例子

【例5-5】从非模态对话框得到数据
本例同样基于5-3
第一步,在UI设计界面添加若干控件,与例5-4一样。
第二步,在mydialog.h的类定义中添加信号
signals:
void sendData(QString,QString,QString,bool,bool);

第三步,在UI界面的OK键上右击,在弹出的菜单中选择转到槽,继续在对话框中选择信号accepted并双击,添加槽函数myDialog::on_buttonBox_accepted
第四步,修改myDialog::on_buttonBox_accepted如下:
 

void myDialog::on_buttonBox_accepted()
{
    QString s1=ui->lineEdit->text();//获取工程路径
    //获取编译器名
    QString s2;
    if(ui->radioButton->isChecked())
        s2=QString("VC++6.0");
    else if(ui->radioButton_2->isChecked())
        s2=QString("VC++2012");
    else
        s2=QString("g++");
    //获取颜色方案
    QListWidgetItem *it=ui->listWidget->currentItem();
    QString s3=it->text();
    bool b1=ui->checkBox->isChecked();//是否缩进
    bool b2=ui->checkBox_2->isChecked();//是否代码自动补全
    emit sendData(s1,s2,s3,b1,b2);//发出自定义信号
}

第五步,修改mainwdindow.h中的类定义:
 

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void setting();
    void receiveData(QString,QString,QString,bool,bool);
private:
    QAction*setAction;
    QLabel*label;
};

第六步,修改mainwindow.cpp中的setting和receiveData函数
 

 void MainWindow::setting()
 {
     myDialog*dialog=new myDialog(this);
     //关联信号和槽函数
     connect(dialog,SIGNAL(sendData(QString,QString,QString,bool,bool)),this,SLOT(receiveData(QString,QString,QString,bool,bool)));
     dialog->show();
 }
 void MainWindow:: receiveData(QString,QString,QString,bool,bool)
 {

     QString s;
     s="工程目录:"+s1+"\n"+"编译环境:"+S2+"\n"+"高亮显示:"+s3+"\n";
     if(b1) s=s+"智能缩进:是"+"\n";
     else s=s+"智能缩进:否"+"\n";
     if(b2) s=s+"代码补全:是"+"\n";
     else s=s+"代码补全:否"+"\n";
 }

在MainWindow构造函数的末尾加上如下代码:

label=new QLabel("",this);
label->setGeometry(0,60,300,140);
这里myDialog中自定了信号sendData(QString,QString,QString,bool,bool),
该信号将所有参数全部发送给主窗口,主窗口利用receiveData函数逐一接收,而后显示在标签上
        事实上,这种利用信号传递数据的方法不仅适用于非模态对话框,也适用于模态对话框。

5.3.3 标准对话框

操作系统一般都会提供一系列的标准对话框,如文件选择对话框、字体选择对话框、颜色选择对话框等,这些标准对话框为应用程序提供了一致的观感。Qt对这些标准对话框都定义了相关的类,如QFileDialog、QFontDialog、QColorDialog、QMessageBox、QPrintDialog等。

1 QFileDialog

文件对话框的getOpenFileName是QFileDialog的一个静态函数,直接调用该函数将创建一个模态的文件选择对话框,用于打开文件。若在此对话框中单机打开按钮,则该函数返回用户选择的文件名;如果用户选择取消按钮,则返回一个空串。

【例5-6】文件选择对话框的使用

第一步,建立一个基于QDialog的程序,创建时取消UI设计文件
第二步,修改dialog.h
 

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
    QPushButton*btn;
public slots:
    void slotOpenFileDlg();
};

第3步,修改dialog.cpp中的Dialog类构造函数:
 

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(150,150);
    btn=new QPushButton("File Dialog",this);
    connect(btn,SIGNAL(clicked()),this,SLOT(slotOpenFileDlg()));
}

第4步,在dialog.cpp中添加函数
 

 void Dialog::slotOpenFileDlg()
 {
     QString s=QFileDialog::getOpenFileName(
                 this,//父窗口
                 "open file dialog" //对话框标题
                 ,"/", //默认选中的文件
                 "C++ files(*.cpp);;C files(*.c);;Head files(*.h)");//文件过滤
     qDebug()<<s;
 }

编译运行后出现下图左边的对话框。单机该对话框中的按钮将调出打开文件对话框,选中某个文件,单击确定按钮,文件路径将出现在输出窗口。
        函数getOpenFileName的四个参数依次为父窗口指针、对话框指针、打开对话框是默认选中的文件、文件过滤器。这个粒子只显示后缀为cpp,c或h的文件。过滤器可以有多种,多种过滤器之间用;;隔开

2QColorDialog

getColor是QColorDialog的一个静态函数,调用getColor函数将创建一个模态的颜色对话框。若单击颜色对话框的OK按钮,则getColor函数返回用户选择的颜色值(一个QColor对象),否则返回无效数值。
        通过QColor::isValid函数可以判断用户选择的颜色是否有效,若用户单击ancel按钮,QColor::isValid将返回false

【例5-7】颜色选择对话框的使用
本例将在5-6的代码中继续添加代码
第一步,在dialog.h文件的Dialog类定义中添加以下代码
 

    QPushButton*btn;
    QPushButton*btn1;
public slots:
    void slotOpenFileDlg();
    void slotOpenColoeDlg();

第2步,在dialog.cpp头文件添加包含文件:
#include<QColorDialog>

在dialog.cpp中的Dialog类构造函数中添加以下代码:
 

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(150,150);
    btn=new QPushButton("File Dialog",this);
    connect(btn,SIGNAL(clicked()),this,SLOT(slotOpenFileDlg()));
    btn1=new QPushButton("Color Dialog",this);
    btn1->move(0,30);
    connect(btn1,SIGNAL(clicked()),this,SLOT(slotOpenColoeDlg()));
}

第3步,在dialog.cpp中添加函数
 

 void Dialog::slotOpenColoeDlg()
    {
        QColor color=QColorDialog::getColor(Qt::blue);
        if(color.isValid())
        {
            int r,g,b;
            color.getRgb(&r,&g,&b);//将红黄蓝分别写入r,g,b
            qDebug()<<r<<" "<<g<<" "<<b;
        }
    }

编译运行

3QFontDialog

QFontDialog用于选择某种字体。getFont是QFontDialog的一个静态函数,调用该函数将创建一个模态的字体对话框。函数定义如下:QFont getFont(bool *ok,QWidget*parent=0);
在对话框中单击OK按钮,参数*ok将为true,函数返回用户选择的字体;否则*ok将为false,此时函数返回默认字体。

【例5-8】字体选择对话框的使用

本例将在5-7的代码中继续添加代码
第一步,在dialog.h文件的Dialog类定义中添加如下代码:
 

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
    QPushButton*btn;
    QPushButton*btn1;
    QPushButton*btn2;
public slots:
    void slotOpenFileDlg();
    void slotOpenColoeDlg();
    void slotOpenFontDlg();
};

第2步,在dialog.cpp头部添加包含文件

#include<QFontDialog>

在dialog.cpp中的Dialog类构造函数中添加如下代码
 

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    resize(150,150);
    btn=new QPushButton("File Dialog",this);
    connect(btn,SIGNAL(clicked()),this,SLOT(slotOpenFileDlg()));
    btn1=new QPushButton("Color Dialog",this);
    btn1->move(0,30);
    connect(btn1,SIGNAL(clicked()),this,SLOT(slotOpenColoeDlg()));
    btn2=new QPushButton("Font",this);
    btn2->setGeometry(0.60,50,50);
    connect(btn2,SIGNAL(clicked()),this,SLOT(slotOpenFontDlg()));
}

第3步在dialog.cpp中添加函数:
 

  void Dialog::slotOpenFontDlg()
  {
      bool ok;
      QFont font=QFontDialog::getFont(&ok);
      if(ok){btn2->setFont(font);}
  }

4 QMessageBox

QMessagBox用于显示消息提示,该类有几个常用的静态函数:information、critical、warning、question、about。每一种静态函数被调用时都会产生一个消息对话框。
        现在从AP中看看其中一个函数的原型

static StandardButton QMessageBox::information
(QWidget*parent,const QString &title,const QString &text,StandardButtons button=Ok,
StandardButton defaultButton=NoButton);
        首先它是静态的(static),所以能够使用类名直接访问。第一个参数parent说明他的父组件;第二个参数title是对话框的标题;第三个参数text是对话框显示的内容;第四个参数buttons声明对话框放置的按钮,默认只放置一个OK按钮,这个参数可以使用或运算,,例如我们希望有一个es和No按钮,可以使用QMessageBox::Yes|QMessageBox::No指定,所有的按钮类型可以在QMessageBox生命的StandardButton枚举中找到;第五个参数defaultButton就是默认选中的按钮,默认值是NoButton,也是所有按钮都不选中。
        其他几个函数的参数类似,具体可查看Qt帮助文档。下面给出几个静态函数的用例
(1)information函数的使用:
QMessageBox::information(NULL,"Title","Content",
QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
(2)critical函数的使用:
QMessageBox::critical(NULL,"Title","critical",
QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
(3)warning函数
QMessageBox::warning(NULL,"Title","warning",
QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
(4)question函数
QMessageBox::question(NULL,"Title","warning",
QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);
(5)about函数
QMessageBox::About(NULL,"Title","About",
QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值