事件(event)-19

前面说了几个标准对话框,下面不打算继续说明一些组件的使用,因为这些使用很难讲完,很多东西都是与实际应用相关的。实际应用的复杂性决定了我 们根本不可能把所有组件的所有使用方法都说明白。这次来说说Qt相对高级一点的特性:事件。
 
事件(event)是有系统或者Qt本身在不同的时刻发出的。当用户按下鼠标,敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事 件。一些事件是在对用户操作做出响应的时候发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。
 
一般来说,使用Qt编程时,我们并不会把主要精力放在事件上,因为在Qt中,需要我们关心的事件总会发出一个信号。比如,我们关心的是 QPushButton的鼠标点击,但我们不需要关心这个鼠标点击事件,而是关心它的clicked()信号。这与其他的一些框架不同:在Swing中, 你所要关心的是JButton的ActionListener这个点击事件。
 
Qt的事件很容易和信号槽混淆。这里简单的说明一下,signal由具体对象发出,然后会马上交给由connect函数连接的slot进行处 理;而对于事件,Qt使用一个事件队列对所有发出的事件进行维护,当新的事件产生时,会被追加到事件队列的尾部,前一个事件完成后,取出后面的事件进行处 理。但是,必要的时候,Qt的事件也是可以不进入事件队列,而是直接处理的。并且,事件还可以使用“事件过滤器”进行过滤。总的来说,如果我们 使 用 组件,我们关心的是信号槽;如果我们 自定义 组件,我们关心的是事件。因为我们可以通过事件来改变 组件的默认操作。比如,如果我们要自定义一个QPushButton,那么我们就需要重写它的鼠标点击事件和键盘处理事件,并且在恰当的时候发出 clicked()信号。
 
还记得我们在main函数里面创建了一个QApplication对象,然后调用了它的exec()函数吗?其实,这个函数就是开始Qt的事件 循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt将创建一个事件对象。Qt的所有事件都继承于 QEvent类。在事件对象创建完毕后,Qt将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事 件对象的类型分派给特定的事件处理函数(event handler)。关于这一点,我们会在以后的章节中详细说明。
 
在所有组件的父类QWidget中,定义了很多事件处理函数,如keyPressEvent()、keyReleaseEvent()、 mouseDoubleClickEvent()、mouseMoveEvent ()、 mousePressEvent()、 mouseReleaseEvent()等。这些函数都是protected virtual的,也就是说,我们应该在子类中重定义这些函数。下面来看一个例子。
 

#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QMouseEvent>

class EventLabel : public QLabel
{

protected :
        void mouseMoveEvent(QMouseEvent *event );
        void mousePressEvent(QMouseEvent *event );
        void mouseReleaseEvent(QMouseEvent *event );
};

void EventLabel::mouseMoveEvent(QMouseEvent *event )
{
        this ->setText(QString("<center><h1>Move: (%1, %2)</h1></center>" )
                                                        .arg(QString::number(event ->x()), QString::number(event ->y())));
}

void EventLabel::mousePressEvent(QMouseEvent *event )
{
        this ->setText(QString("<center><h1>Press: (%1, %2)</h1></center>" )
                                                        .arg(QString::number(event ->x()), QString::number(event ->y())));
}

void EventLabel::mouseReleaseEvent(QMouseEvent *event )
{
        QString msg;
        msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>" ,
                                event ->x(), event ->y());
        this ->setText(msg);
}

int main(int argc, char *argv[])
{
        QApplication app(argc, argv);
        EventLabel *label = new EventLabel;
        label->setWindowTitle("MouseEvent Demo" );
        label->resize(300, 200);
        label->show();
        return app.exec();
}
 
这里我们继承了QLabel类,重写了mousePressEvent、mouseMoveEvent和MouseReleaseEvent三 个函数。我们并没有添加什么功能,只是在鼠标按下(press)、鼠标移动(move)和鼠标释放(release)时把坐标显示在这个Label上面。 注意我们在mouseReleaseEvent函数里面有关QString的构造。我们没有使用arg参数的方式,而是使用C语言风格的sprintf来 构造QString对象,如果你对C语法很熟悉(估计很多C+++程序员都会比较熟悉的吧),那么就可以在Qt中试试熟悉的C格式化写法啦!

本 文出自 “豆子空间 ” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/223974

while (!done) { 338 int offset = 0; 16. string_null_source: 函数 read 不终止字符串 eventBuf。[注意:函数的源代码实现已被内置模型覆盖。] 339 int ret = read(mINotifyFD, eventBuf, sizeof(eventBuf)); 17. 条件 ret >= 16 /* (int)sizeof (inotify_event) */,使用了 true 分支。 340 if (ret >= (int)sizeof(struct inotify_event)) { 18. 条件 offset < ret,使用了 true 分支。 341 while (offset < ret) { 19. var_assign_var: 赋值:event = &eventBuf[offset]。两者现在均指向同一未终止的字符串。 342 struct inotify_event* event = (struct inotify_event*)&eventBuf[offset]; 20. 条件 event->wd == this->mWd,使用了 true 分支。 343 if (event->wd == mWd) { 21. 条件 !strncmp(android::hardware::camera::provider::V2_4::implementation::<unnamed>::kPrefix, event->name, 5U /* android::hardware::camera::provider::V2_4::implementation::<unnamed>::kPrefixLen */),使用了 true 分支。 344 if (!strncmp(kPrefix, event->name, kPrefixLen)) { CID 143777: (#2 of 2): 非 null 字符串终止 (STRING_NULL) 22. string_null: 将未终止的字符串 event->name + 5 传递给期望空字符结尾的字符串的 basic_string。[显示详情] 345 std::string deviceId(event->name + kPrefixLen); 346 if (mInternalDevices.count(deviceId) == 0) { 347 char v4l2DevicePath[kMaxDevicePathLen]; CID 143777:(#1 of 2):非 null 字符串终止 (STRING_NULL) [ "选择问题" ] 348 snprintf(v4l2DevicePath, kMaxDevicePathLen, 349 "%s%s", kDevicePath, event->name); 350 if (event->mask & IN_CREATE) { 351 mParent->deviceAdded(v4l2DevicePath); 352 } 353 if (event->mask & IN_DELETE) { 354 mParent->deviceRemoved(v4l2DevicePath); 355 } 356 } 357 } 358 } 359 offset += sizeof(struct inotify_event) + event->len; 360 } 361 } 362 } 363 364 return true; 365}
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值