最近正在學習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進行代碼測試的。