版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Qt6.2/C++程序設(shè)計(jì)與桌面應(yīng)用開發(fā)21世紀(jì)高等學(xué)校計(jì)算機(jī)類課程創(chuàng)新規(guī)劃教材–微課視頻版教材目錄第1章初識Qt框架第2章Qt開發(fā)基礎(chǔ)第3章界面設(shè)計(jì)組件第4章主框架窗口第5章對話框設(shè)計(jì)第6章事件系統(tǒng)第7章文件與數(shù)據(jù)庫第8章模型/視圖結(jié)構(gòu)第9章圖形繪制第10章多媒體編程第11章網(wǎng)絡(luò)編程第12章進(jìn)程與線程教材目錄第5章對話框設(shè)計(jì)5.1相關(guān)Qt類5.2自定義對話框5.3標(biāo)準(zhǔn)對話框5.4其他Qt窗體5.1相關(guān)Qt類對話框是GUI應(yīng)用程序中不可或缺的界面組件,它一般以頂層窗口的形式出現(xiàn)在程序的最上層,用于實(shí)現(xiàn)短期任務(wù)或者簡潔的用戶交互。Qt中的對話框由QDialog類或其子類表示,可以通過它們或其派生類來創(chuàng)建自定義的對話框,也可以直接使用Qt預(yù)定義的標(biāo)準(zhǔn)對話框。5.1.1QDialog類QDialog是Qt對話框的基類,它繼承自QWidget類。所以,對話框也是屬于Qt窗體中的一種類型。QDialog類的使用非常簡單,下面是對話框的示例。5.1.2QDialogButtonBox類QDialogButtonBox類用于表示對話框上的按鈕框,它會以適合當(dāng)前窗口樣式的布局來顯示按鈕。QDialogButtonBox類繼承自QWidget類,其部分成員函數(shù)及功能如表5.2所示。QDialogButtonBox類的使用非常簡單,先構(gòu)造一個(gè)QDialogButtonBox對象,然后調(diào)用其成員函數(shù)完成相應(yīng)功能即可,運(yùn)行效果如圖5.1所示。5.2自定義對話框Qt中的對話框分為模態(tài)對話框和非模態(tài)對話框。模態(tài)對話框,就是運(yùn)行時(shí)會阻塞同一應(yīng)用程序中其他窗口的輸入的對話框。非模態(tài)對話框,用戶可以在運(yùn)行該對話框的同時(shí)繼續(xù)進(jìn)行程序的其他操作。5.2.1模態(tài)對話框Qt中對話框有兩種級別的模態(tài),即應(yīng)用程序級別的模態(tài)和窗口級別的模態(tài),默認(rèn)是應(yīng)用程序級別的模態(tài)。Qt使用QDialog::exec()函數(shù)實(shí)現(xiàn)應(yīng)用程序級別的模態(tài)對話框,使用QDialog::open()函數(shù)實(shí)現(xiàn)窗口級別的模態(tài)對話框?!纠?.1】編寫一個(gè)Qt應(yīng)用程序,在其主窗口中添加一個(gè)文本編輯器,通過自定義的顏色對話框設(shè)置文本編輯器中的字體顏色。(1)復(fù)制教材源碼中的examp4_6項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_1.pro(2)在QtCreator中打開examp5_1項(xiàng)目,將其主框架標(biāo)題修改為“例5.1”,并在“格式”主菜單下添加一個(gè)名為“顏色”的Action。(3)給項(xiàng)目添加一個(gè)基于QDialog類的界面類,類名為“ColorDialog”。這里使用QtCreator向?qū)瑫r(shí)生成類文件及界面文件。如圖5.3所示。(4)將新對話框的標(biāo)題設(shè)置為“顏色對話框”,大小設(shè)置為200x100。(5)為第(2)步中的“顏色”Action添加信號與槽,并在槽函數(shù)中添加代碼。如下所示。(6)構(gòu)建并運(yùn)行程序。選擇程序的“格式”|“顏色”菜單命令,結(jié)果如圖5.2所示。從程序運(yùn)行結(jié)果可以看出,當(dāng)自定義的“顏色設(shè)置”對話框被激活后,程序的主框架窗口隨即變成灰色。此時(shí),不能對主窗口中的任何元素進(jìn)行操作。5.2.2非模態(tài)對話框Qt使用QDialog::show()函數(shù)來實(shí)現(xiàn)非模態(tài)對話框?qū)⒗?.1中第(5)步中的語句2修改為下面的形式:dlg->show();即可實(shí)現(xiàn)“顏色設(shè)置”對話框的非模態(tài)顯示。程序運(yùn)行結(jié)果如圖5.4所示。注意,QDialog::show()函數(shù)不會阻塞當(dāng)前線程,當(dāng)對話框顯示出來后,show()函數(shù)會立即返回,繼續(xù)執(zhí)行該語句后面的代碼。所以,要實(shí)現(xiàn)非模態(tài)對話框,對話框?qū)ο蟊仨毥⒃诙焉希簿褪且胣ew方法來構(gòu)建對話框?qū)ο?,然后調(diào)用QDialog::show()函數(shù)將其顯示。5.2.3數(shù)據(jù)交換在應(yīng)用程序中使用對話框,往往都是想通過它來傳遞數(shù)據(jù),也就是使用它與主窗口之間進(jìn)行數(shù)據(jù)的交換。1、獲取模態(tài)對話框數(shù)據(jù)在上面的例5.1應(yīng)用程序中,只是實(shí)現(xiàn)了對話框的模態(tài)與非模態(tài)顯示,并沒有真正通過該對話框來設(shè)置主窗口中文本編輯器的字體顏色。下面是一個(gè)如何從模態(tài)對話框中獲取數(shù)據(jù)的實(shí)例?!纠?.2】繼續(xù)實(shí)現(xiàn)例5.1應(yīng)用程序功能,使用“顏色設(shè)置”對話框設(shè)置主窗口中文本編輯器字體顏色。(1)復(fù)制examp5_1項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_2.pro。(2)在QtCreator中打開examp5_2項(xiàng)目,將其主框架標(biāo)題修改為“例5.2”,并在“顏色設(shè)置”對話框框中添加3個(gè)QFrame對象和3個(gè)QRadioButton對象。(3)在ColorDialog中添加一個(gè)private訪問權(quán)限的名稱為color的QColor對象,用于存儲用戶選擇的顏色;另外再添加一個(gè)public訪問權(quán)限的名稱為getColor()的成員函數(shù),該函數(shù)返回一個(gè)QColor顏色對象。(4)在類ColorDialog構(gòu)造方法中編寫代碼,對3個(gè)QFrame對象初始化,將它們填充為相應(yīng)的色塊。代碼如下:(5)編寫ColorDialog類的getColor()成員函數(shù)的實(shí)現(xiàn)代碼。(6)為ColorDialog類的3個(gè)QRadioButton對象添加clicked信號和槽函數(shù),并編寫槽函數(shù)代碼。(7)修改主窗口“格式”|“顏色”菜單命令槽函數(shù)代碼,完成文本編輯器文字顏色的設(shè)置。(8)構(gòu)建并運(yùn)行程序。2、獲取非模態(tài)對話框數(shù)據(jù)非模態(tài)對話框使用QDialog::show()函數(shù)來實(shí)現(xiàn),與QDialog::exec()函數(shù)不同的是,show()函數(shù)沒有返回值,它的作用僅僅是將對話框顯示出來而已。因此,從非模態(tài)對話框中獲取數(shù)據(jù)不能采用:dlg->show()==QDialog::Accepted這樣例5.2中類似的代碼。從非模態(tài)對話框中獲取數(shù)據(jù)最好采用信號與槽的通信機(jī)制,通過信號函數(shù)與槽函數(shù)來進(jìn)行數(shù)據(jù)的傳遞。例如,對于例5.2中的應(yīng)用程序,建立“顏色設(shè)置”對話框和主窗口之間信號與槽通信機(jī)制,當(dāng)對話框執(zhí)行某個(gè)操作(如單擊單選按鈕)時(shí),將對話框中需要傳送的數(shù)據(jù)放到信號中發(fā)送出去,主窗口中的槽函數(shù)接收這一信號并作出相應(yīng)的處理,從而實(shí)現(xiàn)數(shù)據(jù)從對話框向主窗口的傳遞。【例5.3】使用非模態(tài)對話框?qū)崿F(xiàn)例5.2中應(yīng)用程序功能。程序運(yùn)行界面如下圖所示。(1)復(fù)制examp5_2項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_3.pro。(2)在QtCreator中打開examp5_3項(xiàng)目,將其主框架標(biāo)題修改為“例5.3”。(3)在ColorDialog類的頭文件colordialog.h中添加信號聲明代碼。如下所示signals:voidsendData(QColor);(4)打開ColorDialog類的實(shí)現(xiàn)文件colordialog.cpp,修改其中3個(gè)單選按鈕的槽函數(shù)代碼。(5)在MainWindow類的頭文件mainwindow.h中添加槽函數(shù)聲明代碼。privateslots:voidreceiveData(QColor);(6)打開MainWindow類的實(shí)現(xiàn)文件mainwindow.cpp,添加槽函數(shù)的實(shí)現(xiàn)代碼。voidMainWindow::receiveData(QColorc){ui->textEdit->setTextColor(c);}(7)修改mainwindow.cpp文件中槽函數(shù)on_action_color_triggered()代碼。voidMainWindow::on_action_color_triggered(){ColorDialog*dlg=newColorDialog(this);connect(dlg,SIGNAL(sendData(QColor)),this,SLOT(receiveData(QColor)));dlg->show();}(8)構(gòu)建并運(yùn)行程序,測試結(jié)果如圖5.6所示。5.3標(biāo)準(zhǔn)對話框Qt為應(yīng)用程序設(shè)計(jì)提供了一些常用的標(biāo)準(zhǔn)對話框,如文件打開對話框、顏色選擇對話框、字體選擇對話框、數(shù)據(jù)輸入對話框以及信息提示對話框等,來實(shí)現(xiàn)應(yīng)用程序中的一些常用功能。Qt為每個(gè)標(biāo)準(zhǔn)對話框定義了相關(guān)的類,這些類全部繼承自QDialog類下面介紹幾個(gè)常用的標(biāo)準(zhǔn)對話框類:QColorDialog、QFileDialog、QFontDialog、QInputDialog
和QMessageBox5.3.1顏色對話框顏色對話框用于選取顏色值,由QColorDialog類實(shí)現(xiàn)。其界面效果如圖5.7所示?!纠?.4】使用Qt的顏色對話框?qū)崿F(xiàn)例5.1中應(yīng)用程序功能。(1)復(fù)制examp5_1項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_4.pro。(2)在QtCreator中打開examp5_4項(xiàng)目,刪除colordialog.ui界面文件,同時(shí)刪除該界面文件對應(yīng)的類文件colordialog.h和colordialog.cpp。(3)打開mainwindow.cpp文件,修改槽函數(shù)on_action_color_triggered()中的代碼。(4)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,選擇“格式”|“顏色”菜單命令,即可打開Qt的標(biāo)準(zhǔn)顏色對話框,如圖5.7所示。5.3.2文件對話框文件對話框由QFileDialog類實(shí)現(xiàn)。其界面效果如圖5.8所示?!纠?.5】使用文件對話框?qū)崿F(xiàn)例5.4中應(yīng)用程序的“文件”|“打開”菜單的部分功能,要求將用戶選擇的文件名顯示在主窗口的文本編輯器中。(1)復(fù)制examp5_4項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_5.pro。(2)在QtCreator中打開examp5_5項(xiàng)目,為其“文件”|“打開”菜單命令添加槽函數(shù),并編寫代碼。如下所示。(3)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,選擇“文件”|“打開”菜單命令,彈出的文件對話框如圖5.8所示。這里使用QFileDialog類的靜態(tài)函數(shù)getOpenFileName()來打開文件對話框,該函數(shù)的原型如下:其中,參數(shù)parent為父窗口指針;caption為對話框標(biāo)題;dir為默認(rèn)的文件路徑;filter為文件類型過濾器字符串;selectedFilter為文件類型過渡器指針;options為對話框設(shè)置。5.3.3字體對話框字體對話框由QFontDialog類實(shí)現(xiàn)。其界面效果如圖5.9所示?!纠?.6】使用字體對話框設(shè)置例5.5中應(yīng)用程序文本編輯器的字體。(1)復(fù)制examp5_5項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_6.pro。(2)在QtCreator中打開examp5_6項(xiàng)目,在項(xiàng)目主窗口中添加一個(gè)名為“字體”的Action,并將其放置在“格式”|“顏色”菜單命令的后面。為該Action添加槽函數(shù),并編寫代碼。如下所示。(3)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,選擇“文件”|“字體”菜單命令,彈出的字體對話框如圖5.9所示。5.3.4輸入對話框輸入對話框由QInputDialog類實(shí)現(xiàn)。其界面效果如圖5.10~5.14所示?!纠?.7】為例5.6應(yīng)用程序增加“數(shù)據(jù)添加”功能。程序運(yùn)行結(jié)果如圖5.15所示。(1)復(fù)制examp5_6項(xiàng)目,并將項(xiàng)目文件名稱修改為examp5_7.pro。(2)在QtCreator中打開examp5_7項(xiàng)目,在主窗口中添加“數(shù)據(jù)”|“添加”菜單命令,并為“添加”菜單項(xiàng)添加槽函數(shù),代碼如下所示。(3)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,選擇“文件”|“添加”菜單命令,就會依次彈出如圖5.10~5.14所示的5種類型的輸入對話框。5.3.5消息對話框消息對話框由QMessageBox類實(shí)現(xiàn)。其界面效果如圖5.16~5.21所示。【例5.8】編寫一個(gè)基于QWidget的應(yīng)用程序,演示消息框的使用。(1)啟動QtCreator,創(chuàng)建一個(gè)名為examp5_8的應(yīng)用程序,應(yīng)用程序主窗口基于QWidget類。(2)雙擊項(xiàng)目中的界面文件widget.ui,打開QtDesigner工具,設(shè)計(jì)應(yīng)用程序主窗口界面。在主窗口中添加6個(gè)QPushButton按鈕,并為它們設(shè)置clicked()信號的槽函數(shù)。(3)在按鈕的槽函數(shù)中編寫代碼,生成不同類型的消息框。如下所示。(4)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,分別單擊程序主窗口中的各個(gè)按鈕,對各種消息框進(jìn)行測試。5.4其他Qt窗體除了前面第3章介紹的QWidget窗體、第4章介紹的QMainWindow窗體以及本章介紹的QDialog窗體之外,在實(shí)際編程過程中還常常使用分割窗體、層疊窗體、閃屏窗體和MDI多窗體。5.4.1分隔窗體Qt的分割窗體一般用于分割窗口的布局,它所對應(yīng)的C++類為QSplitter類。其繼承關(guān)系如下圖所示?!纠?.9】一個(gè)簡單的分割窗口實(shí)例。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個(gè)名為examp5_9的應(yīng)用程序,應(yīng)用程序主窗口基于QMainWindow類。(2)雙擊界面文件mainwindow.ui,打開QtDesigner設(shè)計(jì)工具。刪除主窗口中默認(rèn)的菜單欄,并設(shè)置其他屬性。(3)打開mainwindow.h文件,在MainWindow類中添加幾個(gè)私有成員指針。如下所示。(4)打開mainwindow.cpp文件,在MainWindow類的構(gòu)造函數(shù)中編寫代碼。如下所示。(5)構(gòu)建并運(yùn)行程序,結(jié)果如圖5.25所示。程序運(yùn)行后,移動分割窗口中的分割條,可以調(diào)整各個(gè)窗口的大小。5.4.2層疊窗體層疊窗體也稱為堆棧窗體,它是一種容器組件,可以將多個(gè)窗體界面疊放在一起,當(dāng)需要時(shí)再將其顯示出來。層疊窗體一般與列表框QListWidget及下拉列表框QComboBox配合使用。層疊窗體所對應(yīng)的C++類為QStackedWidget【例5.10】一個(gè)簡單的層疊窗體應(yīng)用實(shí)例。程序運(yùn)行后,選擇左側(cè)列表框中不同的選項(xiàng)時(shí),右側(cè)顯示所選項(xiàng)內(nèi)容對應(yīng)的不同窗體。(1)啟動QtCreator,創(chuàng)建一個(gè)名為examp5_10的應(yīng)用程序,應(yīng)用程序主窗口基于QWidget類。(2)雙擊界面文件widget.ui,打開QtDesigner設(shè)計(jì)工具。在應(yīng)用程序主窗口中添加一個(gè)名為listWidget的列表框,一個(gè)名為stackedWidget的層疊窗口。在層疊窗口中添加3個(gè)QWidget窗體,并在每個(gè)page窗體中添加一個(gè)測試用的標(biāo)簽部件。主窗口采用水平布局,層疊窗口的每個(gè)page窗體采用垂直布局。最終的界面布局、子部件名稱和對應(yīng)的類如圖5.27所示。設(shè)置主窗口標(biāo)題和大小、列表框初始數(shù)據(jù)項(xiàng)、標(biāo)簽控件文本等屬性,如圖5.28所示。(3)切換到“信號與槽”編輯狀態(tài),將列表框的currentRowChanged(int)信號關(guān)聯(lián)到層疊窗口的setCurrentIndex(int)槽函數(shù)上。(4)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,當(dāng)選擇主窗口左側(cè)列表框中的選項(xiàng)時(shí),顯示層疊窗口中的相應(yīng)page窗體,如圖5.26所示。5.4.3閃屏窗體閃屏(Splash)窗口一般作為大型應(yīng)用程序的啟動畫面,用于展示軟件功能或版權(quán)等信息,當(dāng)然也可以用于登錄驗(yàn)證。閃屏窗口顯示時(shí),應(yīng)用程序會在后臺做一些比較耗時(shí)的啟動準(zhǔn)備工作,例如連接數(shù)據(jù)庫、連接網(wǎng)絡(luò)等,閃屏窗口顯示一段時(shí)間后自動關(guān)閉,然后軟件的主窗口顯示出來。在Qt中,有兩種方法可以創(chuàng)建閃屏窗口。一種是先創(chuàng)建一個(gè)QWidget或QDialog窗體,然后將其窗口類型設(shè)置為Qt::SplashScreen類型;另一種方法是直接使用QSplashScreen類。QSplashScreen類是QWidget的直接子類,它提供了載入圖片、自動設(shè)置窗體無邊框效果等功能。【例5.11】一個(gè)簡單的Splash窗體應(yīng)用實(shí)例。程序運(yùn)行后,首先顯示歡迎界面,幾秒鐘后顯示程序主窗口。(1)啟動QtCreator,創(chuàng)建一個(gè)名為examp5_11的應(yīng)用程序,應(yīng)用程序主窗口基于QWidget類。(2)為項(xiàng)目增加一個(gè)資源文件res.qrc,并在該文件中添加一個(gè)圖像文件,作為程序的splash窗體畫面。(3)打開項(xiàng)目的main.cpp主函數(shù)文件,并編寫代碼。如下所示。(4)構(gòu)造并運(yùn)行程序。5.4.4MDI窗體使用Qt不僅能夠開發(fā)單文檔(SDI,Single-documentInterface)和基于窗體(QWidget或QDialog)的應(yīng)用程序,還可以開發(fā)多文檔(MDI,Multi-documentInterface)界面的應(yīng)用程序。Qt的多文檔應(yīng)用程序需要QMdiArea和QMdiSubWindow這兩個(gè)類的支持。QMdiArea表示一個(gè)多窗口區(qū)域,它是一個(gè)MDI窗口容器,負(fù)責(zé)管理添加到這個(gè)區(qū)域中的多個(gè)子窗口。QMdiSubWindow類用于創(chuàng)建MDI的子窗口實(shí)例。QMdiSubWindow類型的子窗口通過調(diào)用QMdiArea類的addSubWindow()方法將其添加到程序的多文檔界面區(qū)域中。MDI應(yīng)用程序中的子窗口也可以直接使用QWidget類或其子類窗口。【例5.12】一個(gè)簡單的MDI窗體應(yīng)用實(shí)例。程序運(yùn)行后,每單擊一次工具欄上的“新建”按鈕,則在主窗口中產(chǎn)生一個(gè)新的子窗口。(1)啟動QtCreator,創(chuàng)建一個(gè)名為examp5_12的應(yīng)用程序,應(yīng)用程序主窗口基于QMainWindow類。(2)為項(xiàng)目增加一個(gè)新的資源文件res.qrc,并在該文件中添加2個(gè)圖標(biāo)文件,作為程序中Action的圖標(biāo)資源。(3)雙擊mainwindow.ui界面文件,打開QtDesigner設(shè)計(jì)工具,設(shè)計(jì)程序主窗口界面。刪除主窗口中的菜單欄,并添加一個(gè)工具欄;在工具欄上添加“新建”和“退出”2個(gè)按鈕;設(shè)置主窗口的標(biāo)題、大小等屬性。主窗口及其子部件對象名稱、類型如下圖所示。(4)為工具欄上的“退出”按鈕添加信號與槽,如圖5.34所示。(5)在MainWindow類中添加一個(gè)名為mdiArea的私有QMdiArea類型的指針變量。private:…QMdiArea*mdiArea;(6)在MainWindow類的構(gòu)造函數(shù)中添加初始化代碼。如下所示。(7)為工具欄上的“新建”按鈕添加槽函數(shù),并編寫代碼。(8)構(gòu)建并運(yùn)行程序。課后作業(yè)思政本章結(jié)束Qt6.2/C++程序設(shè)計(jì)與桌面應(yīng)用開發(fā)21世紀(jì)高等學(xué)校計(jì)算機(jī)類課程創(chuàng)新規(guī)劃教材–微課視頻版教材目錄第1章初識Qt框架第2章Qt開發(fā)基礎(chǔ)第3章界面設(shè)計(jì)組件第4章主框架窗口第5章對話框設(shè)計(jì)第6章事件系統(tǒng)第7章文件與數(shù)據(jù)庫第8章模型/視圖結(jié)構(gòu)第9章圖形繪制第10章多媒體編程第11章網(wǎng)絡(luò)編程第12章進(jìn)程與線程教材目錄第6章事件系統(tǒng)6.1事件機(jī)制6.2事件處理6.3鼠標(biāo)事件6.4鍵盤事件6.5定時(shí)器事件6.1事件機(jī)制Qt的GUI應(yīng)用程序是由事件驅(qū)動的,事件的描述、派發(fā)、過濾和處理等功能由其事件系統(tǒng)來實(shí)現(xiàn)。在Qt中,事件代表著用戶的某種操作或操作系統(tǒng)的某種行為,用QEvent類的子類對象來表示。例如,當(dāng)用戶在應(yīng)用程序的窗體中操作鼠標(biāo)時(shí),就會產(chǎn)生一個(gè)由QMouseEvent對象表示的鼠標(biāo)事件。6.1.1事件的描述事件是對各種應(yīng)用程序需要知道的、由應(yīng)用程序內(nèi)部或者外部產(chǎn)生的事情或者動作的通稱。在Qt中,事件用QEvent類的子類對象來表示。QEvent類及其子類的繼承關(guān)系如圖6.1所示。Qt系統(tǒng)中的每一個(gè)事件,除具有來自QEvent類的特征外,還擁有眾多的特定信息。例如,鼠標(biāo)事件QMouseEvent包含有鼠標(biāo)的位置信息,鍵盤事件QKeyEvent包含有按鍵的編碼信息。每一個(gè)QEvent子類均提供事件類型的相關(guān)附加信息,因此,每個(gè)Qt的事件處理器可以利用這些附加信息對事件進(jìn)行相應(yīng)的處理?!纠?.1】編寫一個(gè)Qt應(yīng)用程序,演示事件的表示方法。程序運(yùn)行結(jié)果如下圖所示。(1)啟動QtCreator,創(chuàng)建一個(gè)名為examp6_1的Qt應(yīng)用程序,該應(yīng)用程序主窗口基于QWidget類。(2)在Widget類文件中編寫代碼,重寫mousePressEvent()虛函數(shù)。如下所示。(3)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,在主窗口中單擊鼠標(biāo)左鍵,即可在QtCreator的輸出窗口中看到事件類型、設(shè)備類型、鼠標(biāo)按鍵類型及鼠標(biāo)位置等事件信息。如圖6.2所示。在上述代碼中,使用QMouseEvent對象event來表示鼠標(biāo)事件,QMouseEvent類是Qevent的子類。從程序輸出結(jié)果可以看出,這里的事件對象event表示的是鼠標(biāo)事件中的按鍵事件,并且按下的是鼠標(biāo)左鍵。6.1.2事件的產(chǎn)生Qt的事件代表用戶的某種操作或操作系統(tǒng)的某種行為。在Qt中,事件的主要來源是操作系統(tǒng)或Qt應(yīng)用程序。(1)由操作系統(tǒng)產(chǎn)生通常,操作系統(tǒng)把從窗口系統(tǒng)得到的消息,例如鼠標(biāo)按下、鍵盤操作等,放入系統(tǒng)的消息隊(duì)列中。Qt在事件循環(huán)的過程中讀取這些消息,先將其轉(zhuǎn)化為QEvent對象,再依次進(jìn)行處理。(2)由Qt應(yīng)用程序產(chǎn)生Qt應(yīng)用程序通過兩種方式來產(chǎn)生事件,一種是調(diào)用QApplication::postEvent()函數(shù),另一種是調(diào)用QApplication::sendEvent()函數(shù)。例如,當(dāng)需要重新繪制屏幕時(shí),在程序中調(diào)用QWidget::update()函數(shù),產(chǎn)生一個(gè)重繪事件QPaintEvent,Qt系統(tǒng)調(diào)用QApplication::postEvent()函數(shù)將其放入Qt的事件隊(duì)列中,等待被應(yīng)用程序依次處理。6.1.3事件的傳遞Qt應(yīng)用程序都是事件驅(qū)動的,啟動應(yīng)用程序也就是開啟了一個(gè)Qt事件循環(huán)。Qt的事件循環(huán)是一個(gè)無限“循環(huán)”,程序的執(zhí)行過程實(shí)際上就是不停地捕獲事件、傳遞事件、處理事件,這樣一個(gè)循環(huán)往復(fù)的過程。在Qt中,事件的傳遞從派發(fā)開始至處理后結(jié)束。事件派發(fā)從調(diào)用QApplication::notify()函數(shù)開始,因?yàn)镼Application類也是繼承自QObject類,所以應(yīng)先檢查QApplication對象。如果有事件過濾器安裝在應(yīng)用程序?qū)ο笊?,就先調(diào)用該事件過濾器。接下來,QApplication::notify()函數(shù)會過濾或合并一些事件(例如失效窗口的鼠標(biāo)事件會被過濾掉,而同一區(qū)域重復(fù)的繪圖事件會被合并)。之后,事件被送到接收對象的event()函數(shù)進(jìn)行處理?!纠?.2】編寫一個(gè)Qt應(yīng)用程序,演示事件的傳遞方式。程序運(yùn)行結(jié)果如下圖所示。(1)復(fù)制例6.1中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_2。(2)在QtCreator集成開發(fā)環(huán)境中打開項(xiàng)目examp6_2,在該項(xiàng)目中添加一個(gè)自定義的QLineEdit組件類,類名為MyLineEdit。(3)打開MyLineEdit類的頭文件及實(shí)現(xiàn)文件,添加mousePressEvent()虛函數(shù)代碼。如下所示。(4)在MyLineEdit::mousePressEvent()函數(shù)中添加如下測試代碼。qDebug()<<tr("你點(diǎn)擊了MyLineEdit部件!");(5)構(gòu)建并運(yùn)行程序。程序運(yùn)行后分別單擊主窗口和自定義的MyLindEdit組件,觀察程序的輸出結(jié)果。(6)在MyLineEdit::mousePressEvent()函數(shù)中再次添加測試代碼,如下所示。(7)重復(fù)上述第(5)步中的操作。結(jié)果如圖6.3所示。從上面程序兩次運(yùn)行后的輸出結(jié)果可以看出,Qt事件首先被派發(fā)給了指定的窗口部件,確切地說是先傳遞給獲得焦點(diǎn)的窗口部件。但是,如果該部件忽略掉該事件,那么這個(gè)事件就會傳遞給這個(gè)部件的父部件。6.1.4事件的過濾事件過濾器是Qt中一個(gè)獨(dú)特的事件處理機(jī)制,功能強(qiáng)大而且使用起來靈活方便。通過事件過濾器,可以讓一個(gè)對象監(jiān)聽或攔截另外一個(gè)對象的事件。在Qt事件系統(tǒng)中,允許在QObject或其子類的對象A上設(shè)置另一個(gè)派生自QObject的對象B來監(jiān)視將要到達(dá)A的事件。若在A對象上設(shè)置了B對象,則事件首先到達(dá)對象B,對象B根據(jù)需要僅將部分事件傳遞給A。此時(shí),對于A而言,對象B就是事件過濾器?!纠?.3】編寫一個(gè)Qt應(yīng)用程序,再次演示事件的傳遞。程序運(yùn)行結(jié)果如圖6.4所示。(1)復(fù)制例6.2中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_3。(2)在QtCreator集成開發(fā)環(huán)境中打開項(xiàng)目examp6_3,在MyLineEdit類中重寫event()函數(shù)。代碼如下所示。(3)在Widget類中重寫過濾器函數(shù)eventFilter(),代碼如下。(4)在Widget類的構(gòu)造函數(shù)中添加代碼,為自定義組件安裝過濾器。代碼如下:myLineEdit->installEventFilter(this);(5)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,單擊主窗口中的自定義組件MyLineEdit,程序輸出結(jié)果如圖6.4所示。從程序的輸出結(jié)果可以看到,事件傳遞的順序是:先是事件過濾器,然后是該部件的event()函數(shù),最后是該部件的事件處理函數(shù)。6.1.5事件的處理在Qt中有5種事件處理的方法:(1)重新實(shí)現(xiàn)一個(gè)特定事件的處理函數(shù)(2)重新實(shí)現(xiàn)QApplication::notify()函數(shù)(3)在QApplication對象上安裝事件過濾器(4)重新實(shí)現(xiàn)QObject::event()函數(shù)(5)在Qt對象上安裝事件過濾器需要注意的是,上面介紹的5種事件處理的方法,其實(shí)是事件處理的5個(gè)層次,它們的控制權(quán)是不同的。其中,方法(2)的控制權(quán)級別最高,方法(1)的控制權(quán)級別最低。6.2事件處理事件的處理是Qt程序運(yùn)行的核心操作。下面通過實(shí)例來詳細(xì)介紹Qt中5種不同層次的事件處理方法。6.2.1事件處理示例Qt應(yīng)用程序啟動以后,便進(jìn)入了一個(gè)事件循環(huán),Qt程序的執(zhí)行過程就是不斷地產(chǎn)生事件、分發(fā)事件、處理事件的過程。事件的傳遞需要經(jīng)過多個(gè)環(huán)節(jié),所以可以在每個(gè)環(huán)節(jié)中對事件進(jìn)行處理。6.2.1事件處理示例1、重新實(shí)現(xiàn)事件處理函數(shù)在例6.2的應(yīng)用程序中,通過重新實(shí)現(xiàn)鼠標(biāo)事件的mousePressEvent()函數(shù),實(shí)現(xiàn)了對自定義組件MyLineEdit的鼠標(biāo)按鍵事件的處理。下面通過重新實(shí)現(xiàn)鍵盤事件的keyPressEvent()函數(shù),來實(shí)現(xiàn)鍵盤的按鍵事件處理。【例6.4】通過實(shí)現(xiàn)keyPressEvent()函數(shù),實(shí)現(xiàn)例6.2中自定義組件的鍵盤事件處理。(1)復(fù)制例6.2中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_4。(2)在QtCreator集成開發(fā)環(huán)境中打開項(xiàng)目examp6_4,在MyLineEdit類中重寫keyPressEvent()函數(shù)。在keyPressEvent()函數(shù)中添加測試代碼。(3)構(gòu)建并運(yùn)行程序。2、重新實(shí)現(xiàn)QObject::event()函數(shù)從例6.3程序的演示結(jié)果可以看出,事件在到達(dá)目標(biāo)處理函數(shù)之前,需要經(jīng)過event()函數(shù)??梢酝ㄟ^重新實(shí)現(xiàn)該函數(shù)來對事件進(jìn)行處理。【例6.5】通過重新實(shí)現(xiàn)event()函數(shù),過濾掉例6.4程序中自定義部件的鼠標(biāo)按鍵事件。如上圖所示,在沒有過濾掉鼠標(biāo)事件時(shí),單擊自定義部件會輸出鼠標(biāo)按鈕事件的測試文本。本例要求通過重寫自定義部件的event()函數(shù),過濾掉鼠標(biāo)按鈕事件,也就是不對自定義部件的鼠標(biāo)按鈕事件進(jìn)行處理。運(yùn)行結(jié)果如下圖所示。(1)復(fù)制例6.4中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_5。(2)在QtCreator集成開發(fā)環(huán)境中打開examp6_5項(xiàng)目,雙擊打開mylineedit.h文件,右鍵鼠標(biāo),在彈出的快捷菜單中選擇“Refactor”|“InsertVirtualFunctionsofBaseClasses”菜單命令,選擇對話框列表中的event()函數(shù),并添加如下代碼。(3)構(gòu)建并運(yùn)行程序,并進(jìn)行測試。3、重新實(shí)現(xiàn)QApplication類的notify()函數(shù)在Qt應(yīng)用程序中,事件是從QApplication::notify()函數(shù)開發(fā)傳遞的,可以通過重新實(shí)現(xiàn)notify()函數(shù)來對事件進(jìn)行處理。【例6.6】通過重新實(shí)現(xiàn)notify()函數(shù),攔截例6.5程序中自定義部件的鍵盤按鍵事件。(1)復(fù)制例6.5中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_6。(2)在QtCreator集成開發(fā)環(huán)境中打開examp6_6項(xiàng)目,為該項(xiàng)目添加一個(gè)名為MyApplication的應(yīng)用程序類,其基類為QApplication。MyApplication類的頭文件及實(shí)現(xiàn)文件代碼如下:(3)重寫MyApplication類的notify()函數(shù)。(4)打開應(yīng)用程序主函數(shù)main(),將應(yīng)用程序類修改為MyApplication。(5)構(gòu)建并運(yùn)行程序。程序運(yùn)行后單擊自定義組件,或按下鍵盤上的鍵,程序均不會輸出任何信息。6.2.2事件過濾器的使用事件的處理可以通過安裝事件過濾器的方法來實(shí)現(xiàn),事件過濾器可以安裝在組件對象上,也可以安裝在應(yīng)用程序?qū)ο笊稀?、在組件對象上安裝事件過濾器從上面的例6.3可以看出,如果目標(biāo)對象使用installEventFilter()函數(shù)注冊了事件過濾器,目標(biāo)對象中的所有事件將首先發(fā)給這個(gè)監(jiān)視對象的eventFilter()函數(shù)?!纠?.7】在例6.5應(yīng)用程序中為自定義組件安裝事件過濾器,用該過濾器攔截自定義組件的鍵盤按鍵事件。(1)復(fù)制例6.5中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_7。(2)在QtCreator集成開發(fā)環(huán)境中打開examp6_7項(xiàng)目,為項(xiàng)目中的Widget類事件過濾器函數(shù)eventFilter(),并添加代碼。如下所示。(3)在Widget類的構(gòu)造函數(shù)中添加代碼,為自定義組件安裝事件過濾器。如下所示。myLineEdit->installEventFilter(this);(4)構(gòu)建并運(yùn)行程序。結(jié)果如圖6.9所示。2、在QApplication上安裝事件過濾器如果一個(gè)事件過濾器被安裝到程序中唯一的QApplication對象上,應(yīng)用程序中所有對象里的每一個(gè)事件都會在它們被送達(dá)其他事件過濾器之前首先到達(dá)這個(gè)eventFilter()函數(shù)?!纠?.8】在例6.6應(yīng)用程序中為應(yīng)用程序安裝事件過濾器,用該過濾器攔截鍵盤的按鍵事件。(1)復(fù)制例6.6中的應(yīng)用程序,將項(xiàng)目名稱修改為examp6_8。(2)在QtCreator集成開發(fā)環(huán)境中打開examp6_8項(xiàng)目,為項(xiàng)目應(yīng)用程序類MyApplication重新實(shí)現(xiàn)事件過濾器函數(shù)eventFilter(),并添加代碼。如下所示。(3)在應(yīng)用程序主函數(shù)main()中添加代碼,為應(yīng)用程序?qū)ο蟀惭b事件過濾器。如下所示。MyApplicationa(argc,argv);a.installEventFilter(&a);//添加此行代碼,安裝事件過濾器(4)將MyApplication::notify()函數(shù)中的相應(yīng)代碼注釋掉。如下所示。boolMyApplication::notify(QObject*receiver,QEvent*event){/*if(event->type()==QEvent::KeyPress){returntrue;}*/returnQApplication::notify(receiver,event);}(5)編譯并運(yùn)行程序。結(jié)果如圖6.9所示。6.3鼠標(biāo)事件Qt中的鼠標(biāo)事件用QMouseEvent對象來表示,包括鼠標(biāo)的移動,鼠標(biāo)鍵按下、松開、單擊、雙擊等。6.3.1QMouseEvent類QMouseEvent類用來表示一個(gè)鼠標(biāo)事件。通過QMouseEvent對象可以獲知鼠標(biāo)是哪個(gè)鍵按下了、鼠標(biāo)指針的當(dāng)前位置等信息。6.3.1QMouseEvent類QMouseEvent類的對象一般由系統(tǒng)創(chuàng)建,它是以事件處理虛函數(shù)的參數(shù)形式出現(xiàn)的。使用QMouseEvent對象時(shí),更多的是通過它的成員函數(shù)獲取產(chǎn)生事件的鼠標(biāo)鍵的類型,以及事件發(fā)生時(shí)鼠標(biāo)指針的位置。下面是一段有關(guān)QMouseEvent的示例代碼。上述示例代碼實(shí)現(xiàn)了通過按住鼠標(biāo)左鍵,來移動應(yīng)用程序主窗口的功能??梢钥闯?,代碼中的QMouseEvent對象指針是以鼠標(biāo)事件處理函數(shù)的參數(shù)形式呈現(xiàn)的。代碼中使用QMouseEvent類的成員函數(shù)button()和globalPosition(),來獲取按鍵的類型以及全局位置。6.3.2鼠標(biāo)事件處理鼠標(biāo)事件一般使用重新實(shí)現(xiàn)事件處理函數(shù)的方法來進(jìn)行處理。在QWidget類中定義了幾個(gè)常用的鼠標(biāo)事件處理虛函數(shù),如下所示:virtualvoidmouseDoubleClickEvent(QMouseEvent*event)virtualvoidmouseMoveEvent(QMouseEvent*event)virtualvoidmousePressEvent(QMouseEvent*event)virtualvoidmouseReleaseEvent(QMouseEvent*event)從虛函數(shù)的名稱可以看出,它們分別用于處理鼠標(biāo)雙擊、鼠標(biāo)移動、按下鼠標(biāo)按鍵和釋放鼠標(biāo)按鍵事件?!纠?.9】鼠標(biāo)事件處理示例。程序運(yùn)行結(jié)果如圖6.10和6.11所示。當(dāng)用戶操作鼠標(biāo)在特定區(qū)域內(nèi)移動時(shí),狀態(tài)欄右側(cè)會實(shí)時(shí)顯示當(dāng)前鼠標(biāo)所在的位置信息;當(dāng)用戶按下鼠標(biāo)按鍵時(shí),狀態(tài)欄左側(cè)會顯示用戶按下的鍵屬性,并顯示按鍵時(shí)的鼠標(biāo)位置;當(dāng)用戶松開鼠標(biāo)時(shí),狀態(tài)欄左側(cè)又會顯松開時(shí)的位置信息。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個(gè)名稱為examp6_9、選擇QMainWindow主窗口基類并取消“Generateform”選項(xiàng)的勾選。(2)為主框架類MainWindow添加成員屬性及方法。打開項(xiàng)目文件mainwindow.h,在類MainWindow的聲明中添加2個(gè)私有的QLabel對象labelStatus和labelMousePos,分別表示鼠標(biāo)狀態(tài)或位置信息;添加一個(gè)名為createStatus()的私有成員函數(shù),用于初始化應(yīng)用程序的狀態(tài)欄;重寫鼠標(biāo)事件處理函數(shù)mousePressEvent()、mouseReleaseEvent()、mouseDoubleClickEvent()和mouseMoveEvent()。(3)初始化主窗口,并添加新增成員函數(shù)的實(shí)現(xiàn)代碼。如下所示。(4)構(gòu)建并運(yùn)行應(yīng)用程序。程序運(yùn)行后,在應(yīng)用程序主窗口中移動鼠標(biāo),狀態(tài)欄右側(cè)的格柵中會實(shí)時(shí)顯示鼠標(biāo)的當(dāng)前坐標(biāo);分別按下鼠標(biāo)左鍵、中鍵和右鍵,在不釋放的情況下,狀態(tài)欄的左側(cè)格柵中會顯示被按下的鼠標(biāo)按鍵的類型以及鼠標(biāo)位置信息;按下鼠標(biāo)按鍵并釋放后,狀態(tài)欄的左側(cè)格柵中顯示相應(yīng)的提示信息,該信息2秒鐘后會消失。6.4鍵盤事件鍵盤事件是由用戶敲擊鍵盤設(shè)備上的按鍵觸發(fā)的,包括按鍵被按下和被釋放兩種類型。鍵盤事件用QKeyEvent類的對象來表示。6.4.1QKeyEvent類QKeyEvent類的繼承關(guān)系如圖6.1所示。通過QKeyEvent對象,可以獲知鍵盤上的哪個(gè)鍵被按下或釋放了、是否按下了像Ctrl或Shift這樣的修飾鍵等信息。下面是一段示例代碼,當(dāng)用戶按下Ctrl+M組合鍵時(shí),設(shè)置窗口為最大化顯示狀態(tài)。6.4.2鍵盤事件處理鍵盤事件通過重新實(shí)現(xiàn)事件處理函數(shù)的方法來進(jìn)行處理。在QWidget類中定義了2個(gè)鍵盤事件處理虛函數(shù):virtualvoidkeyPressEvent(QKeyEvent*event)virtualvoidkeyReleaseEvent(QKeyEvent*event)這兩個(gè)虛函數(shù)分別用于對鍵盤按鍵被按下、被釋放時(shí)的事件處理?!纠?.10】鍵盤事件處理示例。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個(gè)名稱為examp6_10,取消“Generateform”選項(xiàng)的勾選。(2)為主框架類Widget添加成員屬性及方法。打開項(xiàng)目文件widget.h,在類Widget的聲明中添加1個(gè)私有的QPushButton對象pushBtn,作為移動操作的操作對象;重寫鍵盤事件處理函數(shù)keyPressEvent()。代碼如下所示。(3)初始化主窗口,并添加成員函數(shù)的實(shí)現(xiàn)代碼。打開項(xiàng)目文件widge.cpp,在Widget類的構(gòu)造函數(shù)中添加初始化代碼;在keyPressEvent()函數(shù)中實(shí)現(xiàn)對鍵盤事件的處理。代碼如下所示。(4)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,單獨(dú)按下鍵盤上的方向鍵,或按下Ctrl+方向鍵結(jié)合鍵,可以看到主窗口中的按鈕組件會以不同的步長、向不同的方向移動。6.5定時(shí)器事件定時(shí)器事件是系統(tǒng)以固定的時(shí)間間隔發(fā)送給啟動了一個(gè)或多個(gè)定時(shí)器對象的事件。在Qt中使用定時(shí)器有兩種方法:一種是使
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年來賓道路客運(yùn)輸從業(yè)資格證考試真題保過
- 2024年客運(yùn)從業(yè)資格證考試題目和答案解析
- 2024年晉中資格證客運(yùn)題庫
- 2024年景德鎮(zhèn)客運(yùn)從業(yè)資格證考試模擬考試
- 2023屆新高考化學(xué)選考一輪總復(fù)習(xí)學(xué)案-熱點(diǎn)1 離子方程式的正誤判斷
- 2024年廣州海珠區(qū)住宅裝修工程合同
- 2024年建筑工程合同詳解版
- 《第八單元 世界經(jīng)濟(jì)的全球化趨勢》試卷及答案-高中歷史必修2-人教版-2024-2025學(xué)年
- 不同埋深下盾構(gòu)輸水隧洞預(yù)應(yīng)力雙層襯砌模型試驗(yàn)
- 提升泵站施工組織設(shè)計(jì)方案
- GA 1811.2-2022傳媒設(shè)施反恐怖防范要求第2部分:廣播電視傳輸覆蓋網(wǎng)設(shè)施
- (完整word版)漢語拼音四線三格(63格)模板
- GB/T 5226.1-2019機(jī)械電氣安全機(jī)械電氣設(shè)備第1部分:通用技術(shù)條件
- GB/T 22880-2008紙和紙板CIE白度的測定,D65/10°(室外日光)
- 10000中國普通人名大全
- 開放式小區(qū)物業(yè)管理方案(精選8篇)
- 《突發(fā)事件應(yīng)對法》理論考試題庫(含答案)
- 國家開放大學(xué)酒店管理概論作業(yè)1-4答案
- 景觀植物設(shè)計(jì)-3-各類植物的種植設(shè)計(jì)課件
- 客運(yùn)駕駛員安全指引課件
- 經(jīng)理課后答案1-4(僅作參考)
評論
0/150
提交評論