Linux程序开发:QT中的多线程编程(3)
文章作者 100test 发表时间 2007:03:14 16:38:32
来源 100Test.Com百考试题网
3、用户自定义事件在多线程编程中的应用
在 Qt 系统中,定义了很多种类的事件,如定时器事件、鼠标移动事件、键盘事件、窗口控件事件等。通常,事件都来自底层的窗口系统,Qt 的主事件循环函数从系统的事件队列中获取这些事件,并将它们转换为 QEvent,然后传给相应的 QObjects 对象。
除此之外,为了满足用户的需求,Qt 系统还提供了一个 QCustomEvent 类,用于用户自定义事件,这些自定义事件可以利用 QThread::postEvent() 或者QApplication::postEvent() 被发给各种控件或其他 QObject 实例,而 QWidget 类的子类可以通过 QWidget::customEvent() 事件处理函数方便地接收到这些自定义的事件。需要注意的是:QCustomEvent 对象在创建时都带有一个类型标识 id 以定义事件类型,为了避免与 Qt 系统定义的事件类型冲突,该 id 值应该大于枚举类型 QEvent::Type 中给出的 "User" 值。
在下面的例子中,显示了多线程编程中如何利用用户自定义事件类。UserEvent类是用户自定义的事件类,其事件标识为346798,显然不会与系统定义的事件类型冲突。
class UserEvent : public QCustomEvent //用户自定义的事件类
{
public:
UserEvent(QString s) : QCustomEvent(346798), sz(s) { . }
QString str() const { return sz. }
private:
QString sz.
}.
|
UserThread类是由QThread类继承而来的子类,在该类中除了定义有关的变量和线程控制函数外,最主要的是定义线程的启动函数UserThread::run(),在该函数中创建了一个用户自定义事件UserEvent,并利用QThread类的postEvent函数提交该事件给相应的接收对象。
class UserThread : public QThread //用户定义的线程类
{
public:
UserThread(QObject *r, QMutex *m, QWaitCondition *c).
QObject *receiver.
}
void UserThread::run() //线程类启动函数,在该函数中创建了一个用户自定义事件
{UserEvent *re = new UserEvent(resultstring).
QThread::postEvent(receiver, re).
}
|
UserWidget类是用户定义的用于接收自定义事件的QWidget类的子类,该类利用slotGo()函数创建了一个新的线程recv(UserThread类),当收到相应的自定义事件(即id为346798)时,利用customEvent函数对事件进行处理。
void UserWidget::slotGo() //用户定义控件的成员函数
{ mutex.lock().
if (! recv)
recv = new UserThread(this, &.mutex, &.condition).
recv->start().
mutex.unlock().
}
void UserWidget::customEvent(QCustomEvent *e) //用户自定义事件处理函数
{ if (e->type()==346798)
{
UserEvent *re = (UserEvent *) e.
newstring = re->str().
}
}
|
在这个例子中,UserWidget对象中创建了新的线程UserThread,用户可以利用这个线程实现一些周期性的处理(如接收底层发来的消息等),一旦满足特定条件就提交一个用户自定义的事件,当UserWidget对象收到该事件时,可以按需求做出相应的处理,而一般情况下,UserWidget对象可以正常地执行某些例行处理,而完全不受底层消息的影响。