QT DAY4

一、使用鼠标时间完成组件的移动

#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 mousePressEvent(QMouseEvent *event) override;          //鼠标按下事件
    void mouseMoveEvent(QMouseEvent *event) override;            //鼠标移动事件
 
 
private:
    Ui::Widget *ui;
 
 
    QPoint drap;       //定义Z向量
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
 
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
 
 
    //取消头部
    this->setWindowFlag(Qt::FramelessWindowHint);
 
 
    //qDebug()<<this->geometry().topLeft();
}
 
 
Widget::~Widget()
{
    delete ui;
}
 
 
//鼠标按下事件的实现
void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug()<<this->pos();        //是组件相对于整个屏幕的位置
    qDebug()<<event->globalPos();     //是鼠标相对于整个屏幕的位置
 
 
 
 
 
 
    if(event->buttons() == Qt::LeftButton)
    {
       drap = event->globalPos() - this->pos();  //求出相对于屏幕坐标系中,组件左上角位置到鼠标位置的向量
    }else if(event->buttons() == Qt::RightButton)
    {
        this->close();
    }
}
 
 
//鼠标移动事件的实现
void Widget::mouseMoveEvent(QMouseEvent *event)
{
 
 
     this->move(event->globalPos() - drap);     //将组件移动到新位置,由鼠标所在向量,减去组件左上角位置到鼠标位置的向量
 
 
}

二、定时器

当定时器时间超时后,就会有相关的动作进行相应,一个qt程序可以定义多个定时器,以处理不同的事情

定时器的实现有两种方式,分别是基于属性版本,和基于事件处理函数版本

1> 基于属性版本的定时器(QTimer),本质上是基于信号与槽

  • 1、实例化一个QTimer类对象
  • 2、调用该类对象中的成员函数start(毫秒数),启动一个定时器,并给定所定时长,那么该定时器会每隔给定时长后,发射timeout的信号
  • 3、当时间超时后,那么该定时器就会自动发射一个timeout的信号
  • 4、我们可以将该信号连接到自定义的槽函数中,在槽函数中处理相关逻辑
  • 5、造成的现象是:每隔给定时长后,系统会自动调用槽函数
  • 6、当不用该定时器时,可以使用该类中的成员函数stop停止一个定时器

 

2> 基于事件处理函数

  • 1、基于事件处理函数,无需引入新的类对象,使用的全部都是自己的成员函数
  • 2、调用自己的成员函数startTimer(毫秒数),启动一个定时器,启动之后,系统会每隔给定毫秒后,自动调用timerEvent函数
  • 3、timerEvent函数也是自己类中继承的相关虚函数,所以,要对该函数进行重写
  • 4、如果想要关闭定时器,只需调用自己的成员函数killTimer(定时器ID)
#ifndef WIDGET_H
#define WIDGET_H
 
 
#include <QWidget>
#include<QTimer>          //定时器类
#include<QTime>           //时间类
 
 
#include<QTimerEvent>        //定时器事件类头文件
#include<QDateTime>           //日期时间类
 
 
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 *event)override;
 
 
 
 
private slots:
    void on_objStartBtn_clicked();
 
 
    void timeout_slot();           //自定义处理timeout信号函数的声明
 
 
    void on_eventStartBtn_clicked();
 
 
private:
    Ui::Widget *ui;
 
 
    //实例化一个定时器指针。基于类对象版本的定时器
    QTimer *timer;
 
 
    //定义一个定时器的id
    int timer_id;             //基于事件处理函数的定时器
};
#endif // WIDGET_H

三、绘制事件

QT界面运行时主要调用了绘制事件,将图形化界面绘制在计算机上

而绘制事件中调用时机是:第一次展示窗口、窗口因最大化、最小化恢复正常状态、窗口因被覆盖后再次暴露、更改窗口大小、调用update函数都会调用绘制事件

实现闹钟


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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    timer = new QTimer(this);
    speecher = new QTextToSpeech(this);

    // 初始化组件状态
    ui->dateTimeEdit->setEnabled(true);
    ui->action->setEnabled(true);
    ui->stop->setEnabled(false);
    ui->CurrentTime->setEnabled(false);
    ui->edit1->setEnabled(true);

    // 连接信号和槽
    connect(timer, &QTimer::timeout, this, &Widget::timeout_slot);
    connect(ui->action, &QPushButton::clicked, this, &Widget::on_action_clicked);
    connect(ui->stop, &QPushButton::clicked, this, &Widget::on_stop_clicked);
}

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

void Widget::on_action_clicked()
{
    // 启动定时器
    timer->start(1000);

    // 更新组件状态
    ui->dateTimeEdit->setEnabled(false);
    ui->action->setEnabled(false);
    ui->stop->setEnabled(true);
    ui->CurrentTime->setEnabled(true);
    ui->edit1->setEnabled(false);

    // 获取设定的时间
    alarmTime = ui->dateTimeEdit->dateTime();
}

void Widget::timeout_slot()
{
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString t = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");

    // 更新UI上的时间显示
    ui->CurrentTime->setText(t);

    // 检查是否到达设定的时间
    if (currentDateTime >= alarmTime) {
        // 播报文本
        speecher->say(ui->edit1->toPlainText());

        // 停止定时器
        timer->stop();

        // 更新组件状态
        ui->dateTimeEdit->setEnabled(true);
        ui->action->setEnabled(true);
        ui->stop->setEnabled(false);
        ui->CurrentTime->setEnabled(false);
        ui->edit1->setEnabled(true);
    }
}

void Widget::on_stop_clicked()
{
    // 停止定时器
    timer->stop();

    // 更新组件状态
    ui->dateTimeEdit->setEnabled(true);
    ui->action->setEnabled(true);
    ui->stop->setEnabled(false);
    ui->CurrentTime->setEnabled(false);
    ui->edit1->setEnabled(true);
}