Qt事件和自定义事件

来源链接

什么是事件

怎么产生的事件

1,硬件,比如鼠标,键盘等;---小林code

2,自定义事件;

事件产生之后发送到哪

本应用程序(QApplication)的事件队列。

事件派发的顺序

当有多个widget时,事件事件要发送给哪个对象,父对象还是子对象,还是哪个子对象?

当我在MainWidget中创一个子widget类对象用于捕捉键盘和鼠标事件时,为什么子widget可以捕获鼠标事件,不可用捕获键盘事件?

事件怎么作用的

1,Qt 应用程序的主事件循环(QCoreApplication::exec())从事件队列中获取本地窗口系统事件,将它们转化为 QEvents,然后将转换后的事件发送给 QObjects;

2,QObjects 通过调用它们的 QObject::event() 函数接收事件。该函数可以在子类中重新实现,来处理自定义的事件以及添加额外的事件类型;

postEvent和sendEvent

链接

以下结论错误:

信号和槽函数的原理也是事件

事件是遵循单线程处理原则的,即处理完一个事件才会取出剩余事件执行处理。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
    timer_(new QTimer(this))
{
    timer_->start(1000);
    connect(timer_,&QTimer::timeout,this,&MainWindow::EventLoop);
}

MainWindow::~MainWindow()
{
}

void MainWindow::EventLoop()
{
    static int count=1;
    std::cout<<"==============="<<count++<<std::endl;
    sleep(4);
}

信号和槽的原理 

使用信号和槽必加的两个条件

1,继承:QObject----注意:如果有多个类需要继承,QObject必须是第一个继承的,否则

2,加上宏:Q_Object

事件的拦截处理

拦截之后的事件如果一直交给自己处理,机会崩溃:

bool MainWindow::event(QEvent *e)
{
    //进行事件拦截处理
    if(e->type()==custom_event::CommCallbackEvent::e_type){
        custom_event::CommCallbackEvent* comm_event=static_cast<custom_event::CommCallbackEvent*>(e);
        (*(comm_event->callback_))();
        return true;
    }
    return MainWindow::event(e);
}

键盘事件

void QWidget::keyPressEvent(QKeyEvent *event)

void QWidget::keyReleaseEvent(QKeyEvent *event)

鼠标事件

鼠标的按下,释放,移动事件捕获​​​​​​​

注意区分鼠标按下和鼠标移动按下时的按键判断使用符号区别

按下---------==

移动按下---&

原因:

设置鼠标跟踪

widget->setMouseTracking(true)

QWidget对象或者子对象中的成员函数setMouseTracking();

此属性保存是否为小部件启用鼠标跟踪
如果禁用鼠标跟踪(默认设置),则小部件仅在移动鼠标时按下至少一个鼠标按钮时接收鼠标移动事件。
如果启用了鼠标跟踪,即使没有按下按钮,小部件也会接收鼠标移动事件。

设置鼠标光标状态

空白状态---看不见状态

widget->setCursor(Qt::BlankCursor)

显示箭头状态

widget->setCursor(Qt::ArrowCursor);

捕获鼠标光标坐标值

鼠标的全局和局部位置

链接

全局-----相对于屏幕

局部-----相对于捕获鼠标的控件

QCursor::pos和捕获事件中event->pos()的区别

QCursor::pos捕获的坐标是全局坐标;

event->pos()捕获的是局部坐标 

鼠标光标对象--QCursor

设置光标位置

静态函数

 设置光标位置为当前控件的中心

QCursor::setPos(this->mapToGlobal(this->rect().center()));

注意:QCursor设置的所有光标数据都是全局的,也就是相对于屏幕的,所以小部件的坐标必须转换为全局坐标设置;

this->mapToGlobal(this->rect().center())和this->rect().center()的区别

mapToGlobal()

将小部件给出的某个坐标转换为屏幕全局坐标;

将小部件坐标pos转换为全局屏幕坐标。例如,mapToGlobal(QPoint(0,0))将给出小部件左上角像素的全局坐标。

rect().center()

rect用于获取小部件的中心矩形相对于小部件坐标的x,y,w,h;

center获取 矩形的中心坐标

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void mouseMoveEvent(QMouseEvent* e);
    void mousePressEvent(QMouseEvent* e);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include <QDebug>
#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QRect r=rect();
    qDebug()<<"x="<<r.x()<<"\n"<<"y="<<r.y()<<"\n"<<"w="<<r.width()<<"\n"<<"h="<<r.height();
    QPoint p=rect().center();
    qDebug()<<"conter--x="<<p.x();
    qDebug()<<"conter--y="<<p.y();
}

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

void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
    QPoint center_p=this->mapToGlobal(this->rect().center());
    QPoint coor=e->pos();
    qDebug()<<"Local coordinate--x="<<QString::number(coor.x()).toUtf8().data();
    qDebug()<<"Local coordinate--y="<<QString::number(coor.y()).toUtf8().data();

    QPoint g_coor=e->globalPos();
    qDebug()<<"Global coordinate--x="<<QString::number(g_coor.x()).toUtf8().data();
    qDebug()<<"Global coordinate--y="<<QString::number(g_coor.y()).toUtf8().data();

    qDebug()<<"move ditance x="<<e->globalPos().x()-center_p.x();
    qDebug()<<"move ditance y="<<e->globalPos().y()-center_p.y();
}

void MainWindow::mousePressEvent(QMouseEvent *e)
{
    QPoint center_p=this->mapToGlobal(this->rect().center());
    QCursor::setPos(center_p);
}

屏幕坐标系和控件坐标系

都是

设置光标形状

非静态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中,可以通过自定义控件的鼠标事件来实现对鼠标操作的响应。下面是一般的步骤: 1. 继承QWidget或QAbstractButton等基类,创建自定义控件类。 2. 重写自定义控件类的鼠标事件处理函数,如mousePressEvent、mouseReleaseEvent、mouseMoveEvent等。 3. 在重写的鼠标事件处理函数中,根据需要实现相应的功能逻辑。 例如,如果你想在自定义控件上实现鼠标点击事件的响应,可以按照以下步骤进行: 1. 创建一个继承自QWidget的自定义控件类,例如MyWidget。 2. 在MyWidget类中重写mousePressEvent函数,该函数会在鼠标按下时被调用。 3. 在mousePressEvent函数中实现你想要的功能,比如显示一个提示框或改变控件的状态等。 下面是一个简单的示例代码: ```cpp #include <QWidget> #include <QMouseEvent> class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} protected: void mousePressEvent(QMouseEvent *event) override { if (event->button() == Qt::LeftButton) { // 左键点击事件处理逻辑 // 例如显示一个提示框 qDebug() << "Left button pressed!"; } // 调用父类的事件处理函数,保证其他事件正常处理 QWidget::mousePressEvent(event); } }; ``` 在上述示例中,我们重写了MyWidget类的mousePressEvent函数,并在函数中判断鼠标按下的按钮是否为左键,如果是则输出一条调试信息。同时,我们还调用了父类的mousePressEvent函数,以确保其他事件的正常处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值