Qt---对话框 事件处理 如何发布自己写的软件

目录

一、对话框

1.1 消息对话框(QMessageBox)

1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答

2> 基于属性版本的API

3> 基于静态成员函数版本

4> 对话框案例

1、ui界面

2、头文件

3、源文件

练习:完善登录框

 form.h

widget.h

form.cpp

main.cpp

widget.cpp

form.ui

运行结果: 

1.2 字体对话框(QFontDialog)、颜色对话框(QColorDialog)、文件对话框(QFileDialog) 

1.3 对话框案例(文本编辑器)

1> ui界面

2> 头文件

3> 源文件

二、发布软件

1> 配置系统环境变量,将QT安装路径中的相关bin目录放入系统环境变量中

2> 将自己的程序以release的形式运行一次

3> 将发布后的relsaes文件夹内的可执行程序复制到一个新的文件夹中

4> 在新文件夹的空白处,按shift+右键 ---->选择“在此处打开powershell窗口”

5> 在窗口中输入指令:windeployqt.exe .\可执行文件名.exe

6> 此时,就可以执行可执行程序,也可以打包发给朋友

三、事件处理(核心机制)

3.1 事件处理简介

3.2 事件处理函数由来 

3.3 鼠标和键盘事件

头文件

源文件

练习:

1.Qt文本编辑实现字体和颜色的改变,可进行打开读取和另存为的操作

 widget.h

main.cpp

widget.cpp

widget.ui

演示:

2.实现一个lable 通过键盘控制 wasd 实现上下左右移动

sbjp.h

main.cpp

sbjp.cpp

sbjp.ui

演示: 


一、对话框

消息对话框、字体对话框、颜色对话框、文件对话框

1.1 消息对话框(QMessageBox)

1> 消息对话框提供了一个模态的对话框,用来提示用户信息,或者询问用户问题并得到回答

2> 基于属性版本的API

1、使用该类调用构造函数,构造一个类对象

2、调用成员函数exec进入执行态

3、对用户点击的按钮进行进一步处理即可,通过对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;
  }

3> 基于静态成员函数版本

1、由于静态成员函数独立于类对象而存在,所以,无需实例化对象,直接通过类名进行调用

2、静态成员函数版本提供四个,分别是information(), question(), warning(), and critical()

3、静态成员函数调用后,之间展示对话框,无需使用exec

3、解析其中warning()

[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、头文件

 

#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、源文件

#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

#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

#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

#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

#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

#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) 

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> 头文件

#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> 源文件

#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 事件处理简介

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 事件处理函数由来 

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 鼠标和键盘事件

头文件

#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

源文件

#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

#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

#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

#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

#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

#include "sbjp.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SBJP w;
    w.show();
    return a.exec();
}

sbjp.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)
{

}



sbjp.ui

演示: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/100006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue之若依分页组件的导入使用(不直接使用若依框架,只使用若依分页组件)

vue之若依分页组件的导入使用 步骤 步骤&#xff1a; 工具类&#xff1a;src/utils/scroll-to.js 样式&#xff1a;src/assets/styles/ruoyi.scss 组件&#xff1a;src/components/Pagination 全局挂载&#xff1a;src/main.js 复制工具类 复制若依框架中的src/utils/scrol…

【UE 材质】实现角度渐变材质、棋盘纹理材质

目标 步骤 一、角度渐变材质 1. 首先通过“Mask”节点将"Texture Coordinate" 节点的R、G通道分离 2. 通过“RemapValueRange”节点将0~1范围映射到-1~1 可以看到此时R通道效果&#xff1a; G通道效果&#xff1a; 继续补充如下节点 二、棋盘纹理材质 原视频链接&…

20230901工作心得:IDEA列操作lambda表达式加强版用法

今天是中小学开学时间&#xff0c;亦是9月的开始&#xff0c;继续努力。 今日收获较大的有四个地方&#xff0c;先说这四点。 1、IDEA列操作 使用场景&#xff1a;需要批量将Excel表格里的数据插入到数据库中&#xff0c;此时需要写大量的insert SQL语句。 比如像这样的&am…

Python之父加入微软三年后,Python嵌入Excel!

近日&#xff0c;微软传发布消息&#xff0c;Python被嵌入Excel&#xff0c;从此Excel里可以平民化地进行机器学习了。只要直接在单元格里输入“PY”&#xff0c;回车&#xff0c;调出Python&#xff0c;马上可以轻松实现数据清理、预测分析、可视化等等等等任务&#xff0c;甚…

知识图谱笔记:TransH

1 TransE存在的问题 一对多 假设有一个关系 "是父亲"&#xff0c;其中一个父亲&#xff08;头实体&#xff09;可能有多个孩子&#xff08;尾实体&#xff09; 父亲 A -> 孩子 1父亲 A -> 孩子 2在 TransE 中&#xff0c;这两个关系会被建模为&#xff1a; A是…

网络入门基础

目录 计算机网络背景 网络发展 认识协议 协议的制订 网络协议详解 协议分层 OSI七层模型 TCP/IP模型 网络传输的基本流程 局域网通信 跨网络通信 网络中的地址管理 IP地址 MAC地址 计算机网络背景 网络发展 独立模式&#xff1a;计算机之间相互独立 在早期的时候…

ArcGIS土地利用程度综合指数分析

