前置小知识
事件:由程序内部或者外部,产生的事件或者产生的某个动作(事件 是一个不同步或者说是一个异步的过程,可以由不同对象产生)
信号:是一个同步的过程,只要们点击了/按下了,触发了信号之后,那么槽函数就会进行响应(帮定发送对象和接收对象)
事件举例:
- 鼠标事件
- 按下事件
- 释放事件
- 移动事件
- 双击事件
Qt定时器事件
实现方法一(不建议这么使用)
eventwidget.h
// 需要在头文件中创建id, 实现 timerEvent 方法
public:
virtual void timerEvent(QTimerEvent*event);
private:
int id; // 在publi里面也可以
int id_1;
eventwidget.cpp
// 需要在默认构造中添加定时 Begin
// startTimer属于Object 设置定时间隔2秒, id定时器的标识符
id = this->startTimer(2000);
id_1 = this->startTimer(500); // 对比方便观察
/**
* @brief 定时器事件
* @param event
*/
void EventWidget::timerEvent(QTimerEvent *event) {
static int i = 0, j = 0;
if(event->timerId() == id) {
ui->label->setNum(++i);
// 判断定时器是否达到10秒的时间,如果达成则停止工作
if(i == 5) {
//停止计时->因为没个id都不同所以下面不会有影响
this->killTimer(id);
}
}
if(event->timerId() == id_1) {
ui->label_2->setNum(++j);
}
}
实现方法二
对于QTimer我们还是比较常用的,可能会在很多项目当中看到,并方便我们做一些移植的工作
// 头文件
#include <QTimer>
// QTimer 实现定时器功能
QTimer *timer = new QTimer(this);
static int index = 0;
connect(timer, &QTimer::timeout, this, [=](){
ui->label_3->setNum(++index);
if(index == 10) timer->stop(); // 到10就停止
});
timer->start(500);
Qt鼠标事件
// 头文件
#include <QMouseEvent>
// 声明虚函数_鼠标事件
virtual void mousePressEvent(QMouseEvent *event);
// 鼠标事件,按下、释放、双击、移动
/**
* @brief 鼠标事件(按下(QWidget::mousePressEvent()),释放(QWidget::mouseReleaseEvent()),双击(QWidget::mouseDoubleClickEvent()))
* @param event
*/
void EventWidget::mousePressEvent(QMouseEvent *event) {
// 左键
if(event->button() == Qt::LeftButton) {
// x 代表应用程序左上角起始位置的值, %1 - %2代表有两个参数
ui->label->setText(QString("x : %1, y = %2").arg(event->x()).arg(event->y()));
}
// 右键
else if(event->button() == Qt::RightButton) {
// 以整个窗口左上角为原点的坐标系
ui->label_3->setText(QString("x : %1, y = %2").arg(event->globalX()).arg(event->globalY()));
}
// 中键
else if(event->button() == Qt::MiddleButton) {
ui->label_4->setText("按下鼠标中建");
}
}
Qt键盘事件
使用 QWidget 里面自带的 keyPressEvent 函数来完成对按键的响应。
使用用中可能出现的问题
-
某段程序使用重载 keyPressEvent 后发现不能接收到键盘的响应。
解决办法一:Qt文档曾说明 需要类的构造函数中需要写上
setFocusPolicy(Qt::StrongFocus);
解决办法二:替换掉 keyPressEvent 重载 keyReleaseEvent 进行测试
/**
* @brief 按键事件
* @param event
*/
// 使用 keyPressEvent 捕获不到键盘可以使用 keyReleaseEvent
void EventWidget::keyPressEvent(QKeyEvent *event) {
// 某单一按键按下
if(event->key() == Qt::Key_F) {
qDebug() << "以按下F";
} else if(event->key() == Qt::Key_G) {
qDebug() << "以按下G";
// 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
if(event->key() == Qt::Key_0) {
qDebug() << "以按下G + 0";
}
}
/*
ConstantValueDescription
Qt::NoModifier 0x00000000No modifier key is pressed.
Qt::ShiftModifier 0x02000000A Shift key on the keyboard is pressed.
Qt::ControlModifier 0x04000000A Ctrl key on the keyboard is pressed.
Qt::AltModifier 0x08000000An Alt key on the keyboard is pressed.
Qt::MetaModifier 0x10000000A Meta key on the keyboard is pressed.
Qt::KeypadModifier 0x20000000A keypad button is pressed.
Qt::GroupSwitchModifier 0x40000000X11 only (unless activated on Windows by a command line argument). A Mode_switch key on the keyboard is pressed.
*/
// 组合按键按下Ctrl + F
if(event->modifiers() == Qt::ControlModifier) {
if(event->key() == Qt::Key_F) {
qDebug() << "Ctrl + F 按键被按下";
}
}
else qDebug() << "按键响应测试";
}
Ps:在单一按键按下,里面嵌套另一个单一按键想设置成组合按键这是不可行的(代码如下)
if(event->key() == Qt::Key_G) {
qDebug() << "以按下G";
// 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
if(event->key() == Qt::Key_0) {
qDebug() << "以按下G + 0";
}
}
代码合集
evntwidget.h
#ifndef EVENTWIDGET_H
#define EVENTWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class EventWidget; }
QT_END_NAMESPACE
class EventWidget : public QWidget
{
Q_OBJECT
public:
EventWidget(QWidget *parent = nullptr);
~EventWidget();
protected:
// 时钟事件
virtual void timerEvent(QTimerEvent*event);
// 鼠标事件
virtual void mousePressEvent(QMouseEvent *event);
// 键盘事件
virtual void keyPressEvent(QKeyEvent *event);
private:
Ui::EventWidget *ui;
int id, id_1;
};
#endif // EVENTWIDGET_H
evntwidget.cpp
#include "eventwidget.h"
#include "ui_eventwidget.h"
#include <QTimer>
#include <QDebug>
#include <QMouseEvent>
#include <QKeyEvent>
EventWidget::EventWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::EventWidget)
{
ui->setupUi(this);
// startTimer属于Object 设置定时间隔2秒, id定时器的标识符
id = this->startTimer(2000);
// id_1 = this->startTimer(500);
// QTimer 实现定时器功能
QTimer *timer = new QTimer(this);
static int index = 0;
connect(timer, &QTimer::timeout, this, [=](){
ui->label_3->setNum(++index);
if(index == 10) timer->stop(); // 到10就停止
});
timer->start(500);
// setFocusPolicy(Qt::StrongFocus);
}
EventWidget::~EventWidget()
{
delete ui;
}
/**
* @brief 定时器事件
* @param event
*/
void EventWidget::timerEvent(QTimerEvent *event) {
static int i = 0, j = 0;
if(event->timerId() == id) {
ui->label->setNum(++i);
// 判断定时器是否达到10秒的时间,如果达成则停止工作
if(i == 5) {
//停止计时
this->killTimer(id);
}
}
if(event->timerId() == id_1) {
ui->label_2->setNum(++j);
}
}
// 鼠标事件,按下、释放、双击、移动
/**
* @brief 鼠标事件(按下(QWidget::mousePressEvent()),释放(QWidget::mouseReleaseEvent()),双击(QWidget::mouseDoubleClickEvent()))
* @param event
*/
void EventWidget::mousePressEvent(QMouseEvent *event) {
// 左键
if(event->button() == Qt::LeftButton) {
// x 代表应用程序左上角起始位置的值, %1 - %2代表有两个参数
ui->label->setText(QString("x : %1, y = %2").arg(event->x()).arg(event->y()));
}
// 右键
else if(event->button() == Qt::RightButton) {
// 以整个窗口左上角为原点的坐标系
ui->label_3->setText(QString("x : %1, y = %2").arg(event->globalX()).arg(event->globalY()));
}
// 中键
else if(event->button() == Qt::MiddleButton) {
ui->label_4->setText("按下鼠标中建");
}
}
/**
* @brief 按键事件
* @param event
*/
// 使用 keyPressEvent 捕获不到键盘可以使用 keyReleaseEvent
void EventWidget::keyPressEvent(QKeyEvent *event) {
// 某单一按键按下
if(event->key() == Qt::Key_F) {
qDebug() << "以按下F";
} else if(event->key() == Qt::Key_G) {
qDebug() << "以按下G";
// 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
if(event->key() == Qt::Key_0) {
qDebug() << "以按下G + 0";
}
}
/*
ConstantValueDescription
Qt::NoModifier 0x00000000No modifier key is pressed.
Qt::ShiftModifier 0x02000000A Shift key on the keyboard is pressed.
Qt::ControlModifier 0x04000000A Ctrl key on the keyboard is pressed.
Qt::AltModifier 0x08000000An Alt key on the keyboard is pressed.
Qt::MetaModifier 0x10000000A Meta key on the keyboard is pressed.
Qt::KeypadModifier 0x20000000A keypad button is pressed.
Qt::GroupSwitchModifier 0x40000000X11 only (unless activated on Windows by a command line argument). A Mode_switch key on the keyboard is pressed.
*/
// 组合按键按下Ctrl + F
if(event->modifiers() == Qt::ControlModifier) {
if(event->key() == Qt::Key_F) {
qDebug() << "Ctrl + F 按键被按下";
}
}
else qDebug() << "按键响应测试";
}