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

#ifndef WIDGET_H#define WIDGET_H#include #include#includeQT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic: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()<geometry().topLeft();}Widget::~Widget(){delete ui;}//鼠标按下事件的实现void Widget::mousePressEvent(QMouseEvent *event){qDebug()<pos();//是组件相对于整个屏幕的位置qDebug()<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 #include//定时器类#include //时间类#include//定时器事件类头文件#include //日期时间类QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic: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;//定义一个定时器的idint 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);}