Qt常用事件汇总

一个事件由一个特定的 QEvent 子类来表示,但是有时一个事件又包含多个事件类型,比如鼠标事件又可以分为鼠标按下、双击和移动等多种操作。这些事件类型都由 QEvent 类的枚举型 QEvent::Type 来表示,其中包含了 一百多种事件类型,可以在 QEvent 类的帮助文档中查看。虽然 QEvent 的子类可以表示一个事件,但是却不能用来处理事件,那么应该怎样来处理一个事件呢?在 QCoreApplication 类的notify()函数的帮助文档处给出了5种处理事件的方法:

方法一:重新实现部件的 paintEvent()、mousePressEvent() 等事件处理函数。这是最常用的一种方法,不过它只能用来处理特定部件的特定事件。

方法二:重新实现 notify() 函数。这个函数功能强大,提供了完全的控制,可以在事件过滤器得到事件之前就获得它们。但是,它一次只能处理一个事件。

方法三:向 QApplication 对象上安装事件过滤器。因为一个程序只有一个 QApplication 对象,所以这样实现的功能与使用 notify() 函数是相同的,优点是可以同时处理多个事件。

方法四:重新实现 event() 函数。QObject 类的 event() 函数可以在事件到达默认的事件处理函数之前获得该事件。

方法五:在对象上安装事件过滤器。使用事件过滤器可以在一个界面类中同时处理不同子部件的不同事件。

在实际编程中,最常用的是方法一,其次是方法五。因为方法二需要继承自 QApplication 类;而方法三要使用一个全局的事件过滤器,这将减缓事件的传递,所以,虽然这两种方法功能很强大,但是却很少被用到。

------>>>>>>鼠标单击 移动 释放 与滚动事件
#include
#include

protected:
    void wheelEvent(QWheelEvent *e);
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);

void wheelEvent(QWheelEvent *e)
{
    if (e->delta() > 0) //鼠标向上滚动
    {
        ui->textEdit->zoomIn(); //进行放大,textEdit的光标和字体都放大
    }
    else
    {
        ui->textEdit-zoomOut(); //进行缩小,textEdit的光标和字体都缩小
    }
}

void mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton)
    {
        qDebug() << "左键按下";
    }
    else if (e->button() == Qt::RightButton)
    {
        qDebug() << "右键按下";
    }
    
      qDebug() << "Press:" << event->x() << " " << event->y();
}

//只有鼠标按下后移动鼠标才会产生mouseMove事件
void mouseMoveEvent(QMouseEvent *e)
{
        if(event->button() == Qt::LeftButton)
    {
        qDebug() << "左键移动" ;
    }
    else if(event->button() == Qt::RightButton)
    {
        qDebug() << "右键移动" ;
    }

    //获取移动过程中的鼠标指针坐标
    qDebug() << "move:" << event->x() << " " << event->y();
}

void mouseReleaseEvent(QMouseEvent *e)
{
        if(event->button() == Qt::LeftButton)
    {
        qDebug() << "左键释放" ;
    }
    else if(event->button() == Qt::RightButton)
    {
        qDebug() << "右键释放" ;
    }

    //获取释放时的鼠标指针坐标
    qDebug() << "release:" << event->x() << " " << event->y();
}

----->>>>>>拖拽事件
#include 
#include 
#include 
#include 

protected:
    void dragEnterEvent(QDragEnterEvent *e);
    void dropEvent(QdropEvent *e);


this->setAcceptDrops(true); //接收拖拽事件

void dragEnterEvent(QDragEnterEvent *e)
{
    if (e->mineData()->hasUrls())
        e->acceptProsedAction();
    else
        e->ignore();
}    

void dropEvent(QdropEvent *e)
{
    const QMimeData *mimeData = event->mimeData(); //获取MIME数据
    if (mimeData->hasUrls()){
        QList urlList = mimeData->urls(); //获取url列表
        QString fileName = urlList.at(0).toLocalFile();
        if (!fileName.isEmpty()){
            QFile file(fileName);
            if(!file.open(QIODevice::ReadOnly))
                return
                
            QTextStream in(&file);
            ui->textEdit()->setText(in.readAll());        
        }
    }
}
----->>>>>>键盘事件
#include 

protected:
    void keyPressEvent(QkeyEvent *e);
    void keyReleaseEvent(QKeyEvent *e);

void keyPressEvent(QkeyEvent *e)
{
    switch(e->key())
    {
    case Qt::key_Escape:
        qDebug() << "Esc";
        break;
    case Qt::key_Return
        qDebug() << "Enter";
        break;
    default:
        break;    
    }
    
    
    if (e->modifiers() == Qt::ControlModifier)
    {
        //如果是,那么再检测M键是否按下
        if(event->key() == Qt::Key_M)
        {
            //按下则使窗口最大化
            this->setWindowState(Qt::WindowMaximized);
        }
    }
}

void keyReleaseEvent(QKeyEvent *e)
{
    if (e->key() == Qt::keyUp)
    {
        qDebug() << "Release: " << "Up";
    }
}
----->>>>>>定时器事件
如果想让定时器仅仅执行一次, 可以使用 setSingleShot(bool singleShot);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timeOut()));
timer->setSingleShot(true);
timer->start(2000);

自定义非阻塞的延时功能
QCoreApplication::processEvents();
QEventLoop loop;//定义一个新的事件循环
QTimer::singleShot(2000, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数
loop.exec();

protected:
    void timerEvent(QTimerEvent *e);

id1 = startTimer(1000); 
id2 = startTimer(2000);
id3 = startTimer(3000);    
void timerEvent(QTimerEvent *e)
{
    if (e->timerId() == id1)
    {
        qDebug() << "定时器1超时"
    }
    else if (e->timerId() == id2)
    {
        qDebug() << "定时器2超时"
    }
    else if (e->timerId() == id3)
    {
        qDebug() << "定时器3超时"
    }
}

主动发送事件函数:sendEvent()与PostEvent()
sendEvent()立即处理给定的事件, 不需要放入事件队列中,其QEvent对象参数在事件发送完成后无法自动删除,故需要在栈上创建QEvent对象
postEvent()将事件放入等待调度队列中,等待下一次事件循环处理,其QEvent对象参数在事件发送后队列会自动删除,故需要在堆上创建QEvent对象


    

你可能感兴趣的:(Qt,Qt学习,Qt事件,Qt事件汇总,Qt事件学习)