目录
[1.1 消息对话框(QMessageBox)](#1.1 消息对话框(QMessageBox))
[1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答](#1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答)
[2> 基于属性版本的API](#2> 基于属性版本的API)
[3> 基于静态成员函数版本](#3> 基于静态成员函数版本)
[4> 对话框案例](#4> 对话框案例)
[1.2 字体对话框(QFontDialog)、颜色对话框(QColorDialog)、文件对话框(QFileDialog)](#1.2 字体对话框(QFontDialog)、颜色对话框(QColorDialog)、文件对话框(QFileDialog))
[1.3 对话框案例(文本编辑器)](#1.3 对话框案例(文本编辑器))
[1> ui界面](#1> ui界面)
[2> 头文件](#2> 头文件)
[3> 源文件](#3> 源文件)
[1> 配置系统环境变量,将QT安装路径中的相关bin目录放入系统环境变量中](#1> 配置系统环境变量,将QT安装路径中的相关bin目录放入系统环境变量中)
[2> 将自己的程序以release的形式运行一次](#2> 将自己的程序以release的形式运行一次)
[3> 将发布后的relsaes文件夹内的可执行程序复制到一个新的文件夹中](#3> 将发布后的relsaes文件夹内的可执行程序复制到一个新的文件夹中)
[4> 在新文件夹的空白处,按shift+右键 ---->选择"在此处打开powershell窗口"](#4> 在新文件夹的空白处,按shift+右键 ---->选择“在此处打开powershell窗口”)
[5> 在窗口中输入指令:windeployqt.exe .\可执行文件名.exe](#5> 在窗口中输入指令:windeployqt.exe .\可执行文件名.exe)
[6> 此时,就可以执行可执行程序,也可以打包发给朋友](#6> 此时,就可以执行可执行程序,也可以打包发给朋友)
[3.1 事件处理简介](#3.1 事件处理简介)
[3.2 事件处理函数由来](#3.2 事件处理函数由来)
[3.3 鼠标和键盘事件](#3.3 鼠标和键盘事件)
1.Qt文本编辑实现字体和颜色的改变,可进行打开读取和另存为的操作
[2.实现一个lable 通过键盘控制 wasd 实现上下左右移动](#2.实现一个lable 通过键盘控制 wasd 实现上下左右移动)
一、对话框
消息对话框、字体对话框、颜色对话框、文件对话框
1.1 消息对话框(QMessageBox)
1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答
2> 基于属性版本的API
1、使用该类调用构造函数,构造一个类对象
2、调用成员函数exec进入执行态
3、对用户点击的按钮进行进一步处理即可,通过对exec的返回值得到用户点击的按钮
cpp
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;
}
3> 基于静态成员函数版本
1、由于静态成员函数独立于类对象而存在,所以,无需实例化对象,直接通过类名进行调用
2、静态成员函数版本提供四个,分别是information(), question(), warning(), and critical()
3、静态成员函数调用后,之间展示对话框,无需使用exec
3、解析其中warning()
cpp
[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);
4> 对话框案例
1、ui界面
2、头文件
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QMessageBox> //消息对话框类
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_infoBtn_clicked();
void on_warnBtn_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
3、源文件
cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
//信息按钮对应的槽函数
void Widget::on_infoBtn_clicked()
{
//1、使用QMessageBox实例化一个类对象
QMessageBox box(QMessageBox::Information, //图标
"信息", //对话框标题
"中午一起吃个饭!", //对话框提示信息
QMessageBox::Yes|QMessageBox::No, //对话框的提供的按钮
this); //父组件
box.setDefaultButton(QMessageBox::No); //将no设置成默认按钮
//box.setDetailedText("啦啦啦拉拉阿拉啦");
box.setButtonText(QMessageBox::No,"拒绝");
//2、执行对话框
int ret = box.exec();
//3、对用户点击的按钮进行判断
if(ret == QMessageBox::Yes)
{
qDebug()<<"好的,没问题,老地方见!";
}else
{
qDebug()<<"不好意思,我已经有约了,下次一定";
}
}
//警告按钮对应的槽函数
void Widget::on_warnBtn_clicked()
{
//无需实例化对象,直接调用静态成员函数即可
int ret = QMessageBox::warning(this, //父组件
"警告", //对话框标题
"放学别走,等着哈!", //对话框文本内容
QMessageBox::Yes|QMessageBox::No, //提供的按钮
QMessageBox::Yes); //默认选中的按钮
//对用户点击的按钮进行判断
if(ret == QMessageBox::Yes)
{
qDebug()<<"等着就等着,荤的还是素的尽你挑";
}else
{
qDebug()<<"你永远是我大哥";
}
}
练习:完善登录框
点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容"账号密码不匹配,是否重新登录",给定两个按钮ok和cancel,点击ok后,会清除密码框中的内容,继续进行登录;如果点击cancel按钮,则关闭界面。
如果账号和密码匹配,则弹出信息对话框,给出提示信息为"登录成功",给出一个按钮ok,点击ok后,关闭整个登录界面,跳转到其他界面
点击取消按钮后,弹出问题对话框,询问是否确定要退出登录,给出两个按钮,yes|no,点击yes,则直接关闭整个登录界面,如果点击no则进行进行登录
要求:对象版和静态成员函数版至少各实现一个
form.h
cpp
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
signals:
void jump();
public slots:
void jump_slot();
private slots:
void on_pushButton_clicked();
private:
Ui::Form *ui;
};
#endif // FORM_H
widget.h
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
#include <QIcon>
#include <QLabel>
#include <QPixmap>
#include <QLineEdit>
#include <QMessageBox>
class Widget : public QWidget
{
Q_OBJECT //信号与槽的元对象
signals:
//自定义信号函数
void jump();
//void btn_1_clicked();
public slots:
//自定义的槽函数
void btn_1_clicked();
void btn_2_clicked();
void jump_slot();
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QLabel *lab2;
QLabel *lab3;
QLabel *lab1;
QLineEdit *edit1;
QLineEdit *edit2;
QPushButton *btn1;
QPushButton *btn2;
};
#endif // WIDGET_H
form.cpp
cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::jump_slot()
{
this->show();
}
void Form::on_pushButton_clicked()
{
emit jump();
this->close();
}
main.cpp
cpp
#include "widget.h"
#include "form.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
Form m;
QObject::connect(&w,&Widget::jump ,&m,&Form::jump_slot);
QObject::connect(&m,&Form::jump ,&w,&Widget::jump_slot);
return a.exec();
}
widget.cpp
cpp
#include "widget.h"
#include "form.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setFixedSize(900, 800); //设置固定尺寸
//3、窗口标题
this->setWindowTitle("My First Window");
//4、设置窗口的icon
this->setWindowIcon(QIcon(":/new/prefix1/icon/wodepeizhenshi.png"));
//5、设置背景色,一般使用样式表完成
this->setStyleSheet("background-color:rgb(226,227,228);");
//标签
lab1 = new QLabel(this);
lab1->setGeometry(0, 0, 900, 458);
lab1->setPixmap(QPixmap(":/new/prefix1/icon/logo1.png"));
lab1->setScaledContents(true);
lab2 = new QLabel(this);
lab2->setGeometry(270, 500, 40, 40);
lab2->setPixmap(QPixmap(":/new/prefix1/icon/userName.jpg"));
lab2->setScaledContents(true);
lab3 = new QLabel(this);
lab3->setGeometry(270, 580, 40, 40);
lab3->setPixmap(QPixmap(":/new/prefix1/icon/passwd.jpg"));
lab3->setScaledContents(true);
//行编辑器
//1、构造一个行编辑器,构造时给定父组件
edit1
= new QLineEdit(this);
edit2 = new QLineEdit(this);
edit1->setPlaceholderText("QQ/手机/邮箱"); //设置编辑器的占位文本
edit2->setPlaceholderText("密码");
edit1->resize(200,40); //设置尺寸
edit2->resize(200,40);
edit1->move(350,500); //移动位置
edit2->move(350,580);
edit2->setEchoMode(QLineEdit::Password); //设置回显模式
//按钮组件
btn1 = new QPushButton("登录", this);
btn2 = new QPushButton("取消", this);
btn1->resize(110,60);
btn1->move(320,650);
btn2->resize(110,60);
btn2->move(450,650);
btn1->setIcon(QIcon(":/new/prefix1/icon/login.png"));
btn2->setIcon(QIcon(":/new/prefix1/icon/cancel.png"));
//使用qt5版本连接
connect(btn1,&QPushButton::clicked,this,&Widget::btn_1_clicked);
//使用qt4版本连接
connect(btn2,SIGNAL(pressed()),this,SLOT(close()));
}
Widget::~Widget()
{
}
void Widget::btn_1_clicked()
{
if(edit1->text() == "admin" && edit2->text() == "123456")
{
//使用QMwssageBox实例化一个类对象
QMessageBox msgbox1(QMessageBox::Information, //图标
"信息", //对话框标题
"登录成功", //对话框提示信息
QMessageBox::Ok|QMessageBox::Cancel, //对黄框的提供的按钮
this); //父组件
msgbox1.setDefaultButton(QMessageBox::Ok); //将no设置成默认按钮 ,该按键会有蓝色框标识
//msgbox.setDetailedText("啦啦啦啦"); //很少会用到这个提示框
//执行对话框
int ret = msgbox1.exec();
//对用户点击的按钮进行判断
if(ret == QMessageBox::Ok)
{
emit jump();
this->close();
}else
{
//使用QMwssageBox实例化一个类对象
QMessageBox msgbox2(QMessageBox::Information, //图标
"问题", //对话框标题
"是否确定要退出登录", //对话框提示信息
QMessageBox::Yes|QMessageBox::No, //对黄框的提供的按钮
this); //父组件
msgbox2.setDefaultButton(QMessageBox::Yes); //将no设置成默认按钮 ,该按键会有蓝色框标识
//msgbox.setDetailedText("啦啦啦啦"); //很少会用到这个提示框
//执行对话框
int ret = msgbox2.exec();
//对用户点击的按钮进行判断
if(ret == QMessageBox::Yes)
{
this->close();
}else
{
emit jump();
this->close();
}
}
}
else
{
//无需实例化对象,直接调用静态成员函数即可
int ret = QMessageBox::warning(this, //父组件
"警告", //对话框标题
"账号密码不匹配,是否重新登录", //对话框文本内容
QMessageBox::Ok|QMessageBox::Cancel, //提供的按钮
QMessageBox::Ok); //默认选中的按钮
//对用户点击的按钮进行判断
if(ret == QMessageBox::Ok)
{
edit1->clear();
edit2->clear();
}else
{
this->close();
}
}
}
void Widget::btn_2_clicked()
{
this->close();
}
void Widget::jump_slot()
{
this->show();
}
form.ui
运行结果:
1.2 字体对话框(QFontDialog)、颜色对话框(QColorDialog)、文件对话框(QFileDialog)
cpp
1、字体对话框,可以使用QFontDialog类提供的静态成员函数getFont来完成
当调用了该函数后,就会弹出一个字体选择框,该函数返回的是用户选择的字体
如果用户取消了选择,则参数1为假,如果用户选择了字体,则参数1的值为真
所需类:QFontDialog、QFont
[static] QFont //函数返回值类型,是用户选择的字体 该函数是一个静态成员函数
QFontDialog::getFont( //函数名
bool *ok, //返回用户是否选中字体
const QFont &initial, //初始字体
QWidget *parent = nullptr, //父组件
const QString &title = QString()) //对话框标题
举个例子:
bool ok;
QFont font = QFontDialog::getFont(&ok, QFont("Times", 12), this);
if (ok) {
// font is set to the font the user selected
} else {
// the user canceled the dialog; font is set to the initial
// value, in this case Times, 12.
}
2、颜色对话框,可以使用QColorDialog类中的静态成员函数getColor来调取颜色对话框
该函数返回用户选中的颜色,如果用户选择了取消,则返回一个非法的颜色,可以通过成员函数isValid来进行判断
[static] QColor //返回用户选中的颜色 该函数是一个静态成员函数
QColorDialog::getColor( //函数名
const QColor &initial = Qt::white, //初始颜色
QWidget *parent = nullptr, //父组件
const QString &title = QString()) //对话框标题
举个例子:
//调用静态成员函数,获取系统中的颜色对话框
QColor c = QColorDialog::getColor(QColor("pink"),
this,
"选择颜色");
//对选中的颜色判断合法性
if(c.isValid())
{
//颜色合法,直接使用即可
//ui->textEdit->setTextColor(c);
ui->textEdit->setTextBackgroundColor(c);
}else
{
//颜色不合法
QMessageBox::information(this,"提示","您取消了选择颜色");
}
3、文件对话框,可以通过QFileDialog类中的静态成员函数,来获取要打开的文件路径
所需类:QFileDialog
[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)"));
获取保存文件路径的函数:
[static] QString QFileDialog::getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString())
4、文件相关操作
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.3 对话框案例(文本编辑器)
1> ui界面
2> 头文件
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QFont> //字体类
#include<QFontDialog> //字体对话框类
#include<QDebug>
#include<QMessageBox> //消息对话框类
#include<QColor> //颜色类
#include<QColorDialog> //颜色对话框类
#include<QFileDialog> //文件对话框
#include<QFile> //文件类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_fontBtn_clicked();
void on_colorBtn_clicked();
void on_openBtn_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
3> 源文件
cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
//字体按钮对应的槽函数
void Widget::on_fontBtn_clicked()
{
//调用QFontDialog类中的静态成员函数,getFont函数来调取系统提供的字体对话框
bool ok; //用于接受用户是否选中了字体
QFont f = QFontDialog::getFont(&ok, //返回是否选中字体
QFont("隶书", 10, 10, false), //初始字体
this, //父组件
"选择字体"); //对话框标题
//将选中的字体进行使用
if(ok)
{
//选中了字体,将字体设置到文本上
//ui->textEdit->setFont(f);
ui->textEdit->setCurrentFont(f);
}else
{
//没选中字体
QMessageBox::information(this, "提示", "您取消了选择字体");
}
}
//颜色按钮对应的槽函数
void Widget::on_colorBtn_clicked()
{
//调用静态成员函数,获取系统中的颜色对话框
QColor c = QColorDialog::getColor(QColor("pink"), //初始颜色
this, //父组件
"选择颜色"); //对话框标题
//对选中的颜色判断合法性
if(c.isValid())
{
//颜色合法,直接使用即可
//ui->textEdit->setTextColor(c);
ui->textEdit->setTextBackgroundColor(c);
}else
{
//颜色不合法
QMessageBox::information(this,"提示","您取消了选择颜色");
}
}
//打开文件按钮对应的槽函数
void Widget::on_openBtn_clicked()
{
//调用QFileDialog的静态成员函数getOpenFileName来获取选中文件的路径
QString fileName = QFileDialog::getOpenFileName(this, //父组件
"选择文件", //对话框标题
"./", //起始路径
"Image File(*.png *.jpg *bmp);;Text File(*.txt);;All(*.*)"); //过滤器
//判断是否选中文件
if(fileName.isNull())
{
QMessageBox::information(this,"提示","您取消了选择文件");
return;
}
//输出文件路径
qDebug()<<fileName;
//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> 配置系统环境变量,将QT安装路径中的相关bin目录放入系统环境变量中
2> 将自己的程序以release的形式运行一次
3> 将发布后的relsaes文件夹内的可执行程序复制到一个新的文件夹中
4> 在新文件夹的空白处,按shift+右键 ---->选择"在此处打开powershell窗口"
5> 在窗口中输入指令:windeployqt.exe .\可执行文件名.exe
6> 此时,就可以执行可执行程序,也可以打包发给朋友
三、事件处理(核心机制)
3.1 事件处理简介
cpp
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> 组件的使用者所关心的往往是定义什么样的槽处理什么样的信号,
而组件的实现者更关心覆盖哪些事件处理函数
3.2 事件处理函数由来
cpp
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");
}
3.3 鼠标和键盘事件
头文件
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QKeyEvent> //键盘事件处理头文件
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void keyPressEvent(QKeyEvent *event) override; //键盘按下事件处理函数
void keyReleaseEvent(QKeyEvent *event) override; //键盘抬起事件处理函数
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
源文件
cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
//键盘按下事件处理函数的定义
void Widget::keyPressEvent(QKeyEvent *event)
{
//qDebug()<<"键盘被按下了"<<event->text()<<"键值为:"<<event->key();
switch(event->key())
{
case 'W':
{
if(ui->label->y() <= 0-ui->label->height())
{
ui->label->move(ui->label->x(), this->height());
}
ui->label->move(ui->label->x(), ui->label->y()-1);
}
break;
}
}
//键盘抬起事件处理韩寒说的定义
void Widget::keyReleaseEvent(QKeyEvent *event)
{
}
练习:
1.Qt文本编辑实现字体和颜色的改变,可进行打开读取和另存为的操作
widget.h
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QMainWindow>
#include <QFont> //字体类
#include <QFontDialog> //字体对话框类
#include <QDebug>
#include <QMessageBox> //消息对话框
#include <QColor> //颜色类
#include <QColorDialog> //颜色对话框类
#include <QFileDialog> //文件对话框
#include <QFile> //文明类
#include <QTextCodec>
QT_BEGIN_NAMESPACE
namespace Ui { class widget; }
QT_END_NAMESPACE
class widget : public QMainWindow
{
Q_OBJECT
public:
widget(QWidget *parent = nullptr);
~widget();
private slots:
void on_fontBtn_clicked();
void on_colorBtn_clicked();
void on_openBtn_clicked();
void on_pushButton_4_clicked();
private:
Ui::widget *ui;
};
#endif // WIDGET_H
main.cpp
cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
//解决汉字乱码问题
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec);
QApplication a(argc, argv);
widget w;
w.show();
return a.exec();
}
widget.cpp
cpp
#include "widget.h"
#include "ui_widget.h"
widget::widget(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::widget)
{
ui->setupUi(this);
}
widget::~widget()
{
delete ui;
}
//字体按钮的槽函数
void widget::on_fontBtn_clicked()
{
//调用QFontDialog类中的静态成员函数,getFont函数来调取系统提供的对话框
bool ok; //用于接收用户是否选中了字体
QFont f = QFontDialog::getFont(&ok, //返回是否选中字体
QFont("楷体",10,10,false), //初始字体
this, //父组件
"选择字体"); //对话框标题
//将选中的字体进行使用
if(ok) //选中了字体,将字体设置到文本上
{
//ui->textEdit->setFont(f);
ui->textEdit->setCurrentFont(f);
}else //没选中字体
{
QMessageBox::information(this,"提示","您取消了字体");
}
}
//颜色按钮对应的槽函数
void widget::on_colorBtn_clicked()
{
//调用静态成员函数,获取系统中的颜色对话框
QColor c = QColorDialog::getColor(QColor("pink"),
this,
"选择颜色");
//对选中的颜色判断合法性
if(c.isValid())
{
//颜色合法,直接使用即可
//ui->textEdit->setTextColor(c);
ui->textEdit->setTextBackgroundColor(c);
}else
{
//颜色不合法
QMessageBox::information(this,"提示","您取消了选择颜色");
}
}
//打开文件按钮对应的槽函数
void widget::on_openBtn_clicked()
{
//调用QFileDialog的静态成员函数getOpenFileName来获取选中文件的路径
QString fileName = QFileDialog::getOpenFileName(this, //父组件
"选择文件", //对话框标题
"./", //起始路径
"Image File(*.png *.jpg *bmp);;Text File(*.txt);;All(*.*)"); //过滤器
//判断是否选中文件
if(fileName.isNull())
{
QMessageBox::information(this,"提示","您取消了选择文件");
return;
}
//输出文件路径
qDebug() << fileName;
//1.实例化一个文件对象
QFile file(fileName); //使用获取到的文件路径,实例化一个文件对象,后期对文件的操作都是基于该对象
//2.判断文件是否存在
if(!file.exists())
{
return;
}
//3.打开文件
if(!file.open(QFile::ReadWrite))
{
return;
}
//4.读取文件中的内容
QByteArray msg = file.readAll();
//5.将读取到的内容展示到ui界面
ui->textEdit->setText(QString::fromLocal8Bit(msg));
//6.关闭文件
file.close();
//获取文本编辑器中的内容返回是Qstring
//ui->textEdit->toPlainText();
}
//另存为文件按钮对应的槽函数
void widget::on_pushButton_4_clicked()
{
//调用QFileDialog的静态成员函数getOpenFileName来获取选中文件的路径
QString fileName = QFileDialog::getSaveFileName(this, //父组件
"选择文件", //对话框标题
"./", //起始路径
"Image File(*.png *.jpg *bmp);;Text File(*.txt);;All(*.*)"); //过滤器
//判断是否选中文件
if(fileName.isNull())
{
QMessageBox::information(this,"提示","您取消了选择文件");
return;
}
//输出文件路径
qDebug() << fileName;
//1.实例化一个文件对象
QFile file(fileName); //使用获取到的文件路径,实例化一个文件对象,后期对文件的操作都是基于该对象
//2.判断文件是否存在
if(!file.exists())
{
return;
}
//3.打开文件
if(file.open(QFile::ReadWrite|QFile::Truncate))
{
//获取文本编辑器中的内容返回是Qstring
QString msg = ui->textEdit->toPlainText();
file.write(msg.toLocal8Bit());
QMessageBox::information(this,"提示","文件保存成功");
}
else {
QMessageBox::information(this,"提示","文件保存失败");
}
//6.关闭文件
file.close();
}
widget.ui
演示:
2.实现一个lable 通过键盘控制 wasd 实现上下左右移动
sbjp.h
cpp
#ifndef SBJP_H
#define SBJP_H
#include <QWidget>
#include<QKeyEvent> //键盘事件处理头文件
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class SBJP; }
QT_END_NAMESPACE
class SBJP : public QWidget
{
Q_OBJECT
public:
SBJP(QWidget *parent = nullptr);
~SBJP();
public:
void keyPressEvent(QKeyEvent *event) override; //键盘按下事件处理函数
void keyReleaseEvent(QKeyEvent *event) override; //键盘抬起事件处理函数
void sahbi();
private:
Ui::SBJP *ui;
};
#endif // SBJP_H
main.cpp
cpp
#include "sbjp.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SBJP w;
w.show();
return a.exec();
}
sbjp.cpp
cpp
#include "sbjp.h"
#include "ui_sbjp.h"
SBJP::SBJP(QWidget *parent)
: QWidget(parent)
, ui(new Ui::SBJP)
{
ui->setupUi(this);
}
SBJP::~SBJP()
{
delete ui;
}
//键盘按下时间处理函数的定义
void SBJP::keyPressEvent(QKeyEvent *event)
{
//qDebug()<<"键盘被按下了"<<event->text()<<"键值为:"<<event->key();
//qDebug() << this->height();
switch(event->key())
{
case 'W':
{
if(ui->label->y() <= 0-ui->label->height())
{
ui->label->move(ui->label->x(), this->height());
}
ui->label->move(ui->label->x(), ui->label->y()-10);
qDebug() << ui->label->pos().x() << "," << ui->label->pos().y();
}
break;
case 'S':
{
if(ui->label->y() >= this->height()+ui->label->height())
{
ui->label->move(ui->label->x(),0);
}
ui->label->move(ui->label->x(), ui->label->y()+10);
qDebug() << ui->label->pos().x() << "," << ui->label->pos().y();
}
break;
case 'A':
{
if(ui->label->x() <= 0-ui->label->width())
{
ui->label->move(this->width(),ui->label->y());
}
ui->label->move(ui->label->x()-10, ui->label->y());
qDebug() << ui->label->pos().x() << "," << ui->label->pos().y();
}
break;
case 'D':
{
if(ui->label->x() >= this->width())
{
ui->label->move(0-ui->label->width(),ui->label->y());
}
ui->label->move(ui->label->x()+10, ui->label->y());
qDebug() << ui->label->pos().x() << "," << ui->label->pos().y();
}
break;
}
}
//键盘抬起事件处理函数说的定义
void SBJP::keyReleaseEvent(QKeyEvent *event)
{
}