2023/9/19 -- C++/QT

手術

1> ログイン ボックスは登録機能を実装し、登録結果をファイルに保存します (Junzi の宿題)

2> テキストエディタの保存作業を完了します

void Widget::on_saveBtn_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this,"另存为","./","*.txt");
    if(fileName.isNull()){
        QMessageBox::information(this,"提示","用户取消了另存文件");
        return;
    }
    QFile file(fileName);
    if(!file.isOpen()){
        if(!file.open(QIODevice::WriteOnly)){
            QMessageBox::critical(this,"错误","打开失败");
            return;
        }
    }
    QString text = ui->textEdit->toPlainText();
    file.write(text.toUtf8());
    file.close();
}

3>

 ウィジェット.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QTimer>
#include <QTime>
#include <QTextToSpeech>
#include <QMessageBox>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

    void timerEvent(QTimerEvent *e)override;

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_startBtn_clicked();

    void on_stopBtn_clicked();

private:
    Ui::Widget *ui;

    int time_id1;
    int time_id2;

    QTextToSpeech *speecher;
};
#endif // WIDGET_H

 ウィジェット.cpp:

#include "widget.h"
#include "ui_widget.h"

void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == time_id1){
        QTime sys_t = QTime::currentTime();          //获取系统时间
        //将QTime类对象转换为字符串
        QString t = sys_t.toString("hh:mm:ss");
        //展示到ui界面
        ui->timeLabel->setText(t);

    }
    if(e->timerId() == time_id2){
        QTime sys_t = QTime::currentTime();          //获取系统时间
        //将QTime类对象转换为字符串
        QString t = sys_t.toString("hh:mm:ss");
        if(t == ui->timeEdit->text()){
            QString text = ui->textEdit->toPlainText();
            speecher->say(text.toUtf8());
        }
    }
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    time_id1 = startTimer(1000);
    ui->timeLabel->setAlignment(Qt::AlignCenter);
    ui->timeEdit->setAlignment(Qt::AlignCenter);
    speecher = new QTextToSpeech(this);
}

Widget::~Widget()
{
    delete ui;
}

//启动按钮
void Widget::on_startBtn_clicked()
{
    time_id2 = startTimer(1000);
    //提示信息
    QMessageBox box(QMessageBox::Information,"提示","已启动",QMessageBox::Ok,this);
    box.exec();
}

//停止按钮
void Widget::on_stopBtn_clicked()
{
    killTimer(time_id2);
    //提示信息
    QMessageBox box(QMessageBox::Information,"提示","已停止",QMessageBox::Ok,this);
    box.exec();
}

レンダリング:

1. イベント処理メカニズム

1.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> 组件的使用者所关心的往往是定义什么样的槽处理什么样的信号,
   而组件的实现者更关心覆盖哪些事件处理函数

   

1.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");
     }

1.3 マウスとキーボードのイベント

1>イベントハンドリング機能

 //重写自己的键盘事件处理函数
    void keyPressEvent(QKeyEvent *event) override;           //键盘按下事件处理函数
    void keyReleaseEvent(QKeyEvent *event) override;         //键盘抬起事件处理函数


    //重写自己的鼠标事件处理函数
    void mousePressEvent(QMouseEvent *event) override;           //鼠标按下事件处理函数
    void mouseReleaseEvent(QMouseEvent *event) override;         //鼠标抬起事件处理函数
    void mouseDoubleClickEvent(QMouseEvent *event) override;      //鼠标双击事件处理函数
    void mouseMoveEvent(QMouseEvent *event) override;             //鼠标移动事件处理函数

2> ケース

1. UIインターフェース

2>ヘッダーファイル

#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include<QKeyEvent>            //键盘事件处理类
#include<QDebug>                //信息调试类
#include<QMouseEvent>           //鼠标事件处理类


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;         //键盘抬起事件处理函数


    //重写自己的鼠标事件处理函数
    void mousePressEvent(QMouseEvent *event) override;           //鼠标按下事件处理函数
    void mouseReleaseEvent(QMouseEvent *event) override;         //鼠标抬起事件处理函数
    void mouseDoubleClickEvent(QMouseEvent *event) override;      //鼠标双击事件处理函数
    void mouseMoveEvent(QMouseEvent *event) override;             //鼠标移动事件处理函数




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


    //开启鼠标追踪功能
    this->setMouseTracking(true);
}


Widget::~Widget()
{
    delete ui;
}


//键盘按下事件处理函数的实现
void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug()<<"有键盘被按下了,键值为"<<event->key()<<"   text:"<<event->text();


    //可以对事件的键值进行判断
    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)
{
    qDebug()<<"有键盘被抬起了";
}


