Qt允許你創建自己的事件類型,這在多線程的程序中尤其有用,當然,也可以用在單線程的程序中,作爲一種對象間通訊的機制。那麼,爲什麼我需要使用事件,而不是使用信號槽呢?主要原因是,事件的分發既可以是同步的,又可以是異步的,而函數的調用或者說是槽的回調總是同步的。事件的另外一個好處是,它可以使用過濾器。
Qt中的自定義事件很簡單,同其他類似的庫的使用很相似,都是要繼承一個類進行擴展。在Qt中,你需要繼承的類是QEvent。注意,在Qt3中,你需要繼承的類是QCustomEvent,不過這個類在Qt4中已經被廢除(這裏的廢除是不建議使用,並不是從類庫中刪除)。
繼承QEvent類,你需要提供一個QEvent::Type類型的參數,作爲自定義事件的類型值。這裏的QEvent::Type類型是QEvent裏面定義的一個enum,因此,你是可以傳遞一個int的。重要的是,你的事件類型不能和已經存在的type值重複,否則會有不可預料的錯誤發生!因爲系統會將你的事件當做系統事件進行派發和調用。在Qt中,系統將保留0 - 999的值,也就是說,你的事件type要大於999. 具體來說,你的自定義事件的type要在QEvent::User和QEvent::MaxUser的範圍之間。其中,QEvent::User值是1000,QEvent::MaxUser的值是65535。從這裏知道,你最多可以定義64536個事件,相信這個數字已經足夠大了!但是,即便如此,也只能保證用戶自定義事件不能覆蓋系統事件,並不能保證自定義事件之間不會被覆蓋。爲了解決這個問題,Qt提供了一個函數:registerEventType(),用於自定義事件的註冊。該函數簽名如下:
函數是static的,因此可以使用QEvent類直接調用。函數接受一個int值,其默認值爲-1,返回值是創建的這個Type類型的值。如果hint是合法的,不會發生任何覆蓋,則會返回這個值;如果hint不合法,系統會自動分配一個合法值並返回。因此,使用這個函數即可完成type值的指定。這個函數是線程安全的,因此不必另外添加同步。
你可以在QEvent子類中添加自己的事件所需要的數據,然後進行事件的發送。Qt中提供了兩種發送方式:
另外,你也可以通過重寫event()函數來處理自定義事件:
這兩種辦法都是可行的。
Qt中的自定義事件很簡單,同其他類似的庫的使用很相似,都是要繼承一個類進行擴展。在Qt中,你需要繼承的類是QEvent。注意,在Qt3中,你需要繼承的類是QCustomEvent,不過這個類在Qt4中已經被廢除(這裏的廢除是不建議使用,並不是從類庫中刪除)。
繼承QEvent類,你需要提供一個QEvent::Type類型的參數,作爲自定義事件的類型值。這裏的QEvent::Type類型是QEvent裏面定義的一個enum,因此,你是可以傳遞一個int的。重要的是,你的事件類型不能和已經存在的type值重複,否則會有不可預料的錯誤發生!因爲系統會將你的事件當做系統事件進行派發和調用。在Qt中,系統將保留0 - 999的值,也就是說,你的事件type要大於999. 具體來說,你的自定義事件的type要在QEvent::User和QEvent::MaxUser的範圍之間。其中,QEvent::User值是1000,QEvent::MaxUser的值是65535。從這裏知道,你最多可以定義64536個事件,相信這個數字已經足夠大了!但是,即便如此,也只能保證用戶自定義事件不能覆蓋系統事件,並不能保證自定義事件之間不會被覆蓋。爲了解決這個問題,Qt提供了一個函數:registerEventType(),用於自定義事件的註冊。該函數簽名如下:
static int QEvent::registerEventType
( int hint = -1 );
函數是static的,因此可以使用QEvent類直接調用。函數接受一個int值,其默認值爲-1,返回值是創建的這個Type類型的值。如果hint是合法的,不會發生任何覆蓋,則會返回這個值;如果hint不合法,系統會自動分配一個合法值並返回。因此,使用這個函數即可完成type值的指定。這個函數是線程安全的,因此不必另外添加同步。
你可以在QEvent子類中添加自己的事件所需要的數據,然後進行事件的發送。Qt中提供了兩種發送方式:
- static bool QCoreApplication::sendEvent(QObjecy * receiver, QEvent * event):事件被QCoreApplication的notify()函數直接發送給receiver對象,返回值是事件處理函數的返回值。使用這個函數必須要在棧上創建對象,例如:
QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
QApplication::sendEvent(mainWindow, &event); - static bool QCoreApplication::postEvent(QObject * receiver, QEvent * event):事件被QCoreApplication追加到事件列表的最後,並等待處理,該函數將事件追加後會立即返回,並且注意,該函數是線程安全的。另外一點是,使用這個函數必須要在堆上創建對象,例如:
QApplication::postEvent(object, new MyEvent(QEvent::registerEventType(2048)));
void CustomWidget::customEvent(QEvent *event)
{
CustomEvent *customEvent = static_cast<CustomEvent *>(event);
// ....
}
CustomEvent *customEvent = static_cast<CustomEvent *>(event);
// ....
}
另外,你也可以通過重寫event()函數來處理自定義事件:
bool CustomWidget::event(QEvent
*event) {
if (event->type() == MyCustomEventType) {
CustomEvent *myEvent = static_cast<CustomEvent *>(event);
// processing...
return true;
}
return QWidget::event(event);
}
if (event->type() == MyCustomEventType) {
CustomEvent *myEvent = static_cast<CustomEvent *>(event);
// processing...
return true;
}
return QWidget::event(event);
}
這兩種辦法都是可行的。
本文出自 “豆子空間” 博客,請務必保留此出處http://devbean.blog.51cto.com/448512/232314