QtCreator快速入門(mén)第6章事件系統(tǒng)剖析課件_第1頁(yè)
QtCreator快速入門(mén)第6章事件系統(tǒng)剖析課件_第2頁(yè)
QtCreator快速入門(mén)第6章事件系統(tǒng)剖析課件_第3頁(yè)
QtCreator快速入門(mén)第6章事件系統(tǒng)剖析課件_第4頁(yè)
QtCreator快速入門(mén)第6章事件系統(tǒng)剖析課件_第5頁(yè)
已閱讀5頁(yè),還剩18頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Qt Creator快速入門(mén)第2版第6章 事件系統(tǒng)(1課時(shí))第1頁(yè),共23頁(yè)。 在Qt中,事件作為一個(gè)對(duì)象,繼承自QEvent類(lèi),常見(jiàn)的有鍵盤(pán)事件QKeyEvent、鼠標(biāo)事件QMouseEvent和定時(shí)器事件QTimerEvent等,它們與QEvent類(lèi)的繼承關(guān)系如圖所示。 第2頁(yè),共23頁(yè)。主 要 內(nèi) 容6.1 Qt中的事件6.2 鼠標(biāo)事件和滾輪事件6.3 鍵盤(pán)事件6.4 定時(shí)器事件與隨機(jī)數(shù)6.5 事件過(guò)濾器與事件的發(fā)送6.6 小結(jié)第3頁(yè),共23頁(yè)。6.1 Qt中的事件事件是對(duì)各種應(yīng)用程序需要知道的由應(yīng)用程序內(nèi)部或者外部產(chǎn)生的事情或者動(dòng)作的通稱(chēng)。在Qt中使用一個(gè)對(duì)象來(lái)表示一個(gè)事件,它繼承自Q

2、Event類(lèi)。 事件與信號(hào)并不相同,比如我們使用鼠標(biāo)點(diǎn)擊了一下界面上的按鈕,那么就會(huì)產(chǎn)生鼠標(biāo)事件QMouseEvent(不是按鈕產(chǎn)生的),而因?yàn)榘粹o被按下了,所以它會(huì)發(fā)出clicked()單擊信號(hào)(是按鈕產(chǎn)生的)。這里一般只關(guān)心按鈕的單擊信號(hào),而不用考慮鼠標(biāo)事件,但是如果要設(shè)計(jì)一個(gè)按鈕,或者當(dāng)鼠標(biāo)點(diǎn)擊按鈕時(shí)讓它產(chǎn)生別的效果,那么就要關(guān)心鼠標(biāo)事件了??梢钥吹剑录c信號(hào)是兩個(gè)不同層面的東西,它們的發(fā)出者不同,作用也不同。在Qt中,任何QObject的子類(lèi)的實(shí)例都可以接收和處理事件。 常見(jiàn)事件:鼠標(biāo)事件、鍵盤(pán)事件、定時(shí)事件、上下文菜單事件、關(guān)閉事件、拖放事件、繪制事件等。事件的處理事件的傳遞第4頁(yè)

3、,共23頁(yè)。事件的處理方法一:重新實(shí)現(xiàn)部件的paintEvent(),mousePressEvent()等事件處理函數(shù)。這是最常用也的一種方法,不過(guò)它只能用來(lái)處理特定部件的特定事件。例如前一章實(shí)現(xiàn)拖放操作,就是用的這種方法。方法二:重新實(shí)現(xiàn)notify()函數(shù)。這個(gè)函數(shù)功能強(qiáng)大,提供了完全的控制,可以在事件過(guò)濾器得到事件之前就獲得它們。但是,它一次只能處理一個(gè)事件。方法三:向QApplication對(duì)象上安裝事件過(guò)濾器。因?yàn)橐粋€(gè)程序只有一個(gè)QApplication對(duì)象,所以這樣實(shí)現(xiàn)的功能與使用notify()函數(shù)是相同的,優(yōu)點(diǎn)是可以同時(shí)處理多個(gè)事件。方法四:重新實(shí)現(xiàn)event()函數(shù)。QObj