//鼠标按下事件处理函数的定义
void Widget::mousePressEvent(QMouseEvent *event)
{
    //判断是哪个鼠标被按下
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"鼠标左键被按下,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::RightButton)
    {
        qDebug()<<"鼠标右键被按下,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::MidButton)
    {
        qDebug()<<"鼠标中间键被按下,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else
    {
        qDebug()<<"鼠标其他键被按下,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }
}
//鼠标抬起事件处理函数的定义
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    //判断是哪个鼠标被抬起
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"鼠标左键被抬起,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::RightButton)
    {
        qDebug()<<"鼠标右键被抬起,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::MidButton)
    {
        qDebug()<<"鼠标中间键被抬起,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else
    {
        qDebug()<<"鼠标其他键被抬起,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }
}
//鼠标双击事件处理函数的定义
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    //判断是哪个鼠标被双击
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"鼠标左键被双击,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::RightButton)
    {
        qDebug()<<"鼠标右键被双击,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->button() == Qt::MidButton)
    {
        qDebug()<<"鼠标中间键被双击,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else
    {
        qDebug()<<"鼠标其他键被双击,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }
}
//鼠标移动事件处理函数的定义
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    //判断是哪个鼠标被移动
    qDebug()<<"鼠标全局位置:"<<event->globalPos()<<"    组件内位置:"<<event->pos();


    ui->label->move(event->pos());          //将组件跟随鼠标移动


    if(event->buttons() == Qt::LeftButton)
    {
        qDebug()<<"鼠标左键被移动,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->buttons() == Qt::RightButton)
    {
        qDebug()<<"鼠标右键被移动,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else if(event->buttons() == Qt::MidButton)
    {
        qDebug()<<"鼠标中间键被移动,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }else
    {
        qDebug()<<"鼠标其他键被移动,全局坐标点:"<<event->globalPos()<<"   组件内坐标:"<<event->pos();
    }
}

1.4 マウスイベントの場合

1>ヘッダーファイル

#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include<QDebug>
#include<QMouseEvent>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Widget : public QWidget
{
    Q_OBJECT


public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


    //重写鼠标事件处理函数
    void mouseMoveEvent(QMouseEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;




private:
    Ui::Widget *ui;


    QPoint p;              //记录鼠标相对于组件的位置
};
#endif // WIDGET_H

2> ソースファイル

#include "widget.h"
#include "ui_widget.h"


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


    //设置纯净窗口
    this->setWindowFlag(Qt::FramelessWindowHint);
}


Widget::~Widget()
{
    delete ui;
}


//鼠标移动事件处理函数
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    this->move( event->globalPos() - p );
}


//鼠标按下事件处理函数
void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
    p = event->globalPos() - this->pos();
    //      鼠标的全局坐标        组件的全局坐标
    //qDebug()<<this->pos()<<endl;
    }else if(event->button() == Qt::RightButton)
    {
        this->close();
    }
}

1.5 タイマー

1> いわゆるタイマーとは、タイマーが開始されると、システムが指定された時間に特定の関数を自動的に呼び出すことを意味します。

2> タイマー実装には、属性ベースのバージョンとイベント処理バージョンの 2 つのバージョンがあります。

3> イベント ハンドラー関数のバージョンに基づく

1、无需实例化对象,调用的函数都是自身提供的
2、调用自身的成员函数startTimer(sec),启动一个定时器,那么系统就会每隔sec毫秒,自动调用自身的定时器事件处理函数,该函数返回创建的定时器id
3、调用自身成员函数killTimer(id)
4、重写定时器事件处理函数:void timerEvent(QTimerEvent *event);

場合

1. UIインターフェース

2. ヘッダファイル

#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include<QTimerEvent>             //定时器事件处理类
#include<QTime>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Widget : public QWidget
{
    Q_OBJECT


public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


    void timerEvent(QTimerEvent *e) override;         //定时器事件处理函数


private slots:
    void on_startBtn_clicked();


    void on_closeBtn_clicked();


private:
    Ui::Widget *ui;


    int timer_id;             //定时器的id号


};
#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_startBtn_clicked()
{
    timer_id = this->startTimer(1000);
    //功能:启动一个定时器
    //参数:超时时间,每隔给定的时间后,自动调用定时器事件处理函数
    //返回值:当前定时器的id号


}


//关闭定时器按钮对应的槽函数
void Widget::on_closeBtn_clicked()
{
    this->killTimer(timer_id);           //关闭给定的定时器
}


//定时器事件处理函数
void Widget::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == timer_id)         //说明定时器1到位
    {
        QTime sys_t = QTime::currentTime();          //获取系统时间
        //将QTime类对象转换为字符串
        QString t = sys_t.toString("hh:mm:ss");


        //展示到ui界面
        ui->timeLab->setText(t);
    }


//    if(e->timerId() == timer_id_1)         //说明定时器1到位
//    {


//    }
}

1.6 イベントの描画

1> QT インターフェイスが実行されているとき、実際には主に描画イベントを呼び出して、コンピューター上にグラフィカル インターフェイスを描画します。

2> 描画イベントを呼び出すタイミング: 描画イベントは、ウィンドウが初めて表示されたとき、最大化または最小化によってウィンドウが通常に戻ったとき、ウィンドウが上書きされた後に再度表示されたとき、ウィンドウが表示されたとき、ウィンドウ サイズが変更されたとき、または更新関数が呼び出されたとき。

3> 描画イベントの処理ロジック 一般に、描画イベントでは、ペインタ クラス オブジェクトがインスタンス化され、そのオブジェクトを使用して、関連するベクター テキスト、さまざまなグラフィックス、およびグラフィックスを UI インターフェイスに描画します。

4> イベント処理関数のプロトタイプ: virtual voidPaintEvent(QPaintEvent *event);

ヘッドファイル

#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include<QPaintEvent>           //绘制事件类
#include<QDebug>               //信息调试类
#include<QPainter>              //画家类


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Widget : public QWidget
{
    Q_OBJECT


public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


    //重写绘制事件处理函数
    void paintEvent(QPaintEvent *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::paintEvent(QPaintEvent *event)
{
    //实例化一个画家
    QPainter painter(this);


    //实例化一个画笔
    QPen pen;           //使用无参构造
    pen.setColor(QColor("blue"));
    pen.setStyle(Qt::SolidLine);        //设置线型
    pen.setWidth(5);
    //pen.setBrush(QBrush(Qt::RadialGradientPattern));


    //将画笔给画家安排上
    painter.setPen(pen);






    //给画家偏移起始坐标点
    painter.translate(this->width()/2, this->height()/2);


    //给画家 偏移坐标系
    painter.rotate(0);         //旋转坐标系
    painter.setBrush(QBrush(QColor("skyblue")));      //给画家设置画刷




    //画个椭圆
    painter.drawEllipse(QPoint(0,0), 200,100);


    /***************************************************************/
    painter.translate(-this->width()/2, -this->height()/2);
    //绘制矢量文字
    pen.setColor(QColor("red"));
    painter.setPen(pen);
    //给画家设置字体
    painter.setFont(QFont("隶书", 40, 2));


    //绘制矢量文字
    painter.drawText(this->rect(), Qt::AlignCenter, "好好学习\n天天向上");


}



1.7 イベントケースの描画(製図板)

1>ヘッダーファイル

#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include<QMouseEvent>          //鼠标事件
#include<QPaintEvent>            //绘制事件
#include<QPainter>              //画家类
#include<QPixmap>               //图像引擎类


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Widget : public QWidget
{
    Q_OBJECT


public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


    //重写事件处理函数
    void mouseMoveEvent(QMouseEvent *event) override;          //鼠标移动事件
    void mousePressEvent(QMouseEvent *event) override;         //鼠标点击事件
    void paintEvent(QPaintEvent *event) override;               //绘制事件


private:
    Ui::Widget *ui;


    //定义膜的指针
    QPixmap *pix;


    //定义起始点坐标
    QPoint startPoint;
};
#endif // WIDGET_H

2> ソースファイル

#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //构造一个膜的对象
    pix = new QPixmap(this->size());       //用当前界面大小构造一个膜
    pix->fill(Qt::white);                   //设置膜的填充色


}


Widget::~Widget()
{
    delete ui;
}


//鼠标移动事件处理函数
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    //定义一个画家,在膜上进行作画
    QPainter p1(pix);


    QPen pen;


    pen.setColor(QColor("red"));
    pen.setWidth(2);


    p1.setPen(pen);            //红笔


    //不断在两点之间画直线
    p1.drawLine(startPoint, event->pos());


    //更新起始点
    startPoint = event->pos();


    //手动调用更细函数
    this->update();


}
//鼠标按压事件处理函数
void Widget::mousePressEvent(QMouseEvent *event)
{
    //获取起始位置
    startPoint = event->pos();
}
//绘制事件处理函数
void Widget::paintEvent(QPaintEvent *event)
{
    //定义一个画家,在界面上进行作画
    QPainter p2(this);


    //绘制图像
    p2.drawPixmap(QPoint(0,0), *pix);
}

おすすめ

転載: blog.csdn.net/weixin_54147737/article/details/133045489