内容列表
1. 模态和非模态对话框
- QDialog类是所有对话框窗口类的基类。对话框窗口是一个经常用来完成短小任务或者和用户进行简单交互的顶层窗口。
- 按照运行对话框时是否还可以和该程序的其他窗口进行交互,对话框被分成两类:模态和非模态。
QDialog dialog(this);
dialog.show();
//dialog窗口一闪而过,只剩下MyWidget窗口了
//这是因为对于一个函数中定义的变量,函数执行完城后,变量就会被自动释放
QDialog * dialog = new QDialog(this);
dialog->show();
//定义了一个指向QDialog类对象的指针,指定dialog的父窗口为MyWidget类对象,new运算符开辟了内存空间
//并不需要delete指针dialog,dialog指向了MyWidget,MyWidget销毁时也会销毁其子窗口
//这一种是模态对话框
QDialog dialog(this);
dialog.exec();
//这种方法同样可以让对话框显示出来,但是只有当dialog关闭之后,MyWidget窗口才会显示
//这个对话框就是模态对话框
- 模态对话框就是在没有关闭它之前,不能再与同一个应用程序的其他窗口进行交互;
- 而对于非模态对话框,既可以与它交互,也可以与同一程序中的其他窗口交互。
- 要想使一个对话框称为模态对话框,只需要调用它的 exec() 函数;
- 而要使其称为非模态对话框,可以使用 new 操作来创建,然后使用 show() 函数来显示。
- 其实 show() 函数也可以创建模态对话框,只需在其前面使用 setModal() 函数即可。尽量采用这种方法,它可以让对话框都被看到,只不过下层的对话框无法被操作。
QDialog * dialog = new QDialog(this);
dialog->setModal(true);
dialog->show();
2. 多窗口切换
2.1 信号和槽
- Qt中使用信号和槽机制来完成对象之间的协同操作。
- 信号和槽都是函数,比如单击窗口上的一个按钮想要弹出一个对话框,那么可以将这个按钮的单机信号和自定义的槽关联起来,在这个槽中创建一个对话框并显示它。单击这个按钮时就会发射信号,进而执行槽来显示一个对话框。
2.2 练习信号和槽例程
- 新建widget工程
- 编辑界面如下
- 修改pushButton的objectName
- 在头文件 mywidget.h 中添加槽的声明
public slots: // 槽一般使用 slots 关键字进行修饰,建议使用,以便和普通函数区分开
void showChildDialog();
- 快速添加定义的方法:点击 showChildDialog(),同时按下 Alt + Enter,会有下面的弹窗,按下回车后编辑器会转到**.cpp**页面。从源文件中添加定义,然后自动在头文件中添加声明也是同样使用的。
- 源文件中添加如下代码
- 这里使用了connect()函数将按钮的信号clicked()与新建的槽进行关联。
- clicked() 信号在QPushButton类中定义,而 connect() 是QObject类中的函数,因为MyWidget类继承自QObject,所以可以直接使用它。
- 函数的4个参数分别是:发射信号的对象,发射的信号,接收信号的对象,要执行的槽
connect(ui->showChildButton,&QPushButton::clicked,this,&MyWidget::showChildDialog);
2.3 自定义对话框
- 主界面和子对话框来回切换,跳进跳出,例程练习。
- 第一步:添加自定义对话框类。然后添加两个按钮,如下图:
第二步:设计信号和槽。在设计界面,按下快捷键F4就能进入部件的信号和槽的编辑模式。下图标识的就是关联退出程序按钮和对应的槽**close()**的过程:
- 同样的,在进入主界面按钮上鼠标右键,选择转到槽…,选择对应的信号,点击OK,就会进入到代码编辑模式。
void MyDialog::on_pushButton_clicked()
{
//这个accept()函数是QDialog类中的一个槽,对于使用exec()函数实现的模态对话框
//执行了这个槽就会隐藏这个模态对话框,并返回QDialog::Accepted值,这里就是要使用这个值来判断是哪个按钮被按下了。
//与其对应的还有一个reject()槽,它可以返回一个QDialog::Rejected值,前面的“退出程序”按钮也可以关联这个槽
accept();
}
-
前面提到了两种关联信号和槽的方法,第一种是直接在设计器中进行,这个更合适在设计器中的部件间进行。第二种方法是在设计器中直接进入相关信号的槽,这个与前面讲到的手写函数是一样的,它用的就是自动关联,这样也会在.h文件中自动添加该槽的声明,我们只需更改实现代码就好了。
-
main.cpp代码
#include "mywidget.h"
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWidget w;
MyDialog dialog;//新建MyDialog类对象
if(dialog.exec()==QDialog::Accepted)//判断dialog执行结果
{
w.show();//如果是按下了“进入主界面”按钮,则显示主界面
return a.exec();//程序正常运行
}
else
return 0;//否则退出程序
}
void MyWidget::on_pushButton_clicked()
{
//先关闭主界面,其实它是隐藏起来了,并没有真正退出,然后新建MyDialog对象
close();
MyDialog dlg;
//如果按下了“进入主窗口按钮”,再次显示主界面
//否则,因为现在已经没有显示的界面了,程序退出
if(dlg.exec()==QDialog::Accepted)
show();
}
- 运行程序,发现已经实现了从登录对话框到主界面,再从主界面显示一个对话框,然后再从主界面重新进入登录界面的功能了。
- 需要注意的是:close()槽不一定会使程序退出,只有当只剩下最后一个主界面调用close()槽时,程序才会退出;其他情况下界面只是隐藏起来了,并没有销毁。
3. 标准对话框
- Qt提供了一些常用的对话框类型,它们全部继承自QDialog类,并增加了自己的特色功能。
3.1 颜色对话框
//颜色对话框
void MyWidget::on_pushButton_clicked()
{
//QColorDialog的静态函数getColor()来获取颜色
//4个参数:初始颜色,指定父窗口,设置对话框标题,显示alpha设置
//如果不选择颜色,直接点OK,返回的color: QColor(ARGB 1, 1, 0, 0)
//(透明度, 红色, 绿色, 蓝色) 它们的数值都是0.0~1.0,有效数字为6位
QColor color1=QColorDialog::getColor(Qt::red,this,tr("颜色对话框"), QColorDialog::ShowAlphaChannel);
qDebug()<<"color1: "<<color1;
//前面使用的方法直接显示颜色对话框,好处是不需要创建对象。但是如果想要更灵活的设置,则可以县创建对象,然后进行各项的设置:
QColorDialog dialog(Qt::red,this);
dialog.setOption(QColorDialog::ShowAlphaChannel);
dialog.exec();
QColor color2=dialog.currentColor();
qDebug()<<"color2: "<<color2;
}
3.2 文件对话框
//文件对话框
void MyWidget::on_pushButton_6_clicked()
{
//这里使用QFileDialog类中的getOpenFileName()函数来获取选择的文件名,这个函数会以模态的
//方式运行一个文件对话框。打开后选择一个文件,单击“打开”后,函数会返回选择的文件的文件名。
//4个参数分别是:指定父窗口,设置对话框标题,指定默认打开的目录路径,设置文件类型过滤器
//如果不指定文件过滤器,则默认选择所有类型的文件。
//*png *jpg之间需要空格
QString fileName=QFileDialog::getOpenFileName(this,tr("文件对话框"),"D:",tr("图片文件(*png *jpg)"));
qDebug()<<"fileName:"<<fileName;
//如果想选择多个文件,可以使用getOpenFileNames()
QStringList fileNames=QFileDialog::getOpenFileNames(this,tr("文件对话框"),"D:",tr("图片文件(*png *jpg)"));
qDebug()<<"fileNames:"<<fileNames;
//除此之外,QFileDialog类还提供了 getSaveFileName()函数来实现保存文件对话框和文件另存为对话框,
//还有 getExistingDirectory()函数来获取一个已存在的文件夹路径。
QFileDialog dialog(this);
QString filePath = dialog.getExistingDirectory();
qDebug()<<"filePath:"<<filePath;
}
3.3 字体对话框
//字体对话框
void MyWidget::on_pushButton_2_clicked()
{
//ok用于标记是否单击了OK按钮
bool ok;
QFont font = QFontDialog::getFont(&ok,this);
if(ok)
ui->pushButton_2->setFont(font);
else
qDebug()<<tr("没有选择字体!");
}
3.4 输入对话框
//输入对话框
void MyWidget::on_pushButton_7_clicked()
{
bool ok;
//获得字符串
QString str = QInputDialog::getText(this,tr("输入字符串对话框"),
tr("请输入用户名:"), QLineEdit::Normal,
tr("admin"),&ok);
if(ok) qDebug()<<"str: "<<str;
//获得整数
int value1 = QInputDialog::getInt(this,tr("输入整数对话框"),
tr("请输入-1000到1000之间的整数"),
100,-1000,1000,10,&ok);
if(ok) qDebug()<<"value1: "<<value1;
//获得浮点数
double value2 = QInputDialog::getDouble(this,tr("输入浮点数对话框"),
tr("请输入-1000到1000之间的数值"),
0.00,-1000,1000,2,&ok);
if(ok) qDebug()<<"value2: "<<value2;
//获取条目
QStringList items;
items<<tr("条目 1")<<tr("条目 2");
QString item = QInputDialog::getItem(this,tr("输入条目对话框"),
tr("请选择或输入一个条目"),
items,0,true,&ok);
if(ok) qDebug()<<"item: "<<item;
}
3.5 消息对话框
- 这些不同类型的消息对话框,分别拥有不同的图标和提示音。
//消息对话框
void MyWidget::on_pushButton_4_clicked()
{
//问题对话框
int ret1 = QMessageBox::question(this,tr("问题对话框"),tr("你了解Qt吗?"), QMessageBox::Yes,QMessageBox::No);
if(ret1==QMessageBox::Yes) qDebug()<<tr("问题!");
//提示对话框
int ret2 = QMessageBox::information(this,tr("提示对话框"),tr("这是Q书籍!"), QMessageBox::Ok);
if(ret2==QMessageBox::Ok) qDebug()<<tr("提示!");
//警告对话框
int ret3 = QMessageBox::warning(this,tr("警告对话框"),tr("不能提前结束!"),QMessageBox::Abort);
if(ret3==QMessageBox::Abort) qDebug()<<tr("警告!");
//错误对话框
int ret4 = QMessageBox::question(this,tr("错误对话框"),tr("发现一个严重错误!即将关闭软件!"),QMessageBox::YesAll);
if(ret4==QMessageBox::YesAll) qDebug()<<tr("错误!");
//关于对话框
QMessageBox::about(this,tr("关于对话框"),tr("Qt 5.4.0"));
}
3.6 进度对话框
//进度对话框
void MyWidget::on_pushButton_5_clicked()
{
QProgressDialog dialog(tr("文件复制速度"),tr("取消"),0,500000,this);
dialog.setWindowTitle(tr("进度对话框")); //设置窗口标题
dialog.setWindowModality(Qt::WindowModal); //将对话框设置为模态
dialog.show();
for(int i=0;i<500000;i++)
{
dialog.setValue(i); //演示复制进度
QCoreApplication::processEvents(); //设置进度条的当前值
if(dialog.wasCanceled()) //按下取消按钮则弄断
break;
}
dialog.setValue(500000); //这样才能显示100%,因为for循环中少加了一个数
qDebug()<<tr("复制结束!");
}
- 这里使用了模态对话框,QProgressDialog还可以实现非模态对话框,不过需要定时器的帮助。
3.7 错误消息对话框
- 写在头文件中
class QErrorMessage; //类前置声明
QErrorMessage * errordlg; //私有对象
- 写在源文件中
//构造函数
MyWidget::MyWidget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
errordlg=new QErrorMessage(this);
}
//错误信息对话框
void MyWidget::on_pushButton_3_clicked()
{
errordlg->setWindowTitle(tr("错误信息对话框"));
errordlg->showMessage(tr("这里是错误信息!"));
}
3.8 向导对话框
- 头文件
#include <QWizard> //包含头文件
//函数声明
QWizardPage * createPage1();
QWizardPage * createPage2();
QWizardPage * createPage3();
- 源文件
QWizardPage * MyWidget::createPage1()
{
QWizardPage * page=new QWizardPage;
page->setTitle("介绍");
return page;
}
QWizardPage * MyWidget::createPage2()
{
QWizardPage * page=new QWizardPage;
page->setTitle("用户选择信息");
return page;
}
QWizardPage * MyWidget::createPage3()
{
QWizardPage * page=new QWizardPage;
page->setTitle("结束");
return page;
}
//向导对话框
void MyWidget::on_pushButton_8_clicked()
{
QWizard wizard(this);
wizard.setWindowTitle("向导对话框");
wizard.addPage(createPage1());
wizard.addPage(createPage2());
wizard.addPage(createPage3());
wizard.exec();
}
4. 资源下载
https://download.csdn.net/download/weixin_38566632/85095018
转载自:https://liuhui.blog.csdn.net/article/details/124036754
评论(0)
您还未登录,请登录后发表或查看评论