版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
《QtCreator快速入門》第2版第5章應用程序主窗口(3課時)這一章開始接觸應用程序主窗口的相關內(nèi)容。對于日常見到的應用程序而言,它們中的許多都是基于主窗口的,主窗口中包含了菜單欄、工具欄、狀態(tài)欄和中心區(qū)域等。本章會詳細介紹主窗口的每一個部分,還會涉及到資源管理、富文本處理、拖放操作和文檔打印等相關內(nèi)容。在Qt中提供了以QMainWindow類為核心的主窗口框架,它包含了眾多相關的類:主要內(nèi)容5.1主窗口框架(第1課時)5.2富文本處理(第2課時)5.3拖放操作(第3課時)5.4打印文檔(第3課時)5.5小結(jié)(第3課時)5.1主窗口框架菜單欄和工具欄使用資源系統(tǒng)中心部件Dock部件狀態(tài)欄自定義菜單主窗口為建立應用程序用戶界面提供了一個框架,Qt提供了QMainWindow和與其相關的一些類來進行主窗口的管理。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)欄。在設計器中給菜單欄、工具欄添加動作
在QtCreator中雙擊項目中的.ui文件進入設計模式。添加菜單,雙擊左上角的“在這里輸入”,修改為“文件(&F)”,這里要使用英文半角的括號,“&F”被稱為加速鍵,表明程序運行時,可以按下Alt+F鍵來激活該菜單。修改完成后,按下回車鍵,并在彈出的下拉菜單中,將第一項改為“新建文件(&N)”并按下回車鍵。這時可以看到在下面的Action編輯器中已經(jīng)有了“新建文件”動作。在這里用鼠標點擊該動作,將其拖入菜單欄下面的工具欄中。菜單欄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標圍住,用來表示該動作被選中了。代碼方式添加菜單//添加編輯菜單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);
工具欄工具欄QToolBar類提供了一個包含了一組控件的可以移動的面板。在上面已經(jīng)看到可以將QAction對象添加到工具欄中,它默認只是顯示一個動作的圖標,這個可以在QToolBar的屬性欄中進行更改。在設計器中可以查看QToolBar的屬性欄,其中toolButtonStyle屬性設置圖標和相應文本的顯示及其相對位置等;movabel屬性設置狀態(tài)欄是否可以移動;allowedArea設置允許??康奈恢?;iconsize屬性設置圖標的大?。籪loatable屬性設置是否可以懸浮。在工具欄中添加部件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部件資源系統(tǒng)Qt資源系統(tǒng)是一個獨立于平臺的(跟使用的操作系統(tǒng)無關)用于在可執(zhí)行文件中存儲二進制文件的機制??梢宰屝枰奈募▓D片、文本等)包含到程序編程生成的可執(zhí)行文件(例如exe文件)中。保證了程序中使用的文件不會丟失、不會因為存放路徑而導致程序運行錯誤。在QtCreator中添加資源第一步,添加Qt資源文件。往項目中添加新文件,選擇Qt分類中的Qt資源文件,文件名稱改為“myImage”,其他選項默認即可。第二步,添加資源。建立好資源文件后會默認進入資源管理界面,就是新建的myImage.qrc文件中。現(xiàn)在先到項目文件夾myMainWindow中新建一個名為“images”的文件夾,并在其中放入兩張圖標圖片,比如這里放入了一個“new.png”和一個“open.png”圖片。(注意:Qt的資源系統(tǒng)要求資源文件必須放在與qrc文件同級或子級目錄下,如果放在其他地方,當添加資源時會提示將文件復制到有效的位置。)然后回到QtCreator中,在資源管理界面,按下“添加”按鈕,選擇“添加前綴”,然后將屬性欄中的前綴改為“/myImage”,再點擊“添加”按鈕,選擇“添加文件”,在彈出的對話框中進入到前面新建的images文件夾中,選中那兩張圖片,點擊打開即可。這時myImage.qrc文件中就出現(xiàn)了添加的圖片的列表。最后按下Ctrl+S快捷鍵,保存對文件的修改(注意:這一點很重要,如果沒有保存,在下面使用圖片時將看不到圖片)。第三步,使用圖片。在設計模式Action編輯器中雙擊“新建文件”動作,這時會彈出編輯動作對話框。在其中將對象名稱改為“action_New”,工具提示改為“新建文件”,然后按下圖標后面的按鈕,進入選擇資源界面。第一次進入該界面還沒有顯示可用的資源,需要按下左上角的重新加載綠色箭頭圖標,這時圖片資源就顯示出來了。這里選擇new.png圖片,然后按下確定按鈕。如果在編寫代碼時使用new.png圖片,那么就可以將其路徑指定為“:/myImage/images/new.png”,前綴“/myImage”是添加資源時手動設置的。資源文件介紹在使用資源時添加的qrc資源文件其實是一個XML格式的文本文件,進入編輯模式,在myImage.qrc文件上點擊鼠標右鍵,選擇“用…打開”→“PlainTextEditor”,這時就會看到myImage.qrc的內(nèi)容如下:<RCC><qresourceprefix="/myImage"><file>images/new.png</file><file>images/open.png</file></qresource></RCC>在這里指明了文件類型為RCC,表明是Qt資源文件。然后是資源前綴,在下面羅列了添加的圖片的路徑。當往項目中添加了一個資源文件時,會自動往工程文件myMainW中添加代碼:RESOURCES+=\myImage.qrc這表明項目中使用了資源文件myImage.qrc。中心部件在主窗口的中心區(qū)域可以放置一個中心部件,它一般是一個編輯器或者瀏覽器。這里支持單文檔部件,也支持多文檔部件。一般的,會在這里放置一個部件,然后使用布局管理器使其充滿整個中心區(qū)域,并可以隨著窗口的大小變化而改變大小。例如在設計模式中,往中心區(qū)域拖入一個TextEdit,然后點擊界面,按下Ctrl+G使其處于一個柵格布局中。效果如下。Dock部件QDockWidget類提供了這樣一個部件,它可以??吭赒MainWindow中也可以懸浮起來作為桌面頂級窗口,我們稱它為Dock部件或者??看翱?。Dock部件一般用于存放其他一些部件來實現(xiàn)一些特殊功能,就像一個工具箱一樣。它在主窗口中可以停靠在中心部件的四周,也可以懸浮起來,被拖動到任意的地方,還可以被關閉或隱藏起來。一個Dock部件包含一個標題欄和一個內(nèi)容區(qū)域,可以向Dock部件中放入任何部件。
例如:在設計模式中向中心區(qū)域拖入一個DockWidget部件,然后再向Dock中隨意拖入幾個部件,比如這里拖入一個PushButton和一個FontComboBox。然后在dockWidget的屬性欄中更改其windowTitle為“工具箱”。狀態(tài)欄QStatusBar類提供了一個水平條,用來顯示狀態(tài)信息。QMainWindow中默認提供了一個狀態(tài)欄。狀態(tài)信息可以被分為三類:臨時信息,如一般的提示信息;正常信息,如顯示頁數(shù)和行號;永久信息,如顯示版本號或者日期??梢允褂胹howMessage()函數(shù)來顯示一個臨時消息,它會出現(xiàn)在狀態(tài)欄的最左邊。一般用addWidget()函數(shù)添加一個QLabel到狀態(tài)欄上用于顯示正常信息,它會生成到狀態(tài)欄的最左邊,可能會被臨時消息所掩蓋。如果要顯示永久信息,要使用addPermanentWidget()函數(shù)來添加一個如QLabel一樣的可以顯示信息的部件,它會生成在狀態(tài)欄的最右端,不會被臨時消息所掩蓋。在狀態(tài)欄的最右端,還有一個QSizeGrip部件,用來調(diào)整窗口的大小,可以使用setSizeGripEnabled()函數(shù)來禁用它。目前的設計器中還不支持直接向狀態(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)欄最右端。自定義菜單
Qt中的QWidgetAction類可以實現(xiàn)自定義菜單的功能。為了實現(xiàn)自定義菜單,需要新建一個類,它繼承自QWidgetAction類,并且在其中重新實現(xiàn)createWidget()函數(shù)。自學內(nèi)容:寫一個程序,實現(xiàn)了這樣一個菜單:它包含一個標簽和一個行編輯器,可以在行編輯器中輸入字符串,然后按下回車鍵,就可以自動將字符串輸入到中心部件文本編輯器中。
5.2富文本處理富文本(RichText)或者叫做富文本格式,簡單來說就是在文檔中可以使用多種格式,比如字體顏色、圖片和表格等等。它是與純文本(PlainText)相對而言的,比如Windows上的記事本就是純文本編輯器,而Word就是富文本編輯器。富文本文檔結(jié)構(gòu)文本塊表格、列表與圖片查找功能語法高亮與HTML在Qt中提供了對富文本處理的支持。Qt中對富文本的處理分為了編輯操作和只讀操作兩種方式。編輯操作是使用基于光標的一些接口函數(shù),這樣更好的模擬了用戶的編輯操作,更加容易理解,而且不會丟失底層的文檔框架;而對于文檔結(jié)構(gòu)的概覽,使用了只讀的分層次的接口函數(shù),它們有利于文檔的檢索和輸出。
對于文檔的讀取和編輯要使用不同方面的兩組接口。文檔的光標主要基于QTextCursor類文檔的框架主要基于QTextDocument類。一個富文本文檔的結(jié)構(gòu)被分為了幾種元素來表示,分別是框架(QTextFrame)、文本塊(QTextBlock)、表格(QTextTable)和列表(QTextList)。每種元素的格式又使用相應的format類來表示,它們分別是框架格式(QTextFrameFormat)、文本塊格式(QTextBlockFormat)、表格格式(QTextTableFormat)和列表格式(QTextListFormat),這些格式一般在編輯文檔時使用,所以它們常和QTextCursor類配合使用。
富文本文檔結(jié)構(gòu)因為QTextEdit類就是一個富文本編輯器,所以在構(gòu)建QTextEdit類的對象時就已經(jīng)構(gòu)建了一個QTextDocument類對象和一個QTextCursor類對象,只需調(diào)用它們進行相應的操作即可。一個空的文檔包含了一個根框架(Rootframe),這個根框架又包含了一個空的文本塊(Block)。框架將一個文檔分為多個部分,在根框架里可以再添加文本塊、子框架和表格等。
設置根框架QTextDocument*document=ui->textEdit->document();//獲取文檔對象QTextFrame*rootFrame=document->rootFrame();//獲取根框架QTextFrameFormatformat;//創(chuàng)建框架格式format.setBorderBrush(Qt::red);//邊界顏色format.setBorder(3);//邊界寬度rootFrame->setFrameFormat(format);//框架使用格式添加子框架QTextFrameFormatframeFormat;frameFormat.setBackground(Qt::lightGray);//設置背景顏色frameFormat.setMargin(10);//設置邊距frameFormat.setPadding(5);//設置填襯frameFormat.setBorder(2);//設置邊框樣式frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted);QTextCursorcursor=ui->textEdit->textCursor();//獲取光標cursor.insertFrame(frameFormat);//在光標處插入框架文本塊 文本塊QTextBlock類為文本文檔QTextDocument提供了一個文本片段(QTextFragment)的容器。一個文本塊可以看做是一個段落,但是它不能使用回車換行,因為一個回車換行就表示創(chuàng)建一個新的文本塊。QTextBlock提供了只讀接口,它是前面提到的文檔分層次的接口的一部分,如果QTextFrame看做是一層,那么其中的QTextBlock就是另一層。文本塊的格式由QTextBlockFormat類來處理,它主要涉及對齊方式,文本塊四周的邊白,縮進等內(nèi)容。而文本塊中的文本內(nèi)容的格式,比如字體大小、加粗、下劃線等內(nèi)容,則由QTextCharFormat類來設置。遍歷框架QTextDocument*document=ui->textEdit->document();QTextFrame*frame=document->rootFrame();QTextFrame::iteratorit;//建立QTextFrame類的迭代器for(it=frame->begin();!(it.atEnd());++it){QTextFrame*childFrame=it.currentFrame();//獲取當前框架的指針QTextBlockchildBlock=it.currentBlock();//獲取當前文本塊if(childFrame)qDebug()<<"frame";elseif(childBlock.isValid())qDebug()<<"block:"<<childBlock.text();}遍歷子框架QTextDocument*document=ui->textEdit->document();QTextBlockblock=document->firstBlock();//獲取文檔的第一個文本塊for(inti=0;i<document->blockCount();i++){qDebug()<<tr("文本塊%1,文本塊首行行號為:%2,長度為:%3,內(nèi)容為:").arg(i).arg(block.firstLineNumber()).arg(block.length())<<block.text();block=block.next();//獲取下一個文本塊}編輯文本塊及其內(nèi)容的格式QTextCursorcursor=ui->textEdit->textCursor();QTextBlockFormatblockFormat;//文本塊格式blockFormat.setAlignment(Qt::AlignCenter);//水平居中cursor.insertBlock(blockFormat);//使用文本塊格式QTextCharFormatcharFormat;//字符格式charFormat.setBackground(Qt::lightGray);//背景色charFormat.setForeground(Qt::blue);//字體顏色//使用宋體,12號,加粗,傾斜charFormat.setFont(QFont(tr("宋體"),12,QFont::Bold,true));charFormat.setFontUnderline(true);//使用下劃線cursor.setCharFormat(charFormat);//使用字符格式cursor.insertText(tr("測試字體"));//插入文本表格、列表和圖片插入表格QTextCursorcursor=ui->textEdit->textCursor();
QTextTableFormatformat;//表格格式format.setCellSpacing(2);//表格外邊白format.setCellPadding(10);//表格內(nèi)邊白cursor.insertTable(2,2,format);//插入2行2列表格插入列表
QTextListFormatformat;//列表格式format.setStyle(QTextListFormat::ListDecimal);//數(shù)字編號ui->textEdit->textCursor().insertList(format);插入圖片
QTextImageFormatformat;//圖片格式format.setName("logo.png");//圖片路徑ui->textEdit->textCursor().insertImage(format);查找功能查找文本QDialog*dlg=newQDialog(this);//創(chuàng)建對話框lineEdit=newQLineEdit(dlg);//創(chuàng)建行編輯器QPushButton*btn=newQPushButton(dlg);//創(chuàng)建按鈕btn->setText(tr("查找下一個"));connect(btn,SIGNAL(clicked()),this,SLOT(findNext()));//關聯(lián)信號和槽QVBoxLayout*layout=newQVBoxLayout;//創(chuàng)建垂直布局管理器layout->addWidget(lineEdit);//添加部件layout->addWidget(btn);dlg->setLayout(layout);//在對話框中使用布局管理器dlg->show();查找下一個QStringstring=lineEdit->text();//使用查找函數(shù)查找指定字符串,查找方式為向后查找boolisfind=ui->textEdit->find(string,QTextDocument::FindBackward);if(isfind){//如果查找成功,輸出字符串所在行和列的編號qDebug()<<tr("行號:%1列號:%2").arg(ui->textEdit->textCursor().blockNumber()).arg(ui->textEdit->textCursor().columnNumber());}語法高亮
在使用QtCreator編輯代碼時可以發(fā)現(xiàn),輸入關鍵字時會顯示不同的顏色,這就是所謂的語法高亮。在Qt的富文本處理中提供了QSyntaxHighlighter類來實現(xiàn)語法高亮。為了實現(xiàn)這個功能,需要創(chuàng)建QSyntaxHighlighter類的子類,然后重新實現(xiàn)highlightBlock()函數(shù),使用時直接將QTextDocument類對象指針作為其父部件指針,這樣就可以自動調(diào)用highlightBlock()函數(shù)了。
例如,自定義的類為MySyntaxHighlighter,像這樣來使用:highlighter=newMySyntaxHighlighter(ui->textEdit->document());這里創(chuàng)建了MySyntaxHighlighter類的對象,并且使用編輯器的文檔對象指針作為其參數(shù),這樣,每當編輯器中的文本改變時都會調(diào)用highlightBlock()函數(shù)來設置語法高亮。
重新實現(xiàn)highlightBlock()函數(shù):QTextCharFormatmyFormat;//字符格式myFormat.setFontWeight(QFont::Bold);myFormat.setForeground(Qt::green);QStringpattern="\\bchar\\b";//要匹配的字符,這里是“char”單詞QRegExpexpression(pattern);//創(chuàng)建正則表達式intindex=text.indexOf(expression);//從位置0開始匹配字符串//如果匹配成功,那么返回值為字符串的起始位置,它大于或等于0while(index>=0){intlength=expression.matchedLength();//要匹配字符串的長度setFormat(index,length,myFormat);//對要匹配的字符串設置格式index=text.indexOf(expression,index+length);//繼續(xù)匹配} 在這里主要是使用了正則表達式和QString類的indexOf()函數(shù)來進行字符串的匹配,如果匹配成功,則使用QSyntaxHighlighter類的setFormat()函數(shù)來設置字符格式。
HTML在富文本處理中還提供了對HTML子集的支持,可以在QLabel或者QTextEdit添加文本時使用HTML標簽或者CSS屬性,例如:
ui->textEdit->append(tr("<h1><fontcolor=red>使用HTML</font></h1>"));
這里往編輯器中添加了文本,并且使用了HTML標簽,5.3拖放操作對于一個實用的應用程序,我們不僅希望能從文件菜單中打開一個文件,更希望可以通過拖動,直接將桌面上的文件拖入程序界面上來打開,就像可以將.pro文件拖入QtCreator中來打開整個項目一樣。Qt中提供了強大的拖放機制,拖放操作分為拖動(Drag)和放下(Drop)兩種操作。當數(shù)據(jù)被拖動時會被存儲為MIME(MultipurposeInternetMailExtensions)類型,在Qt中使用QMimeData類來表示MIME類型的數(shù)據(jù),并使用QDrag類來完成數(shù)據(jù)的轉(zhuǎn)移,而整個拖放操作都是在幾個鼠標事件和拖放事件中完成的。使用拖放打開文件自定義拖放操作
使用拖放打開文件例如:將桌面上的txt文本文件拖入自己編寫的程序中來打開。使用拖放需要聲明兩個函數(shù):protected:voiddragEnterEvent(QDragEnterEvent*event);//拖動進入事件voiddropEvent(QDropEvent*event);//放下事件拖入操作voidMainWindow::dragEnterEvent(QDragEnterEvent*event)//進入事件{if(event->mimeData()->hasUrls())//數(shù)據(jù)中是否包含URLevent->acceptProposedAction();//如果是則接收動作elseevent->ignore();//否則忽略該事件}
當鼠標拖拽一個數(shù)據(jù)進入主窗口時,就會觸發(fā)dragEventEvent()事件處理函數(shù),獲取其中的MIME數(shù)據(jù),然后查看它是否包含URL路徑,因為拖入的文本文件實際上就是拖入了它的路徑,這就是event->mimeData()->hasUrls()實現(xiàn)的功能。如果有這樣的數(shù)據(jù),就接收它,否則就忽略該事件。放下操作voidMainWindow::dropEvent(QDropEvent*event)//放下事件{constQMimeData*mimeData=event->mimeData();//獲取MIME數(shù)據(jù)if(mimeData->hasUrls()){//如果數(shù)據(jù)中包含URLQList<QUrl>urlList=mimeData->urls();//獲取URL列表//將其中第一個URL表示為本地文件路徑QStringfileName=urlList.at(0).toLocalFile();if(!fileName.isEmpty()){//如果文件路徑不為空QFilefile(fileName);//建立QFile對象并且以只讀方式打開該文件if(!file.open(QIODevice::ReadOnly))return;QTextStreamin(&file);//建立文本流對象ui->textEdit->setText(in.readAll());//將文件中所有內(nèi)容讀入編輯器}}}當松開鼠標左鍵,將數(shù)據(jù)放入主窗口時就會觸發(fā)dropEvent()事件處理函數(shù),這里獲取了MIME數(shù)據(jù)中的URL列表,因為拖入的只有一個文件,所以獲取了列表中的第一個條目,并使用toLocalFile()函數(shù)將它轉(zhuǎn)換為本地文件路徑。然后使用QFile和QTextStream將文件中的數(shù)據(jù)讀入編輯器中。MIME類型數(shù)據(jù)處理函數(shù)在QMimeData類中提供了幾個函數(shù)來方便的處理常見的MIME數(shù)據(jù):自定義拖放操作
下面以在窗口中拖動圖片為例,需要聲明以下幾個函數(shù):protected:voidmousePressEvent(QMouseEvent*event);//鼠標按下事件voiddragEnterEvent(QDragEnterEvent*event);//拖動進入事件voiddragMoveEvent(QDragMoveEvent*event);//拖動事件voiddropEvent(QDropEvent*event);//放下事件mousePressEvent:為拖動圖片做準備工作,將圖片數(shù)據(jù)放到自定義的MIME類型中。dragEnterEvent:開始拖動,先判斷是否包含需要移動的類型。dragMoveEvent:拖動過程。dropEvent:放下圖片,創(chuàng)建新的圖片放到光標處。
當鼠標按下時會觸發(fā)鼠標按下事件,進而執(zhí)行其處理函數(shù),在這里進行了一系列操作,大體上可以分為六步。第一步,先獲取鼠標指針所在處的部件的指針,將它強制轉(zhuǎn)換為QLabel類型的指針,然后使用inherits()函數(shù)判斷它是否是QLabel類型,如果不是則直接返回,不再進行下面的操作。第二步,因為不僅要在拖動的數(shù)據(jù)中包含圖片數(shù)據(jù),還要包含它的位置信息,所以需要使用自定義的MIME類型。這里使用了QByteArray字節(jié)數(shù)組來存放圖片數(shù)據(jù)和位置數(shù)據(jù)。然后使用QDataStream類將數(shù)據(jù)寫入數(shù)組中。其中位置信息是當前鼠標指針的坐標減去圖片左上角的坐標而得到的差值。第三步,創(chuàng)建了QMimeData類對象指針,使用了自定義的MIME類型“myimage/png”,將字節(jié)數(shù)組放入QMimeData中。第四步,為了移動數(shù)據(jù),必須創(chuàng)建QDrag類對象,然后為其添加QMimeData數(shù)據(jù)。這里為了在移動過程中一直顯示圖片,需要使用setPixmap()函數(shù)為其設置圖片。然后使用setHotSpot()函數(shù)指定了鼠標在圖片上點擊的位置,這里是相對于圖片左上角的位置,如果不設定這個,那么在拖動圖片過程中,指針會位于圖片的左上角。第五步,在移動圖片過程中希望原來的圖片有所改變來表明它正在被操作,所以為其添加了一層陰影。第六步,執(zhí)行拖動操作,這需要使用QDrag類的exec()函數(shù)。這個函數(shù)可以設定所支持的放下動作和默認的放下動作,比如這里設置了支持復制動作Qt::CopyAction和移動動作Qt::MoveAction,并設置默認的動作是復制。這就是說拖動圖片,可以是移動它,也可以是進行復制,而默認的是復制操作,比如使用acceptProposedAction()函數(shù)時就是使用默認的操作。當圖片被放下后exec()函數(shù)就會返回操作類型,這個返回值由下面要講到的dropEvent()函數(shù)中的設置決定。這里判斷到底進行了什么操作,如果是移動操作,那么就刪除原來的圖片,如果是復制操作,就恢復原來的圖片。voidMainWindow::mousePressEvent(QMouseEvent*event)//鼠標按下事件{//第一步:獲取圖片//將鼠標指針所在位置的部件強制轉(zhuǎn)換為QLabel類型QLabel*child=static_cast<QLabel*>(childAt(event->pos()));if(!child->inherits("QLabel"))return;//如果部件不是QLabel則直接返回QPixmappixmap=*child->pixmap();//獲取QLabel中的圖片//第二步:自定義MIME類型QByteArrayitemData;//創(chuàng)建字節(jié)數(shù)組QDataStreamdataStream(&itemData,QIODevice::WriteOnly);//創(chuàng)建數(shù)據(jù)流//將圖片信息,位置信息輸入到字節(jié)數(shù)組中dataStream<<pixmap<<QPoint(event->pos()-child->pos());
//第三步:將數(shù)據(jù)放入QMimeData中QMimeData*mimeData=newQMimeData;//創(chuàng)建QMimeData用來存放要移動的數(shù)據(jù)//將字節(jié)數(shù)組放入QMimeData中,這里的MIME類型是我們自己定義的mimeData->setData("myimage/png",itemData);
//第四步:將QMimeData數(shù)據(jù)放入QDrag中QDrag*drag=newQDrag(this);//創(chuàng)建QDrag,它用來移動數(shù)據(jù)drag->setMimeData(mimeData);drag->setPixmap(pixmap);//在移動過程中顯示圖片,若不設置則默認顯示一個小矩形drag->setHotSpot(event->pos()-child->pos());//拖動時鼠標指針的位置不變//第五步:給原圖片添加陰影QPixmaptempPixmap=pixmap;//使原圖片添加陰影QPainterpainter;//創(chuàng)建QPainter,用來繪制QPixmappainter.begin(&tempPixmap);//在圖片的外接矩形中添加一層透明的淡黑色形成陰影效果painter.fillRect(pixmap.rect(),QColor(127,127,127,127));painter.end();child->setPixmap(tempPixmap);//在移動圖片過程中,讓原圖片添加一層黑色陰影//第六步:執(zhí)行拖放操作if(drag->exec(Qt::CopyAction|Qt::MoveAction,Qt::CopyAction)==Qt::MoveAction)//設置拖放可以是移動和復制操作,默認是復制操作child->close();//如果是移動操作,那么拖放完成后關閉原標簽else{child->show();//如果是復制操作,那么拖放完成后顯示標簽child->setPixmap(pixmap);//顯示原圖片,不再使用陰影}}voidMainWindow::dragEnterEvent(QDragEnterEvent*event)//拖動進入事件{//如果有我們定義的MIME類型數(shù)據(jù),則進行移動操作if(event->mimeData()->hasFormat("myimage/png")){event->setDropAction(Qt::MoveAction);event->accept();}else{event->ignore();}}voidMainWindow::dragMoveEvent(QDragMoveEvent*event)//拖動事件{if(event->mimeData()->hasFormat("myimage/png")){event->setDropAction(Qt::MoveAction);event->accept();}else{event->ignore();}}voidMainWindow::dropEvent(QDropEvent*event)//放下事件{if(event->mimeData()->hasFormat("myimage/png")){QByteArrayitemData=event->mimeData()->data("myimage/png");QDataStreamdataStream(&itemData,QIODevice::ReadOnly);QPixmappixmap;QPointoffset;//使用數(shù)據(jù)流將字節(jié)數(shù)組中的數(shù)據(jù)讀入到QPixmap和QPoint變量中dataStream>>pixmap>>offset;//新建標簽,為其添加圖片,并根據(jù)圖片大小設置標簽的大小QLabel*newLabel=newQLabel(this);newLabel->setPixmap(pixmap);newLabel->resize(pixmap.size());//讓圖片移動到放下的位置,不設置的話,圖片會默認顯示在(0,0)點即窗口左上角newLabel->move(event->pos()-offset);
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年汽車運輸車輛運輸安全培訓合同范本3篇
- 二零二五年度二次供水工程環(huán)保驗收合同
- 二零二五年度企業(yè)級二手服務器采購與租賃服務合同3篇
- 2024版彩票銷售專員合作合同精簡版版B版
- 2024版地下綜合管廊建設協(xié)議規(guī)范版B版
- 2024年項目分包與合作合同
- 2024年語音識別技術(shù)開發(fā)合同
- 2024版建筑工程施工合同范例下載
- 2024版公司文員雇傭勞動合同
- 2024年度物流供應鏈管理國際貨物運輸合同3篇
- 貴州省黔東南州2023-2024學年九年級上學期期末文化水平測試化學試卷
- 《空調(diào)零部件介紹》課件
- 2024年度醫(yī)院內(nèi)分泌與代謝科述職報告課件
- 手術(shù)室無菌操作流程
- 農(nóng)業(yè)機械控制系統(tǒng)硬件在環(huán)測試規(guī)范
- 翁潭電站大王山輸水隧洞施工控制網(wǎng)設計說明書
- 隆胸術(shù)培訓課件
- 鋼筋焊接培訓課件
- 行政內(nèi)勤培訓課件
- 化纖企業(yè)(化學纖維紡織企業(yè))安全生產(chǎn)操作規(guī)程
- 重大事故隱患專項排查檢查表
評論
0/150
提交評論