




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
第七講應用程序主窗口和
事件系統(tǒng)1主要內(nèi)容7.1主窗口框架7.2Qt中的事件7.3鼠標事件和滾輪事件7.4
鍵盤事件27.1應用程序主窗口3這一節(jié)開始接觸應用程序主窗口的相關(guān)內(nèi)容。對于日常見到的應用程序而言,它們中的許多都是基于主窗口的,主窗口中包含了菜單欄、工具欄、狀態(tài)欄和中心區(qū)域等。本章會詳細介紹主窗口的每一個部分,還會涉及到資源管理、富文本處理、拖放操作和文檔打印等相關(guān)內(nèi)容。在Qt中提供了以QMainWindow類為核心的主窗口框架,它包含了眾多相關(guān)的類:47.1主窗口框架菜單欄和工具欄中心部件Dock部件狀態(tài)欄5主窗口為建立應用程序用戶界面提供了一個框架,Qt提供了QMainWindow和與其相關(guān)的一些類來進行主窗口的管理。QMainWindow類擁有自己的布局:①菜單欄(QMenuBar)。菜單欄包含了一個下拉菜單項的列表,這些菜單項由QAction動作類實現(xiàn)。菜單欄位于主窗口的頂部,一個主窗口只能有一個菜單欄。②工具欄(QToolBar)。工具欄一般用于顯示一些常用的菜單項目,它也可以插入其他窗口部件,并且工具欄是可以移動的。一個主窗口可以擁有多個工具欄。③中心部件(CentralWidget)。在主窗口的中心區(qū)域可以放入一個窗口部件作為中心部件,它是應用程序的主要功能實現(xiàn)區(qū)域。一個主窗口只能擁有一個中心部件。④Dock部件(QDockWidget)。Dock部件常被稱為??看翱?,因為它可以??吭谥行牟考乃闹?。它用來放置一些部件來實現(xiàn)一些功能,就像個工具箱一樣。一個主窗口可以擁有多個Dock部件。⑤狀態(tài)欄(QStatusBar)。狀態(tài)欄用于顯示程序的一些狀態(tài)信息,它在主窗口的最底部。一個主窗口只能擁有一個狀態(tài)欄。6在設計器中給菜單欄、工具欄添加動作
在QtCreator中雙擊項目中的.ui文件進入設計模式。添加菜單,雙擊左上角的“在這里輸入”,修改為“文件(&F)”,這里要使用英文半角的括號,“&F”被稱為加速鍵,表明程序運行時,可以按下Alt+F鍵來激活該菜單。修改完成后,按下回車鍵,并在彈出的下拉菜單中,將第一項改為“新建文件(&N)”并按下回車鍵。這時可以看到在下面的Action編輯器中已經(jīng)有了“新建文件”動作。在這里用鼠標點擊該動作,將其拖入菜單欄下面的工具欄中。7菜單欄QMenuBar類提供了一個水平的菜單欄,在QMainWindow中可以直接獲取它的默認存在的菜單欄,向其中添加QMenu類型的菜單對象,然后向彈出菜單中添加QAction類型的動作對象。在QMenu中還提供了間隔器,可以在設計器中向添加菜單那樣直接添加間隔器,或者在代碼中使用addSeparator()函數(shù)來添加,它是一條水平線,可以將菜單分成幾組,使得布局很整齊。在應用程序中很多普通的命令都是通過菜單來實現(xiàn)的,而我們也希望能將這些菜單命令放到工具欄中,以方便使用。QAction就是這樣一種命令動作,它可以同時放在菜單和工具欄中。一個QAction動作包含了一個圖標,一個菜單顯示文本,一個快捷鍵,一個狀態(tài)欄顯示文本,一個“What’sThis?”顯示文本和一個工具提示文本。這些都可以在構(gòu)建QAction類對象時在構(gòu)造函數(shù)中指定。另外還可以設置QAction的checkable屬性,如果指定這個動作的checkable為true,那么當選中這個菜單時就會在它的前面顯示“√”之類的表示選中狀態(tài)的符號,如果該菜單有圖標,那么就會用線框?qū)D標圍住,用來表示該動作被選中了。8代碼方式添加菜單//添加編輯菜單QMenu*editMenu=ui->menuBar->addMenu(tr("編輯(&E)"));//添加打開菜單QAction*action_Open=editMenu->addAction(QIcon(“../images/open.png"),tr("打開文件(&O)"));//設置快捷鍵action_Open->setShortcut(QKeySequence("Ctrl+O"));//在工具欄中添加動作ui->mainToolBar->addAction(action_Open);
9工具欄工具欄QToolBar類提供了一個包含了一組控件的可以移動的面板。在上面已經(jīng)看到可以將QAction對象添加到工具欄中,它默認只是顯示一個動作的圖標,這個可以在QToolBar的屬性欄中進行更改。在設計器中可以查看QToolBar的屬性欄,其中toolButtonStyle屬性設置圖標和相應文本的顯示及其相對位置等;movabel屬性設置狀態(tài)欄是否可以移動;allowedArea設置允許停靠的位置;iconsize屬性設置圖標的大??;floatable屬性設置是否可以懸浮。10在工具欄中添加部件QToolButton*toolBtn=newQToolButton(this);//創(chuàng)建QToolButtontoolBtn->setText(tr("顏色"));QMenu*colorMenu=newQMenu(this);//創(chuàng)建一個菜單colorMenu->addAction(tr("紅色"));colorMenu->addAction(tr("綠色"));toolBtn->setMenu(colorMenu);//添加菜單toolBtn->setPopupMode(QToolButton::MenuButtonPopup);//設置彈出模式ui->mainToolBar->addWidget(toolBtn);//向工具欄添加QToolButton按鈕QSpinBox*spinBox=newQSpinBox(this);//創(chuàng)建QSpinBoxui->mainToolBar->addWidget(spinBox);//向工具欄添加QSpinBox部件11資源系統(tǒng)Qt資源系統(tǒng)是一個獨立于平臺的(跟使用的操作系統(tǒng)無關(guān))用于在可執(zhí)行文件中存儲二進制文件的機制??梢宰屝枰奈募▓D片、文本等)包含到程序編程生成的可執(zhí)行文件(例如exe文件)中。保證了程序中使用的文件不會丟失、不會因為存放路徑而導致程序運行錯誤。12中心部件在主窗口的中心區(qū)域可以放置一個中心部件,它一般是一個編輯器或者瀏覽器。這里支持單文檔部件,也支持多文檔部件。一般的,會在這里放置一個部件,然后使用布局管理器使其充滿整個中心區(qū)域,并可以隨著窗口的大小變化而改變大小。例如在設計模式中,往中心區(qū)域拖入一個TextEdit,然后點擊界面,按下Ctrl+G使其處于一個柵格布局中。效果如下。13Dock部件QDockWidget類提供了這樣一個部件,它可以??吭赒MainWindow中也可以懸浮起來作為桌面頂級窗口,我們稱它為Dock部件或者停靠窗口。Dock部件一般用于存放其他一些部件來實現(xiàn)一些特殊功能,就像一個工具箱一樣。它在主窗口中可以??吭谥行牟考乃闹埽部梢詰腋∑饋?,被拖動到任意的地方,還可以被關(guān)閉或隱藏起來。一個Dock部件包含一個標題欄和一個內(nèi)容區(qū)域,可以向Dock部件中放入任何部件。
例如:在設計模式中向中心區(qū)域拖入一個DockWidget部件,然后再向Dock中隨意拖入幾個部件,比如這里拖入一個PushButton和一個FontComboBox。然后在dockWidget的屬性欄中更改其windowTitle為“工具箱”。14狀態(tài)欄QStatusBar類提供了一個水平條,用來顯示狀態(tài)信息。QMainWindow中默認提供了一個狀態(tài)欄。狀態(tài)信息可以被分為三類:臨時信息,如一般的提示信息;正常信息,如顯示頁數(shù)和行號;永久信息,如顯示版本號或者日期。可以使用showMessage()函數(shù)來顯示一個臨時消息,它會出現(xiàn)在狀態(tài)欄的最左邊。一般用addWidget()函數(shù)添加一個QLabel到狀態(tài)欄上用于顯示正常信息,它會生成到狀態(tài)欄的最左邊,可能會被臨時消息所掩蓋。如果要顯示永久信息,要使用addPermanentWidget()函數(shù)來添加一個如QLabel一樣的可以顯示信息的部件,它會生成在狀態(tài)欄的最右端,不會被臨時消息所掩蓋。在狀態(tài)欄的最右端,還有一個QSizeGrip部件,用來調(diào)整窗口的大小,可以使用setSizeGripEnabled()函數(shù)來禁用它。15目前的設計器中還不支持直接向狀態(tài)欄中拖放部件,所以需要使用代碼來生成。例如://顯示臨時消息,顯示2000毫秒即2秒鐘ui->statusBar->showMessage(tr("歡迎使用多文檔編輯器"),2000);//創(chuàng)建標簽,設置標簽樣式并顯示信息,將其以永久部件的形式添加到狀態(tài)欄QLabel*permanent=newQLabel(this);permanent->setFrameStyle(QFrame::Box|QFrame::Sunken);permanent->setText("");ui->statusBar->addPermanentWidget(permanent); 此時運行程序,可以發(fā)現(xiàn)“歡迎使用多文檔編輯器”字符串在顯示一會兒后就自動消失了,而“”一直顯示在狀態(tài)欄最右端。16練習寫字板界面的設計17在Qt中,事件作為一個對象,繼承自QEvent類,常見的有鍵盤事件QKeyEvent、鼠標事件QMouseEvent和定時器事件QTimerEvent等,它們與QEvent類的繼承關(guān)系如圖所示。187.2Qt中的事件事件是對各種應用程序需要知道的由應用程序內(nèi)部或者外部產(chǎn)生的事情或者動作的通稱。在Qt中使用一個對象來表示一個事件,它繼承自QEvent類。事件與信號并不相同,比如我們使用鼠標點擊了一下界面上的按鈕,那么就會產(chǎn)生鼠標事件QMouseEvent(不是按鈕產(chǎn)生的),而因為按鈕被按下了,所以它會發(fā)出clicked()單擊信號(是按鈕產(chǎn)生的)。這里一般只關(guān)心按鈕的單擊信號,而不用考慮鼠標事件,但是如果要設計一個按鈕,或者當鼠標點擊按鈕時讓它產(chǎn)生別的效果,那么就要關(guān)心鼠標事件了??梢钥吹?,事件與信號是兩個不同層面的東西,它們的發(fā)出者不同,作用也不同。在Qt中,任何QObject的子類的實例都可以接收和處理事件。常見事件:鼠標事件、鍵盤事件、定時事件、上下文菜單事件、關(guān)閉事件、拖放事件、繪制事件等。事件的處理事件的傳遞19事件的處理方法一:重新實現(xiàn)部件的paintEvent(),mousePressEvent()等事件處理函數(shù)。這是最常用也的一種方法,不過它只能用來處理特定部件的特定事件。例如前一章實現(xiàn)拖放操作,就是用的這種方法。方法二:重新實現(xiàn)notify()函數(shù)。這個函數(shù)功能強大,提供了完全的控制,可以在事件過濾器得到事件之前就獲得它們。但是,它一次只能處理一個事件。方法三:向QApplication對象上安裝事件過濾器。因為一個程序只有一個QApplication對象,所以這樣實現(xiàn)的功能與使用notify()函數(shù)是相同的,優(yōu)點是可以同時處理多個事件。方法四:重新實現(xiàn)event()函數(shù)。QObject類的event()函數(shù)可以在事件到達默認的事件處理函數(shù)之前獲得該事件。方法五:在對象上安裝事件過濾器。使用事件過濾器可以在一個界面類中同時處理不同子部件的不同事件。在實際編程中,最常用的是方法一,其次是方法五。
20重新實現(xiàn)事件處理函數(shù)例如:使用自定義的Widget作為主窗口(繼承自QWidget),然后在上面放置一個自定義的MyLineEdit(繼承自QLineEdit)。21在MyLineEdit中添加鍵盤按下事件處理函數(shù)聲明:protected:voidkeyPressEvent(QKeyEvent*event);事件處理函數(shù)的定義:voidMyLineEdit::keyPressEvent(QKeyEvent*event)//鍵盤按下事件{qDebug()<<tr("MyLineEdit鍵盤按下事件");QLineEdit::keyPressEvent(event);//執(zhí)行QLineEdit類的默認事件處理event->ignore();//忽略該事件}在Widget中添加鍵盤按下事件處理函數(shù)聲明:protected:voidkeyPressEvent(QKeyEvent*event);事件處理函數(shù)的定義:voidWidget::keyPressEvent(QKeyEvent*event){qDebug()<<tr("Widget鍵盤按下事件");}22從這個例子中可以看到,事件是先傳遞給指定窗口部件的,這里確切的說應該是先傳遞給獲得焦點的窗口部件的。但是如果該部件忽略掉該事件,那么這個事件就會傳遞給這個部件的父部件。在重新實現(xiàn)事件處理函數(shù)時,一般要調(diào)用父類的相應的事件處理函數(shù)來實現(xiàn)默認的操作。23安裝事件過濾器在MyLineEdit中添加函數(shù)聲明:boolevent(QEvent*event);該函數(shù)定義:boolMyLineEdit::event(QEvent*event)//事件{if(event->type()==QEvent::KeyPress)qDebug()<<tr("MyLineEdit的event()函數(shù)");returnQLineEdit::event(event);//執(zhí)行QLineEdit類event()函數(shù)的默認操作}在MyLineEdit的event()函數(shù)中使用了QEvent的type()函數(shù)來獲取事件的類型,如果是鍵盤按下事件QEvent::KeyPress,則輸出信息。因為event()函數(shù)具有bool型的返回值,所以在該函數(shù)的最后要使用return語句,這里一般是返回父類的event()函數(shù)的操作結(jié)果。24在Widget中進行事件過濾器函數(shù)的聲明:booleventFilter(QObject*obj,QEvent*event);在widget.cpp文件中的構(gòu)造函數(shù)的最后添上一行代碼:lineEdit->installEventFilter(this);//在Widget上為lineEdit安裝事件過濾器下面是事件過濾器函數(shù)的定義:boolWidget::eventFilter(QObject*obj,QEvent*event)//事件過濾器{if(obj==lineEdit){//如果是lineEdit部件上的事件if(event->type()==QEvent::KeyPress)qDebug()<<tr("Widget的事件過濾器");}returnQWidget::eventFilter(obj,event);}在事件過濾器中,先判斷該事件的對象是不是lineEdit,如果是,再判斷事件類型。最后返回了QWidget類默認的事件過濾器的執(zhí)行結(jié)果。
25事件的傳遞
在每個程序的main()函數(shù)的最后,都會調(diào)用QApplication類的exec()函數(shù),它會使Qt應用程序進入事件循環(huán),這樣就可以使應用程序在運行時接收發(fā)生的各種事件。一旦有事件發(fā)生,Qt便會構(gòu)建一個相應的QEvent子類的對象來表示它,然后將它傳遞給相應的QObject對象或其子對象。從前面的例子可以看到,事件的傳遞順序是這樣的:先是事件過濾器,然后是該部件的event()函數(shù),最后是該部件的事件處理函數(shù)。這里還要注意,event()函數(shù)和事件處理函數(shù),是在該部件內(nèi)進行重新定義的,而事件過濾器卻是在該部件的父部件中進行定義的。267.3鼠標事件和滾輪事件
QMouseEvent類用來表示一個鼠標事件,當在窗口部件中按下鼠標或者移動鼠標指針時,都會產(chǎn)生鼠標事件。利用QMouseEvent類可以獲知鼠標是哪個鍵按下了,還有鼠標指針的當前位置等信息。通常是重定義部件的鼠標事件處理函數(shù)來進行一些自定義的操作。QWheelEvent類用來表示鼠標滾輪事件,在這個類中主要是獲取滾輪移動的方向和距離。下面來看一個實際的例子,這個例子要實現(xiàn)的效果是:可以在界面上按著鼠標左鍵來拖動窗口,雙擊鼠標左鍵來使其全屏,按著鼠標右鍵則使指針變?yōu)橐粋€自定義的圖片,而使用滾輪則可以放大或者縮小編輯器中的內(nèi)容。27voidWidget::mousePressEvent(QMouseEvent*event)//鼠標按下事件{if(event->button()==Qt::LeftButton){//如果是鼠標左鍵按下QCursorcursor;cursor.setShape(Qt::ClosedHandCursor);QApplication::setOverrideCursor(cursor);//使鼠標指針暫時改變形狀offset=event->globalPos()-pos();//獲取指針位置和窗口位置的差值}elseif(event->button()==Qt::RightButton){//如果是鼠標右鍵按下QCursorcursor(QPixmap(":images/new.png"));QApplication::setOverrideCursor(cursor);//使用自定義的圖片作為鼠標指針}}在鼠標按下事件處理函數(shù)中,先判斷是哪個按鍵按下,如果是鼠標左鍵,那么就更改指針的形狀,并且存儲當前指針位置與窗口位置的差值。這里使用了globalPos()函數(shù)來獲取鼠標指針的位置,這個位置是指針在桌面上的位置,因為窗口的位置就是指的它在桌面上的位置。另外,還可以使用QMouseEvent類的pos()函數(shù)獲取鼠標指針在窗口中的位置。如果是鼠標右鍵按下,那么就將指針顯示為我們自己的圖片。
28voidWidget::mouseMoveEvent(QMouseEvent*event)//鼠標移動事件{if(event->buttons()&Qt::LeftButton){//這里必須使用buttons()QPointtemp;temp=event->globalPos()-offset;move(temp);//使用鼠標指針當前的位置減去差值,就得到了窗口應該移動的位置}} 在鼠標移動事件處理函數(shù)中,先判斷是否是鼠標左鍵按下,如果是,那么就使用前面獲取的差值來重新設置窗口的位置。因為在鼠標移動時,會檢測所有按下的鍵,而這時使用QMouseEvent的button()函數(shù)無法獲取哪個按鍵被按下,只能使用buttons()函數(shù),所以這里使用buttons()和Qt::LeftButton進行按位與的方法來判斷是否是鼠標左鍵按下。voidWidget::mouseReleaseEvent(QMouseEvent*event)//鼠標釋放事件{QApplication::restoreOverrideCursor();//恢復鼠標指針形狀} 在鼠標釋放函數(shù)中進行了恢復鼠標形狀的操作,這里使用的restoreOverrideCursor()函數(shù)要和前面的setOverrideCursor()函數(shù)配合使用。29voidWidget::mouseDoubleClickEvent(QMouseEvent*event)//鼠標雙擊事件{if(event->button()==Qt::LeftButton){//如果是鼠標左鍵按下if(windowState()!=Qt::WindowFullScreen)//如果現(xiàn)在不是全屏setWindowState(Qt::WindowFullScreen);//將窗口設置為全屏elsesetWindowState(Qt::WindowNoState);//否則恢復以前的大小}} 在鼠標雙擊事件處理函數(shù)中使用setWidowState()函數(shù)來使窗口處于全屏狀態(tài)或者恢復以前的大小。30voidWidget::wheelEvent(QWheelEvent*event)//滾輪事件{if(e
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030中國高爾夫鞋服行業(yè)市場發(fā)展分析及前景趨勢與投資研究報告
- 馬工學管理學敏捷管理實踐試題及答案
- 娛樂與教育結(jié)合試題及答案
- 2025-2030中國香連化滯丸行業(yè)運行環(huán)境分析及競爭策略分析研究報告
- 2025-2030中國香檳酒市場深度調(diào)查研究報告
- 2025-2030中國飼料級磷酸鈣行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 2025-2030中國食用水箱行業(yè)市場發(fā)展現(xiàn)狀及商業(yè)模式與投資發(fā)展研究報告
- 領導力與馬工學的創(chuàng)新性思考試題及答案
- 電子商務中職教師資格證考試內(nèi)容試題及答案
- 監(jiān)理行為規(guī)范的重要性試題及答案
- 《電費回收》課件
- 小學語文分層作業(yè)講座
- 公司安全生產(chǎn)事故隱患內(nèi)部報告獎勵工作制度
- 做枝花兒送媽媽(課件)三年級下冊勞動人教版
- 2024年世界職業(yè)院校技能大賽中職組“短視頻制作組”賽項考試題庫(含答案)
- 《心理壓力與調(diào)適》課件
- 眼科診所安全消毒規(guī)程
- 水利信息化數(shù)據(jù)中心及軟件系統(tǒng)單元工程質(zhì)量驗收評定表、檢查記錄
- 新員工培訓:廉潔從業(yè)
- 專題05 特殊的平行四邊形中的最值模型之胡不歸模型(原卷版)
- 【人教版】《勞動教育》五上 勞動項目三《制作扇子》 課件
評論
0/150
提交評論