一、对话框
消息对话框、字体对话框、颜色对话框、文件对话框
1.1消息对话框
主要分为这四类对话及一种NoIcon无图标对话
而对话框也分为两种实现方式,一种为基于属性分开初始化的方式,这种方式更灵活,更多元,需要对exec的返回值进行判断才能得知是点击哪个按钮,需要写出exec进入执行态
QMessageBox::QMessageBox( //有参构造函数名
QMessageBox::Icon icon, //图标
const QString &title, //对话框标题
const QString &text, //对话框提示信息文本
QMessageBox::StandardButtons buttons = NoButton, //对话框提供的按钮
QWidget *parent = nullptr) //父组件
参数1的介绍:是对话框提供的图标
内容 值 描述
QMessageBox::NoIcon 0 没有任何图标的对话框
QMessageBox::Question 4 带一个问号的对话框
QMessageBox::Information 1 带一个i符号图标的对话框
QMessageBox::Warning 2 带一个感叹号图标的对话框
QMessageBox::Critical 3 带一个叉号图标的对话框
参数4的介绍:对话框提供的按钮
Constant Value Description
QMessageBox::Ok 0x00000400 提供确定按钮
QMessageBox::Open 0x00002000 提供打开按钮
QMessageBox::Save 0x00000800 提供保存按钮
QMessageBox::Cancel 0x00400000 提供取消按钮
举个例子:
QMessageBox msgBox;
msgBox.setText("The document has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Save:
// Save was clicked
break;
case QMessageBox::Discard:
// Don't Save was clicked
break;
case QMessageBox::Cancel:
// Cancel was clicked
break;
default:
// should never be reached
break;
}
静态成员函数与之相比会更简洁,无需实例化对象,直接通过类名调用,提供了information(), question(), warning(), critical()。无需使用exec,直接展示对话框,但与上一种方式相比也会更局限
[static] QMessageBox::StandardButton //函数返回值类型,返回的是对话框上用户按下的按钮
QMessageBox::warning( //函数名
QWidget *parent, //父组件
const QString &title, //对话框标题
const QString &text, //对话框文本内容
QMessageBox::StandardButtons buttons = Ok, //提供的按钮
QMessageBox::StandardButton defaultButton = NoButton) //默认按钮
举个例子:
int ret = QMessageBox::warning(this, tr("My Application"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard
| QMessageBox::Cancel,
QMessageBox::Save);
目前对于登录框的完善已经基本完成
1.2 字体对话框(QFontDialog)、颜色对话框(QColorDialog)、文件对话框(QFileDialog)
字体对话框用来更改对话内字体大小,通过对ok值的判断将用户选中的字体格式导入选中字体
可使用setCurrentFont或者setFont来对选中区域或全部区域进行更改
[static] QFont //函数返回值类型,是用户选择的字体 该函数是一个静态成员函数
QFontDialog::getFont( //函数名
bool *ok, //返回用户是否选中字体
const QFont &initial, //初始字体
QWidget *parent = nullptr, //父组件
const QString &title = QString()) //对话框标题
颜色对话框与字体对话框相似,也是用来更改字体或字体背景颜色的
可以使用QColorDialog类中的静态成员函数getColor来调取颜色对话框
该函数返回用户选中的颜色,如果用户选择了取消,则返回一个非法的颜色,可以通过成员函数isValid来进行判断
[static] QColor //返回用户选中的颜色 该函数是一个静态成员函数
QColorDialog::getColor( //函数名
const QColor &initial = Qt::white, //初始颜色
QWidget *parent = nullptr, //父组件
const QString &title = QString()) //对话框标题
文件对话框,对于文件的操作分为读写,出了Open之外还有相似的Save类
[static] QString //返回值类型是用户选中的文件的路径
QFileDialog::getOpenFileName( //函数名
QWidget *parent = nullptr, //父组件
const QString &caption = QString(), //对话框标题
const QString &dir = QString(), //起始路径
const QString &filter = QString(), //过滤器
QString *selectedFilter = nullptr) //默认选中的过滤器
注意:该函数返回的是选中文件的路径
过滤器如果有多个,中间使用两个分号隔开:"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
举个例子:
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
"/home",
tr("Images (*.png *.xpm *.jpg)"));
文件相关操作
1> 使用QFile类实例化一个对象,通过该对象可以操作整个文件,该类的构造函数需要给定文件的路径
2> 可以使用exists函数判断文件是否存在,如果存在,则可以对文件进行相关操作
3> 使用该类中的成员函数open函数,用于打开文件,打开时需要给定打开模式
4> 可以使用read、readLine、readAll从文件中读取数据,使用write函数,将数据写入文件
5> 使用成员函数close关闭文件
6> 所需类:QFile
举个例子:
//1、实例化一个文件对象
QFile file(fileName); //使用获取到的文件路径,实例化一个文件对象,后期对文件的操作都是基于该对象
//2、判断文件是否存在
if(!file.exists())
{
return;
}
//3、打开文件
if(!file.open(QFile::ReadWrite))
{
return;
}
//4、读取文件中的内容
QByteArray msg = file.readAll();
//将内容展示到ui界面
ui->textEdit->setText(msg);
//获取文本编辑器中的内容
//ui->textEdit->toPlainText();
//5、关闭文件
file.close();
二、软件发布
1.配置环境变量,将两个bin文件配置到系统环境变量中
2.之后将程序release一次,并将准备发布的文件夹内的可执行文件放到一个新文件夹中
3.在当前文件夹下调用终端
4.使用windeployqt.exe .\可执行文件名.exe命令即可将文件发布
三、事件处理机制
1. 什么是事件? (重点)
事件是由窗口系统或者自身产生的,用以响应所发生的
各类事情,比如用户按下并释放了键盘或者鼠标、窗口因
暴露而需要重绘、定时器到时而应有所动作,等等
从某种意义上讲,事件比信号更原始,甚至可以认为大多
数信号其实都是由事件产生的。比如一个下压式按钮首先
感受到的是鼠标事件,
在进行必要的处理以产生按钮下沉
继而弹起的视觉效果之后,才会发射 clicked()信号
2. 如何处理事件? (重点)
myWnd(自定义类) -继承-> QWidget -继承-> QObject
1> 当事件发生时,首先被调用的是QObject类中的虚函数event(),
其 QEvent型参数标识了具体的事件类型
bool QObject:: event (QEvent* e)
{
if (e == mouseEvent)
{
void QWidget::mousePressEvent (QMouseEvent* e)
void QWidget:: mouseReleaseEvent (QMouseEvent* e)
}
if(e == keyEvent){
void QWidget::keyPressEvent (QMouseEvent* e)
void QWidget:: keyReleaseEvent (QMouseEvent* e)
}
}
2> 作为QObject类的子类, QWidget类覆盖了其基类中的
event()虚函数,并根据具体事件调用具体事件处理函数
void QWidget::mousePressEvent (QMouseEvent* e)
void QWidget::mouseReleaseEvent (QMouseEvent* e)
void QWidget::keyPressEvent (QMouseEvent* e)
void QWidget:: keyReleaseEvent (QMouseEvent* e)
void QWidget::paintEvent (QPaintEvent* e):
3> 而这些事件处理函数同样也是虚函数,也可以被 QWidget类
的子类覆盖,以提供针对不同窗口部件类型的事件处理
4> 组件的使用者所关心的往往是定义什么样的槽处理什么样的信号,
而组件的实现者更关心覆盖哪些事件处理函数
事件处理函数的由来是有QObject类提供可改写的虚函数,而QWidget类覆盖了继承而来的虚函数,并提供了一批用于处理事件的时间处理函数(也是虚函数),这也意味着它们也可以被子类覆盖,根据不同情况重写时间处理函数。
QObject类 提供了那些可以重写的虚函数
[virtual] bool QObject::event(QEvent *e)
// 参数:事件的类型
QWidgets类, 提供了那些可以重写的虚函数
[override virtual protected] bool QWidget::event(QEvent *event)
[virtual protected] void QWidget::keyPressEvent(QKeyEvent *event)
[virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event)
[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
[virtual protected] void QObject::timerEvent(QTimerEvent *event)
QPainter类 ---> 画家类
void SimpleExampleWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(Qt::blue);
painter.setFont(QFont("Arial", 30));
painter.drawText(rect(), Qt::AlignCenter, "Qt");
}
例如使用太阳左右移的示例便能看出
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
this -> setWindowTitle("WeiFeng Talking Room");
this -> resize(831,840);
//接收栏
edit1 = new QTextEdit(this);
edit1 -> resize(801,615);
//edit1->setFixedHeight(30);
edit1 -> move(15,15);
//发送栏
edit2 = new QTextEdit(this);
edit2 -> resize(edit1 -> width(),165);
edit2 -> move(edit1 -> x(),edit1 ->height()+45);
//上传按键
btn1 = new QPushButton("上传", this);
btn1 -> resize(70,30);
btn1 -> move(edit1 -> x() ,edit1->y() + edit1->height());
connect(btn1,&QPushButton::clicked,this,&Form::on_openBtn_clicked);
//下载按键
btn2 = new QPushButton("下载", this);
btn2 -> resize(btn1 -> size());
btn2 -> move(btn1 ->x()+btn1 -> width() ,btn1 -> y());
connect(btn2,&QPushButton::clicked,this,&Form::on_saveBtn_clicked);
btn3 = new QPushButton("设置字体", this);
btn3 -> resize(btn1 -> size());
btn3 -> move(btn2 ->x()+btn2 -> width() ,btn1 -> y());
connect(btn3,&QPushButton::clicked,this,&Form::on_fontBtn_clicked);
btn4 = new QPushButton("设置颜色", this);
btn4 -> resize(btn1 -> size());
btn4 -> move(btn3 ->x()+btn3 -> width() ,btn1 -> y());
connect(btn4,&QPushButton::clicked,this,&Form::on_colorBtn_clicked);
}
Form::~Form()
{
delete ui;
}
void Form::jump_slot(){
this->show();
}
void Form::on_fontBtn_clicked()
{
//调用QFontDialog类的静态成员函数,getFont函数来调取系统提供的字体对话框
bool ok;//用于接受用户是否选选中的字体
QFont f = QFontDialog::getFont(&ok,QFont("隶书",10,10,false),this,"选择字体");
//将选中的字体进行使用
if(ok){
edit1 -> setCurrentFont(f);
}else{
QMessageBox::information(this,"提示 ","您取消了选择字符" );
}
}
void Form::on_colorBtn_clicked()
{
QColor c = QColorDialog :: getColor(QColor("pink"),this,"color");
if(c.isValid()){
edit1 -> setTextColor(c);
//edit1 -> setTextBackgroundColor(c);
}else{
QMessageBox::information(this,"提示","您取消了选择颜色");
}
}
void Form::on_openBtn_clicked()
{
QString fileName=QFileDialog::getOpenFileName(this,"上传",
"F:\\Shanghai\\QT\\QTfile\\QT DAY3",
"Image File(*.png *jpg *bmp);;Text File(*.txt);;All(*.*)");
if(fileName.isNull()){
QMessageBox::information(this,"提示","已取消");
}else{
qDebug() << fileName;
QFile file(fileName);
if(!file.exists()){
return;
}else{}
//以读写方式打开
if(!file.open(QFile::ReadWrite)){
return;
}else{
qDebug() << fileName;
QFile file(fileName);
if(!file.exists()){
return;
}else{}
if(!file.open(QFile::ReadWrite)){
return;
}else{}
edit2 ->clear();
QFileInfo fileInfo(fileName);
QString suffix = fileInfo.suffix();
if (suffix == "txt") {
QByteArray msg = file.readAll();
edit1 ->setText(QString::fromLocal8Bit(msg));
} else if (suffix == "png" || suffix == "jpg" || suffix == "bmp") {
edit1->insertHtml(QString("<img src='%1' />").arg(fileName));
}
}
}
}
void Form::on_saveBtn_clicked()
{
QString fileName = QFileDialog::getSaveFileName(this, "下载",
"F:\\Shanghai\\QT\\QTfile\\QT DAY3",
"Image File(*.png *jpg *bmp);;Text File(*.txt);;All(*.*)");
if (fileName.isNull()) {
QMessageBox::information(this, "提示", "已取消");
return;
}
QFile file(fileName);
// 以只写方式打开文件,如果文件不存在,它会被创建。
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, "保存文件", "无法保存文件 " + fileName + ": " + file.errorString());
return;
}
edit2 ->clear();
qDebug() << fileName;
QFileInfo fileInfo(fileName);
QString suffix = fileInfo.suffix(); // 获取文件后缀
if (suffix == "txt") {
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
return;
}
QTextStream out(&file);
out <<edit1->toPlainText();
file.close();
} else if (suffix == "png" || suffix == "jpg" || suffix == "bmp") {
QPixmap pixmap = this->grab(); // 抓取当前窗口的内容
pixmap.save(fileName); // 保存为图片
} else {
}
}