Qt事件

Qt事件

keyPressEvent()实现

void xxx::keyPressEvent(QKeyEvent *event)
{
    switch(event->key()){
        case Qt::Key_Home:
            if(event->modifiers()&Qt::ControlModifier){
                //处理,ctrl按键
            }else{
                //处理
            }
            break;
        case Qt::Key_End:
            break;
        default:
            QWidget::keyPressEvent(event);
    }
}

安装事件过滤器

Qt事件模型一个非常强大的功能是:QObject实例在看到它的事件之前,可以通过设置另外一个QObject实例先监视这些事件。

创建一个事件过滤器包括如下两步过程:

1.通过对目标对象调用installEventFilter()来注册监视对象。

2.在监视对象的eventFilter()函数中处理目标对象的事件。

CustomerInfoDialog::CustomerInfoDialog(QWidget *parent):QDialog(parent)
{
	firstNameEdit->installEventFilter(this);
	lastNameEdit->installEventFilter(this);
	cityEdit->installEventFilter(this);
	phoneNumberEdit->installEventFilter(this);
}

这个事件过滤器一旦注册,发送给firstNameEdit、lastNameEdit、cityEdit和phoneNumberEdit窗口部件的事件就会在它们到达目的地之前先被发送给CustomerInfoDialog的eventFilter()函数。以下是接收这些事件的eventFilter()函数:

bool CustomerInfoDialog::eventFilter(QObjet *target,QEvent *event)
{
    if(target == firstNameEdit || target==lastNameEdit || target==cityEdit
       || target==phoneNumberEdit){
        if(event->type() == QEvent::KeyPress){
            QKeyEvent *keyEvent == static_cast<QKeyEvent*>event;
            if(keyEvent->key() == Qt::Key_Space){
                focusNextChild();
                return true;
            }
        }
    }
    return QDialog::eventFilter(target,event);
}

Qt提供了5个级别的事件处理和事件过滤方法。

1、重新实现特殊的事件处理器

重新实现像mousePressEvent() keyPressEvent() 和paintEvent(),这样的事件处理器是到目前为止最常用的事件处理方式。

2、重新实现QObject::event()

通过event()函数的重新实现,可以在这些事件到达特定的事件处理器之前处理它们。这种方式常用于覆盖Tab键的默认意义。当重新实现event()时,必须对那些没有明确处理的情况调用器基类的event()函数。

3、在QObject中安装事件过滤器

对象一旦使用installEventFilter()注册过,用于目标对象的所有事件都会首先发送给这个监视对象的eventFilter()函数。

4、在QApplication对象中安装事件过滤器

一旦在qApp(唯一的QApplication对象)中注册了事件过滤器,那么应用程序中每个对象的每个事件都会在发送到其它事件过滤器之前,先发送给这个eventFilter()函数。这种处理方式对于调试试非常有用的。

5、子类化QApplication并重新实现notify()

Qt调用QApplication::notify()来发送一个事件。重新实现这个函数实在事件过滤器得到所有事件之前获得它们的唯一方式。事件过滤器通常更有用,因为可以同时有多个事件过滤器,而notify()函数却只能有一个。

当调用QApplication::exec()时,就启动了Qt的事件循环。在开始的时候,Qt会发出一些事件命令来显示和绘制窗口部件。在这之后,事件循环就开始运行,它不断检查是否有事件发生并且把这些事件发送给应用程序中的QObject。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
9.1事件机制与原理分析 9.1.1 什么是Qt事件驱动?         我们在写Qt工程类项目的时候都会发现,主程序里面都有这么一段代码: int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } 有点抽象,Qt进行了封装        实际上a.exec()便是Qt程序进入事件消息循环, 9.1.2 图形界面应用程序的消息处理模型 回调、os的魔抓windows、linux,从用户层到 内核层,如何管理进程、线程、 Os如何处理、底层机制 特点: 基于操作系统才能运行 GUI应用程序提供的功能必须由用户触发 用户操作界面时操作系统是第一个感知的  系统内核的消息通过事件处理转变成QT的信号 9.1.3 Qt事件处理 (1)在Qt事件被封装成一个个对象,所有的事件均继承自抽象类QEvent.              事件处理的核心包括事件①产生、②分发、③接受和处理 ①事件的产生 谁来产生事件? 最容易想到的是我们的输入设备,比如键盘、鼠标产生的 keyPressEvent,keyReleaseEvent, mousePressEvent,mouseReleaseEvent事件 (被封装成QMouseEvent和QKeyEvent)。 ②Qt事件的分发 谁来负责分发事件? 对于non-GUI的Qt程序,是由QCoreApplication负责将QEvent分发给QObject的子类-Receiver.  对于Qt GUI程序,由QApplication来负责   ③事件的接受和处理 谁来接受和处理事件? 答案是QObject。 类是整个Qt对象模型的心脏,事件处理机制是QObject三大职责( 内存管理、内省intropection、事件处理制)之一。 任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重载QObject::event()函数或事件的处理权转给父类。 9.1.4 QObject的内省机制
Qt事件过滤器 Qt事件模型一个真正强大的特色是一个QObject 的实例能够管理另一个QObject 实例的事件。 让我们试着设想已经有了一个CustomerInfoDialog的小部件。CustomerInfoDialog 包含一系列QLineEdit. 现在,我们想用空格键来代替Tab,使焦点在这些QLineEdit间切换。 一个解决的方法是子类化QLineEdit,重新实现keyPressEvent(),并在keyPressEvent()里调用focusNextChild()。像下面这样: void MyLineEdit::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { focusNextChild(); } else { QLineEdit::keyPressEvent(event); } } 但这有一个缺点。如果CustomerInfoDialog里有很多不同的控件(比如QComboBox,QEdit,QSpinBox),我们就必须子类化这么多控件。这是一个烦琐的任务。 一个更好的解决办法是: 让CustomerInfoDialog去管理他的子部件的按键事件,实现要求的行为。我们可以使用事件过滤器。 一个事件过滤器的安装需要下面2个步骤: 1, 调用installEventFilter()注册需要管理的对象。 2,在eventFilter() 里处理需要管理的对象的事件。 一般,推荐在CustomerInfoDialog的构造函数注册被管理的对象。像下面这样: CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) : QDialog(parent){ ... firstNameEdit->installEventFilter(this); lastNameEdit->installEventFilter(this); cityEdit->installEventFilter(this); phoneNumberEdit->installEventFilter(this); } 一旦,事件管理器被注册,发送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit的事件将首先发送到eventFilter()。 下面是一个 eventFilter()函数的实现: bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event) { if (target == firstNameEdit || target == lastNameEdit || target == cityEdit || target == phoneNumberEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Space) { focusNextChild(); return true; } } } return QDialog::eventFilter(target, event); } 在上面的函数,我们首先检查目标部件是否是 firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit。接着,我们判断事件是否是按键事件。如果事件是按键事件,我们把事件转换为QKeyEvent。接着,我们判断是否按下了空格键,如果是,我们调用focusNextChild(),把焦点传递给下一个控件。然后,返回,true通知Qt,我们已经处理了该事件。 如果返回false的话,Qt继续将该事件发送给目标控件,结果是一个空格被插入到QLineEdit。 如果目标控件不是 QLineEdit,或者按键不是空格键,我们将把事件传递给基类的eventFilter()函数。 Qt提供5个级别

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值