4、ect類(lèi)的event()函數(shù)可以在事件到達(dá)默認(rèn)的事件處理函數(shù)之前獲得該事件。方法五:在對(duì)象上安裝事件過(guò)濾器。使用事件過(guò)濾器可以在一個(gè)界面類(lèi)中同時(shí)處理不同子部件的不同事件。、在實(shí)際編程中,最常用的是方法一,其次是方法五。 第5頁(yè),共23頁(yè)。重新實(shí)現(xiàn)事件處理函數(shù)例如:使用自定義的Widget作為主窗口(繼承自QWidget),然后在上 面放置一個(gè)自定義的MyLineEdit(繼承自QLineEdit)。第6頁(yè),共23頁(yè)。在MyLineEdit中添加鍵盤(pán)按下事件處理函數(shù)聲明:protected: void keyPressEvent(QKeyEvent *event);事件處理函數(shù)的定義:void

5、MyLineEdit:keyPressEvent(QKeyEvent *event) / 鍵盤(pán)按下事件 qDebug() ignore(); / 忽略該事件在Widget中添加鍵盤(pán)按下事件處理函數(shù)聲明:protected: void keyPressEvent(QKeyEvent *event);事件處理函數(shù)的定義:void Widget:keyPressEvent(QKeyEvent *event) qDebug() type() = QEvent:KeyPress) qDebug() installEventFilter(this); / 在Widget上為lineEdit安裝事件過(guò)濾器下

6、面是事件過(guò)濾器函數(shù)的定義:bool Widget:eventFilter(QObject *obj, QEvent *event) / 事件過(guò)濾器 if(obj = lineEdit) / 如果是lineEdit部件上的事件 if(event-type() = QEvent:KeyPress) qDebug() button() = Qt:LeftButton) / 如果是鼠標(biāo)左鍵按下 QCursor cursor; cursor.setShape(Qt:ClosedHandCursor); QApplication:setOverrideCursor(cursor); / 使鼠標(biāo)指針暫時(shí)改變

7、形狀 offset = event-globalPos() - pos(); / 獲取指針位置和窗口位置的差值 else if(event-button() = Qt:RightButton) / 如果是鼠標(biāo)右鍵按下 QCursor cursor(QPixmap(./yafeilinux.png); QApplication:setOverrideCursor(cursor);/ 使用自定義的圖片作為鼠標(biāo)指針 在鼠標(biāo)按下事件處理函數(shù)中,先判斷是哪個(gè)按鍵按下,如果是鼠標(biāo)左鍵,那么就更改指針的形狀,并且存儲(chǔ)當(dāng)前指針位置與窗口位置的差值。這里使用了globalPos()函數(shù)來(lái)獲取鼠標(biāo)指針的位置,這個(gè)

8、位置是指針在桌面上的位置,因?yàn)榇翱诘奈恢镁褪侵傅乃谧烂嫔系奈恢?。另外,還可以使用QMouseEvent類(lèi)的pos()函數(shù)獲取鼠標(biāo)指針在窗口中的位置。如果是鼠標(biāo)右鍵按下,那么就將指針顯示為我們自己的圖片。 第13頁(yè),共23頁(yè)。void Widget:mouseMoveEvent(QMouseEvent *event) / 鼠標(biāo)移動(dòng)事件 if(event-buttons() & Qt:LeftButton) / 這里必須使用buttons() QPoint temp; temp = event-globalPos() - offset; move(temp);/ 使用鼠標(biāo)指針當(dāng)前的位置減去差值,

9、就得到了窗口應(yīng)該移動(dòng)的位置 在鼠標(biāo)移動(dòng)事件處理函數(shù)中,先判斷是否是鼠標(biāo)左鍵按下,如果是,那么就使用前面獲取的差值來(lái)重新設(shè)置窗口的位置。因?yàn)樵谑髽?biāo)移動(dòng)時(shí),會(huì)檢測(cè)所有按下的鍵,而這時(shí)使用QMouseEvent的button()函數(shù)無(wú)法獲取哪個(gè)按鍵被按下,只能使用buttons()函數(shù),所以這里使用buttons()和Qt:LeftButton進(jìn)行按位與的方法來(lái)判斷是否是鼠標(biāo)左鍵按下。void Widget:mouseReleaseEvent(QMouseEvent *event) / 鼠標(biāo)釋放事件 QApplication:restoreOverrideCursor(); / 恢復(fù)鼠標(biāo)指針形狀在鼠