成图展示&#xff1a; 土地利用程度综合指数 第一步 准备数据 使用的数据为2010年河南省土地利用类型数据与其行政区划县级数据&#xff08;为了节省操作&#xff0c;这里使用上次实验的部分数据[1]&#xff0c;各土地利用类型已被提取&#xff09; 第二步 面积统计 水域为例…

Qt各个版本下载及安装教程(离线和非离线安装)

Qt各个版本下载链接&#xff1a; Index of /archive/qthttps://download.qt.io/archive/qt/ 离线安装 &#xff0c;离线安装很无脑&#xff0c;下一步下一步就可以。 我离线下载 半个小时把2G的exe下载下来了

MySQL - 函数

1 什么是函数&#xff1f; 要想实现上面的这些效果&#xff0c;就得借助于MySQL当中的内置函数。 函数&#xff1a;是指一段可以直接被另一段程序调用的程序或代码。 MySQL当中内置了很多的函数&#xff0c;根据其操作的数据类型&#xff0c;分为以下四类&#xff1a; 字符串…

java 浅谈ThreadLocal底层源码(通俗易懂)

目录 一、ThreadLocal类基本介绍 1.概述 : 2.作用及特定 : 二、ThreadLocal类源码解读 1.代码准备 : 1.1 图示 1.2 数据对象 1.3 测试类 1.4 运行测试 2.源码分析 : 2.1 set方法解读 2.2 get方法解读 一、ThreadLocal类基本介绍 1.概述 : (1) ThreadLocal&#xff0c;本…

Maven基础的快速入门

导读 概念&#xff1a;Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建Java项目的工具 Maven的作用&#xff1a; 1.依赖管理&#xff1a;放便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;&#xff0c;避免版本冲突的问题 2.统一项目结构&…

关于CICD流水线的前端项目运行错误,npm项目环境配置时出现报错:Not Found - GET https://registry.npm...

关于CICD流水线的前端项目运行错误&#xff0c;npm项目环境配置时出现报错&#xff1a;Not Found - GET https://registry.npm… 原因应该是某些jar包缓存中没有需要改变镜像将包拉下来 npm config set registry http://registry.npm.taobao.org npm install npm run build

Matlab图像处理-灰度分段线性变换

灰度分段线性变换 如数学涵义的分段一般&#xff0c;分段线性变换就是将图像不同的灰度范围进行不同的线性灰度处理。其表达式可表示如下&#xff1a; 灰度分段线性变换可根据需求突出增强目标区域&#xff0c;而不增强非目标区间&#xff0c;达到特定的显示效果。 示例程序 …

疑问:相同Service ID、不同Instance ID的SOME/IP服务如何被使用?

这是我的一个疑问&#xff0c;向各位朋友请教&#xff0c;请帮忙留意回复一下&#xff0c;感谢&#xff01; 在SOME/IP中&#xff0c;Service ID是用来识别和标记哪个服务&#xff0c;Instance ID是用来识别和标记某个服务的哪个实例。 既然是相同的服务&#xff0c;这个服务…

虚拟机安装aix 7.2

虚拟机安装aix 7.2 环境安装参考 环境 kali 2023 aix7.2镜像 https://archive.org/details/aix_7200-04-02-2027_072020安装 apt install qemu-system qemu-img create -f qcow2 aix-hdd.qcow2 20G qemu-system-ppc64 -cpu POWER8 -machine pseries -m 4G -serial mon:stdio…

nepctf2023 部分web复现

目录 <1> EZJAVA_CHECKIN(shiro550) <2> 独步天下-转生成为镜花水月中的王者(环境变量提权) <3> 独步天下-破除虚妄_探见真实(Venom代理&ping%0a绕过rce&c文件描述符未关闭连接父进程修改文件权限) <4> 独步天下-破除试炼_加冕成王(tp6rceu…

go学习part21(3)redis连接池

连接池 1.介绍 每次使用数据就就建立链接再关闭可以&#xff0c;但是如果有大量客户端频繁请求连接&#xff0c;大量创建连接和关闭会非常耗费资源。 所以就建立一个连接池&#xff0c;里面存放几个不关闭的连接&#xff0c;谁要用就分配给谁。 说明:通过Golang 对 Redis操…

大数据-玩转数据-Flink 水印

一、Flink 中的水印 在Flink的流式操作中, 会涉及不同的时间概念&#xff1a; 1.1 处理时间 是指的执行操作的各个设备的时间&#xff0c;对于运行在处理时间上的流程序, 所有的基于时间的操作(比如时间窗口)都是使用的设备时钟。比如, 一个长度为1个小时的窗口将会包含设备…

Uncaught ReferenceError: process is not defined

最近在搞老项目升级,将Vue2.6.11里的vuecli5.0.8升级到vite最新版本4.4.9&#xff0c;中间遇到不少问题&#xff0c;有机会以后做记录。 遇到问题 把所有的工作就搞好项目也成功的跑起来&#xff0c;页面一片空白。打开控制台 Uncaught ReferenceError: process is not defi…

hive部署

下载hive安装包&#xff1a;https://dlcdn.apache.org/hive/hive-2.3.9/解压及环境部署 tar -zxvf apache-hive-2.3.9-bin.tar.gz mv apache-hive-2.3.9-bin hivevim /etc/profile添加至环境变量 export HIVE_HOME/usr/local/hive export PATH$PATH:$HIVE_HOME/binsource /etc…