最近正在学习QT编程,刚刚学习到多线程的章节,由于曾经有过MFC的使用经历,所以想到QT多线程是否也可以自定义事件。由于勾了一下,发现这篇文章更正《基于QT4的一个多线程工程实现》http://easons.blogbus.com/logs/30443107.html。于是也尝试测试了一下代码,发现居然有不少的代码错误,修改一番后终于能够运行了,但是跟踪却发现,事件发送后,代码根本就不能运行到MyThread::customEvent函数。
于是查找QT帮助,发现了这样一段文字:
void QObject::customEvent ( QEvent * event ) [virtual protected]
This event handler can be reimplemented in a subclass to receive custom events. Custom events are user-defined events with a type value at least as large as the QEvent::User item of the QEvent::Type enum, and is typically a QEvent subclass. The event is passed in the event parameter.
于是从QObject派生出一个类MyObject来接收customEvent:
class MyObject:public QObject
{
Q_OBJECT
public:
MyObject( ){}
~MyObject( ){}
protected:
void customEvent(QEvent * e);
};
class MyObject:public QObject
{
Q_OBJECT
public:
MyObject( ){}
~MyObject( ){}
protected:
void customEvent(QEvent * e);
};
更改MyThread类:
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
~MyThread();
bool StartThread();
bool StopThread();
void PushEvent(MethodEvent* method);
protected:
void run();
private:
bool inited;
};
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
~MyThread();
bool StartThread();
bool StopThread();
void PushEvent(MethodEvent* method);
protected:
void run();
private:
bool inited;
};
将MyThread类的成员函数customEvent修改为MyObject的成员函数:
view plaincopy to clipboardprint?
void CMyObject::customEvent(QEvent * e)
{
if(0 == e)
return;
if( METHOD_EVENT != e->type() )
{
return;
}
MethodEvent* methodEvent = static_cast<MethodEvent*>(e);
if(NULL == methodEvent)
return;
for (int i = 0; i < 1000000000; ++i)
{
methodEvent->i = i;
}
}
void CMyObject::customEvent(QEvent * e)
{
if(0 == e)
return;
if( METHOD_EVENT != e->type() )
{
return;
}
MethodEvent* methodEvent = static_cast<MethodEvent*>(e);
if(NULL == methodEvent)
return;
for (int i = 0; i < 1000000000; ++i)
{
methodEvent->i = i;
}
}
注:void PushEvent(MethodEvent* method) 函数中的pushEvent需要修改为postEvent,这句我想应该是笔者笔误。
即使将《基于QT4的一个多线程工程实现》文中代码做了以上修改,你也可能无法接受自定义的customEvent,这是因为在主函数中的mythread.StartThread()函数调用后,MyThread的run可能还未被调用进入事件循环就调用了事件发送函数,所以发送的事件根本就没有在线程的队列中。
我调试的方法是,建立一个最简单的GUI,通过按下一个button来发送事件。
说明一下,我是使用VS2008进行代码测试的。