10、標(biāo)釋放函數(shù)中進(jìn)行了恢復(fù)鼠標(biāo)形狀的操作,這里使用的restoreOverrideCursor()函數(shù)要和前面的setOverrideCursor()函數(shù)配合使用。第14頁(yè),共23頁(yè)。void Widget:mouseDoubleClickEvent(QMouseEvent *event) / 鼠標(biāo)雙擊事件 if(event-button() = Qt:LeftButton) / 如果是鼠標(biāo)左鍵按下 if(windowState() != Qt:WindowFullScreen) / 如果現(xiàn)在不是全屏 setWindowState(Qt:WindowFullScreen); / 將窗口設(shè)置為全屏

11、else setWindowState(Qt:WindowNoState); / 否則恢復(fù)以前的大小 在鼠標(biāo)雙擊事件處理函數(shù)中使用setWidowState()函數(shù)來(lái)使窗口處于全屏狀態(tài)或者恢復(fù)以前的大小。第15頁(yè),共23頁(yè)。void Widget:wheelEvent(QWheelEvent *event) / 滾輪事件 if(event-delta() 0) / 當(dāng)滾輪遠(yuǎn)離使用者時(shí) ui-textEdit-zoomIn(); / 進(jìn)行放大 else / 當(dāng)滾輪向使用者方向旋轉(zhuǎn)時(shí) ui-textEdit-zoomOut(); / 進(jìn)行縮小 在滾輪事件處理函數(shù)中,使用QWheelEvent類(lèi)的d

12、elta()函數(shù)獲取了滾輪移動(dòng)的距離,每當(dāng)滾輪旋轉(zhuǎn)一下,默認(rèn)的是15度,這時(shí)delta()函數(shù)就會(huì)返回15*8即整數(shù)120。當(dāng)滾輪向遠(yuǎn)離使用者的方向旋轉(zhuǎn)時(shí),返回正值;當(dāng)向著靠近使用者的方向旋轉(zhuǎn)時(shí),返回負(fù)值。這樣便可以利用這個(gè)函數(shù)的返回值來(lái)判斷滾輪的移動(dòng)方向,從而進(jìn)行編輯器中內(nèi)容的放大或者縮小操作。第16頁(yè),共23頁(yè)。6.3 鍵盤(pán)事件 QKeyEvent類(lèi)用來(lái)描述一個(gè)鍵盤(pán)事件。當(dāng)鍵盤(pán)按鍵被按下或者被釋放時(shí),鍵盤(pán)事件便會(huì)被發(fā)送給擁有鍵盤(pán)輸入焦點(diǎn)的部件。 QKeyEvent的key()函數(shù)可以獲取具體的按鍵,需要特別說(shuō)明的是,回車(chē)鍵在這里是Qt:Key_Return;鍵盤(pán)上的一些修飾鍵,比如Ctrl

13、和Shift等,這里需要使用QKeyEvent的modifiers()函數(shù)來(lái)獲取它們。例如:void Widget:keyPressEvent(QKeyEvent *event) / 鍵盤(pán)按下事件 if(event-modifiers() = Qt:ControlModifier) / 是否按下Ctrl鍵 if(event-key() = Qt:Key_M) / 是否按下M鍵 setWindowState(Qt:WindowMaximized); / 窗口最大化 else QWidget:keyPressEvent(event);void Widget:keyReleaseEvent(QKey

14、Event *event) / 按鍵釋放事件 / 其他操作 第17頁(yè),共23頁(yè)。6.4 定時(shí)器事件與隨機(jī)數(shù) QTimerEvent類(lèi)用來(lái)描述一個(gè)定時(shí)器事件。對(duì)于一個(gè)QObject的子類(lèi),只需要使用int QObject:startTimer ( int interval )函數(shù)來(lái)開(kāi)啟一個(gè)定時(shí)器,這個(gè)函數(shù)需要輸入一個(gè)以毫秒為單位的整數(shù)作為參數(shù)來(lái)表明設(shè)定的時(shí)間,它返回一個(gè)整型編號(hào)來(lái)代表這個(gè)定時(shí)器。當(dāng)定時(shí)器溢出時(shí)就可以在timerEvent()函數(shù)中獲取該定時(shí)器的編號(hào)來(lái)進(jìn)行相關(guān)操作。 編程中更多的是使用QTimer類(lèi)來(lái)實(shí)現(xiàn)一個(gè)定時(shí)器,它提供了更高層次的編程接口,比如可以使用信號(hào)和槽,還可以設(shè)置只運(yùn)行

