<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                #(23):自定義事件 盡管 Qt 已經提供了很多事件,但對于更加千變萬化的需求來說,有限的事件都是不夠的。例如,我要支持一種新的設備,這個設備提供一種嶄新的交互方式,那么,這種事件如何處理呢?所以,允許創建自己的事件 類型也就勢在必行。即便是不說那種非常極端的例子,在多線程的程序中,自定義事件也是尤其有用。當然,事件也并不是局限在多線程中,它可以用在單線程的程序中,作為一種對象間通訊的機制。那么,為什么我需要使用事件,而不是信號槽呢?主要原因是,事件的分發既可以是同步的,又可以是異步的,而函數的調用或者說是槽的回調總是同步的。事件的另外一個好處是,它可以使用過濾器。 Qt 自定義事件很簡單,同其它類庫的使用很相似,都是要繼承一個類進行擴展。在 Qt 中,你需要繼承的類是QEvent。 繼承QEvent類,最重要的是提供一個QEvent::Type類型的參數,作為自定義事件的類型值。回憶一下,這個 type 是我們在處理事件時用于識別事件類型的代號。比如在event()函數中,我們使用QEvent::type()獲得這個事件類型,然后與我們定義的實際類型對比。 QEvent::Type是QEvent定義的一個枚舉。因此,我們可以傳遞一個 int 值。但是需要注意的是,我們的自定義事件類型不能和已經存在的 type 值重復,否則會有不可預料的錯誤發生。因為系統會將你新增加的事件當做系統事件進行派發和調用。在 Qt 中,系統保留 0 – 999 的值,也就是說,你的事件 type 要大于 999。這種數值當然非常難記,所以 Qt 定義了兩個邊界值:QEvent::User和QEvent::MaxUser。我們的自定義事件的 type 應該在這兩個值的范圍之間。其中,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(QObject *receiver, QEvent *event); ~~~ 直接將event事件發送給receiver接受者,使用的是QCoreApplication::notify()函數。函數返回值就是事件處理函數的返回值。在事件被發送的時候,event對象并不會被銷毀。通常我們會在棧上創建event對象,例如: ~~~ QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0); QApplication::sendEvent(mainWindow, &event); ~~~ ~~~ static void QCoreApplication::postEvent(QObject *receiver, QEvent *event); ~~~ 將event事件及其接受者receiver一同追加到事件隊列中,函數立即返回。 因為 post 事件隊列會持有事件對象,并且在其 post 的時候將其 delete 掉,因此,我們必須在堆上創建event對象。當對象被發送之后,再試圖訪問event對象就會出現問題(因為 post 之后,event對象就會被 delete)。 當控制權返回到主線程循環是,保存在事件隊列中的所有事件都通過notify()函數發送出去。 事件會根據 post 的順序進行處理。如果你想要改變事件的處理順序,可以考慮為其指定一個優先級。默認的優先級是Qt::NormalEventPriority。 這個函數是線程安全的。 Qt 還提供了一個函數: ~~~ static void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type); ~~~ 這個函數的作用是,將事件隊列中的接受者為receiver,事件類似為 event_type 的所有事件立即發送給 receiver 進行處理。需要注意的是,來自窗口系統的事件并不由這個函數進行處理,而是processEvent()。詳細信息請參考 Qt API 手冊。 現在,我們已經能夠自定義事件對象,已經能夠將事件發送出去,還剩下最后一步:處理自定義事件。處理自定義事件,同前面我們講解的那些處理方法沒有什么區別。我們可以重寫QObject::customEvent()函數,該函數接收一個QEvent對象作為參數: ~~~ void QObject::customEvent(QEvent *event); ~~~ 我們可以通過轉換 event 對象類型來判斷不同的事件: ~~~ void CustomWidget::customEvent(QEvent *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); } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看