赞
踩
需要注意的是,与信号不同,事件并不是一产生就被分发。事件产生之后被加入到一个队列中(这里的队列含义同数据结构中的概念,先进先出),该队列即被称为事件队列。事件分发器遍历事件队列,如果发现事件队列中有事件,那么就把这个事件发送给它的目标对象。这个循环被称作事件循环。事件循环的伪代码描述大致如下所示:
- while (is_active)
- {
- while (!event_queue_is_empty) {
- dispatch_next_event();
- }
- wait_for_more_events();
- }
PyQt程序在执行的时候
调用QApplication.
exec() 函数意味着进入了主循环。我们把事件循环理解为一个无限循环,直到QApplication.exit()或者QApplication.quit()被调用,事件循环才真正退出。
伪代码里面的while会遍历整个事件队列,发送从队列中找到的事件;wait_for_more_events()函数则会阻塞事件循环,直到又有新的事件产生。我们仔细考虑这段代码,在wait_for_more_events()函数所得到的新的事件都应该是由程序外部产生的。因为所有内部事件都应该在事件队列中处理完毕了。因此,我们说事件循环在wait_for_more_events()函数进入休眠,并且可以被下面几种情况唤醒:
在类 UNIX 系统中,窗口管理器(比如 X11)会通过套接字(Unix Domain 或 TCP/IP)向应用程序发出窗口活动的通知,因为客户端就是通过这种机制与 X 服务器交互的。如果我们决定要实现基于内部的socketpair(2)函数的跨线程事件的派发,那么窗口的管理活动需要唤醒的是:
- QApplication.exec()
- […]
- QWidget.event()
- Button.mousePressEvent()
- Button.clicked()
- […]
- Worker.doWork()
开始事件循环,也就执行QApplication.exec()函数。窗口管理器侦测到鼠标点击后,PyQt 会发现并将其转换成QMouseEvent事件,发送给组件的event()函数。这一过程是通过QApplication.notify()函数实现的。注意我们的按钮并没有覆盖event()函数,因此其父类的实现将被执行,也就是QWidget.event()函数。这个函数发现这个事件是一个鼠标点击事件,于是调用了对应的事件处理函数,就是Button.mousePressEvent()函数。我们重写了这个函数,发出Button.clicked()信号,而正是这个信号会调用Worker.doWork()槽函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。