15、一次的定時(shí)器。所以在以后的章節(jié)中,如果使用定時(shí)器,那么一般都是使用的QTimer類(lèi)。 關(guān)于隨機(jī)數(shù),在Qt中是使用qrand()和qsrand()兩個(gè)函數(shù)實(shí)現(xiàn)的。 第18頁(yè),共23頁(yè)。通過(guò)ID使用定時(shí)器 使用QTimerEvent的timerId()函數(shù)來(lái)獲取定時(shí)器的編號(hào),然后判斷是哪一個(gè)定時(shí)器并分別進(jìn)行不同的操作。 在構(gòu)造函數(shù)中:id1 = startTimer(1000); / 開(kāi)啟一個(gè)1秒定時(shí)器,返回其IDid2 = startTimer(2000);id3 = startTimer(3000);下面是定時(shí)器事件函數(shù)的定義:void Widget:timerEvent(QTimerEven

16、t *event) if (event-timerId() = id1) / 判斷是哪個(gè)定時(shí)器 qDebug() timerId() = id2) qDebug() timer2; else qDebug() start(1000); 溢出處理:void Widget:timerUpdate() / 定時(shí)器溢出處理 QTime time = QTime:currentTime(); / 獲取當(dāng)前時(shí)間 QString text = time.toString(hh:mm); / 轉(zhuǎn)換為字符串 if(time.second() % 2) = 0) text2= ; / 每隔一秒就將“:”顯示為空格

17、 ui-lcdNumber-display(text); 這里在構(gòu)造函數(shù)中開(kāi)啟了一個(gè)1秒的定時(shí)器,當(dāng)它溢出時(shí)就會(huì)發(fā)射timeout()信號(hào),這時(shí)就會(huì)執(zhí)行我們的定時(shí)器溢出處理函數(shù)。在槽里我們獲取了當(dāng)前的時(shí)間,并且將它轉(zhuǎn)換為可以顯示的字符串。 第20頁(yè),共23頁(yè)。隨機(jī)數(shù)構(gòu)造函數(shù)里添加一行代碼:qsrand(QTime(0, 0, 0).secsTo(QTime:currentTime();然后在timerUpdate()函數(shù)里面添加如下代碼:int rand = qrand() % 300; / 產(chǎn)生300以?xún)?nèi)的正整數(shù)ui-lcdNumber-move(rand, rand); 在使用qrand()函數(shù)產(chǎn)生隨機(jī)數(shù)之前,一般要使用qsrand()函數(shù)為其設(shè)置初值,如果不設(shè)置初值,那么每次運(yùn)行程序,qrand()都會(huì)產(chǎn)生相同的一組隨機(jī)數(shù)。為了每次運(yùn)行程序時(shí),都可以產(chǎn)生不同的隨機(jī)數(shù),我們要使用qsrand()設(shè)置一個(gè)不同的初值。這里使用了QTime類(lèi)的secsTo()函數(shù),它表示兩個(gè)時(shí)間點(diǎn)之間所包含的秒數(shù),比如代碼中就是指從零點(diǎn)整到當(dāng)前時(shí)間所經(jīng)過(guò)的秒數(shù)。當(dāng)使用qrand()要獲取一個(gè)范圍內(nèi)的數(shù)值時(shí),一般是讓它與一個(gè)整數(shù)取余,比如這里與300取余,就會(huì)使所有生成的

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論