![C++程序設(shè)計及互動多媒體開發(fā) 課件匯 羅立宏 第7-10章 QT開發(fā) -虛擬現(xiàn)實應(yīng)用_第1頁](http://file4.renrendoc.com/view14/M00/07/22/wKhkGWegbOKAFBxtAABa5PvKHJc866.jpg)
![C++程序設(shè)計及互動多媒體開發(fā) 課件匯 羅立宏 第7-10章 QT開發(fā) -虛擬現(xiàn)實應(yīng)用_第2頁](http://file4.renrendoc.com/view14/M00/07/22/wKhkGWegbOKAFBxtAABa5PvKHJc8662.jpg)
![C++程序設(shè)計及互動多媒體開發(fā) 課件匯 羅立宏 第7-10章 QT開發(fā) -虛擬現(xiàn)實應(yīng)用_第3頁](http://file4.renrendoc.com/view14/M00/07/22/wKhkGWegbOKAFBxtAABa5PvKHJc8663.jpg)
![C++程序設(shè)計及互動多媒體開發(fā) 課件匯 羅立宏 第7-10章 QT開發(fā) -虛擬現(xiàn)實應(yīng)用_第4頁](http://file4.renrendoc.com/view14/M00/07/22/wKhkGWegbOKAFBxtAABa5PvKHJc8664.jpg)
![C++程序設(shè)計及互動多媒體開發(fā) 課件匯 羅立宏 第7-10章 QT開發(fā) -虛擬現(xiàn)實應(yīng)用_第5頁](http://file4.renrendoc.com/view14/M00/07/22/wKhkGWegbOKAFBxtAABa5PvKHJc8665.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
C++程序設(shè)計第7章QT開發(fā)第1節(jié)QT開發(fā)環(huán)境搭建第2節(jié)窗體第3節(jié)菜單、工具欄和狀態(tài)欄第4節(jié)鼠標與鍵盤第5節(jié)簡單繪圖第1節(jié)QT開發(fā)環(huán)境搭建QT開發(fā)環(huán)境搭建HelloWorld程序發(fā)布1.1QT簡介Qt是一個1991年由QtCompany開發(fā)的跨平臺C++圖形用戶界面應(yīng)用程序開發(fā)框架。它既可以開發(fā)GUI程序,也可用于開發(fā)非GUI程序,比如控制臺工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣堋?008年,QtCompany被諾基亞公司收購,Qt也因此成為諾基亞旗下的編程語言工具。2012年,Qt被Digia收購。2014年4月,跨平臺集成開發(fā)環(huán)境QtCreator3.1.0正式發(fā)布,實現(xiàn)了對于iOS、Android、WP的全面支持?;旧希琎t同XWindow上的Motif,Openwin,GTK等圖形界面庫和Windows平臺上的MFC,VCL,ATL是同類型的東西。1.2QT下載在線下載器:https://download.qt.io/official_releases/online_installers課程使用版本:6.5.11.3QT安裝……1.4例7-1創(chuàng)建HelloWorld程序新建HelloWorldQT項目路徑中不要有中文編譯,運行若遇到LNK1158無法運行rc.exe的錯誤,解決辦法見這里。QT框架代碼mainwindow.hMainWindow類定義#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>QT_BEGIN_NAMESPACEnamespaceUi{classMainWindow;}QT_END_NAMESPACEclassMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();private:Ui::MainWindow*ui;};#endif//MAINWINDOW_HQT框架代碼mainwindow.cppMainWindow類定義#include"mainwindow.h"#include"ui_mainwindow.h"MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);}MainWindow::~MainWindow(){deleteui;}QT框架代碼main.cpp主函數(shù)文件#include"mainwindow.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;w.show();returna.exec();}添加控件拖入一個標簽(Label),修改文字為“HelloWorld!”編譯,運行OK!1.5程序發(fā)布成功編譯之后,在項目目錄同級的目錄下會多一個名字形如“build-HelloWorldQT-Desktop_Qt_6_5_1_MinGW_64bit-Debug”的目錄。進入到里面的debug的目錄,就會發(fā)現(xiàn)編譯生成的HelloWorldQT.exe程序。運行exe程序,可能會出現(xiàn)以下缺少dll文件的提示:在QT的安裝目錄找到程序windeployqt.exe。該程序的作用是找到要發(fā)布的程序的所有依賴庫。在安裝了多個QT版本和部件時,要注意目錄要找對,和構(gòu)建目錄要對應(yīng)。在控制臺中運行“windeployqt.exe目標.exe”。運行完畢后,發(fā)布程序的目錄就會出現(xiàn)所有依賴的庫文件。至此,HelloWorldQT已可脫離QT運行。第2節(jié)窗體編輯窗體彈出窗體信號和槽純代碼編寫2.1例7-2創(chuàng)建一個多窗口程序程序的功能:運行開始出現(xiàn)一個對話框,按下登錄主界面按鈕后該對話框消失并進入主窗口。進入主窗口后,按下顯示對話框按鈕,會彈出一個對話框。(1)新建項目打開QtCreator,新建QtWidgetsApplication,項目名稱設(shè)置為windows完成項目創(chuàng)建后,雙擊mainwindow.ui文件進入設(shè)計模式,從左側(cè)部件列表中向界面上拖入一個PushButton,然后雙擊并修改顯示文本為“按鈕”。Ctrl+R運行一次程序。(2)使用代碼設(shè)置顯示文本在構(gòu)造函數(shù)MainWindow()中添加一行代碼MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);
ui->pushButton->setText("新窗口");//將界面上按鈕的顯示文本更改為“新窗口”}若出現(xiàn)錯誤“errorC2001:常量中有換行符”的解決辦法(3)添加登錄對話框往項目中添加新文件。模板選擇Qt分類中的Qt設(shè)計師界面類,然后界面模板選擇DialogwithoutButtons下一步進入類信息界面,這里將類名更改為LoginDlg完成后會自動跳轉(zhuǎn)到設(shè)計模式(4)增加按鈕拖入一個PushButton,更改顯示文本為“登錄到主界面”(5)設(shè)置信號和槽點擊設(shè)計模式上方
圖標,或者按下F4,進入信號和槽編輯模式。按著鼠標左鍵,從按鈕上拖向界面,如下圖所示。信號和槽大家可以把它們都看做是函數(shù),比如這里,當單擊了按鈕以后就會發(fā)射單擊信號,即clicked();然后對話框接收到信號就會執(zhí)行相應(yīng)的操作,即執(zhí)行accept()槽。一般情況下,我們只需要修改槽函數(shù)即可,不過,這里的accept()已經(jīng)實現(xiàn)了默認的功能,它會將對話框關(guān)閉并返回QDialog::Accepted標識,所以無需再做更改。下面我們要使用返回的QDialog::Accepted標識來判斷是否按下了登錄按鈕。完成后,可以按下圖標或者F3鍵來返回控件編輯模式。(6)修改main.cpp#include"mainwindow.h"#include<QApplication>#include"logindlg.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;LoginDlgdlg;//建立自己新建的LoginDlg類的實例dlgif(dlg.exec()==QDialog::Accepted)//利用Accepted返回值判斷按鈕是否被按下
{w.show();//如果被按下,顯示主窗口
returna.exec();//程序一直執(zhí)行,直到主窗口關(guān)閉
}elsereturn0;//如果沒有被按下,則不會進入主窗口,整個程序結(jié)束運行}(7)再彈出一個對話框我們計劃點擊主窗口“新窗口”按鈕時再彈出一個對話框。為此:打開mainwindow.ui文件進入設(shè)計模式,然后在“按鈕”部件上右擊并選擇轉(zhuǎn)到槽菜單在彈出的轉(zhuǎn)到槽對話框中選擇第一個clicked()信號并按下確定按鈕。這時會跳轉(zhuǎn)到編輯模式mainwindow.cpp中的on_pushButton_clicked()
函數(shù)處。添加代碼:#include"ui_mainwindow.h"#include"qdialog.h"……voidMainWindow::on_pushButton_clicked(){QDialog*dlg=newQDialog(this);dlg->show();}編譯,運行注意兩種彈出新窗口的方法:一種是舊窗口消失一種是舊窗口不消失OK!2.2例7-3登陸對話框新建QtWidgetsApplication,項目名稱為login,類名和基類保持MainWindow和QMainWindow不變。完成項目創(chuàng)建后,向項目中添加新的Qt設(shè)計師界面類,模板選擇DialogwithoutButtons,類名更改為LoginDlg。完成后向界面上添加兩個標簽Label、兩個行編輯器LineEdit和兩個按鈕PushButton。分別更改兩個行編輯器的objectName屬性為ledUser和ledPassword。分別更改兩個按鈕的objectName屬性為btnLogin和btnExit。使用信號和槽編輯器窗口來關(guān)聯(lián)信號和槽,設(shè)置退出按鈕。在設(shè)計模式下方的信號和槽編輯器(Signals&SlotsEditor)中,先點擊左上角的綠色加號添加關(guān)聯(lián),然后選擇發(fā)送者為btnExit,信號為clicked(),接收者為LoginDlg,槽為close()。這樣,就實現(xiàn)了當單擊退出按鈕時,就關(guān)閉登錄對話框。右擊登錄按鈕,在彈出的菜單中選擇“轉(zhuǎn)到槽…”,然后選擇clicked()信號并確定。轉(zhuǎn)到相應(yīng)的槽以后,添加函數(shù)調(diào)用:voidLoginDlg::on_btnLogin_clicked(){accept();}修改main.cpp#include"mainwindow.h"#include<QApplication>#include"logindlg.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;LoginDlgdlg;if(dlg.exec()==QDialog::Accepted){w.show();returna.exec();}elsereturn0;}實現(xiàn)使用用戶名和密碼登錄voidLoginDlg::on_btnLogin_clicked(){//判斷用戶名和密碼是否正確,錯誤則彈出警告對話框
if(ui->ledUser->text()==tr("zhang")&&ui->ledPassword->text()==tr("12345678")){accept();}else{QMessageBox::warning(this,tr("警告!"),tr("用戶名或密碼錯誤!"),QMessageBox::Yes);
//清空內(nèi)容并定位光標
ui->ledUser->clear();ui->ledPassword->clear();ui->ledUser->setFocus();}}在屬性編輯器中將echoMode屬性選擇為Password,密碼顯示變?yōu)楹邳c兩個文本框的placeholderText屬性更改為“請輸入用戶名”、“請輸入密碼”。文本框在沒有輸入前將顯示提示文本OK!2.3斷點調(diào)試嘗試設(shè)置一個斷點,利用調(diào)試運行按鈕啟動調(diào)試若出現(xiàn)錯誤“Unabletocreateadebuggingengine”的解決辦法2.4純代碼編寫QT除了可以使用UI框架編寫程序,還可以用純代碼實現(xiàn)UI界面。例7-4純代碼編寫的登陸對話框例子(1)新建工程新建QtWidgetsApplication,項目名稱為CodeLogin,在類信息頁面保持類名和基類為MainWindow和QMainWindow不變,取消選擇創(chuàng)建界面選項(GenerateForm)
往項目中添加新文件,模板選擇C++分類中的C++Class將類名設(shè)置為LoginDialog,基類選擇Custom定制,然后手動設(shè)置為Qdialog點擊“下一步”直到完成。(2)創(chuàng)建登錄對話框類(3)設(shè)置完成后,修改代碼。先修改LoginDlg.h文件#ifndefLOGINDIALOG_H#defineLOGINDIALOG_H#include<QDialog>classQLabel;//類的前置聲明classQLineEdit;classQPushButton;classLoginDlg:publicQDialog{//使用信號和槽等特性必須添加該宏Q_OBJECTpublic:LoginDlg(QWidget*parent=0);~LoginDlg();private:QLabel*labUser;QLabel*labPassword;QLineEdit*ledUser;QLineEdit*ledPassword;QPushButton*btnLogin;QPushButton*btnExit;};#endif修改LoginDlg.cpp文件#include"logindialog.h"#include<QLabel>#include<QLineEdit>#include<QPushButton>#include<QMessageBox>LoginDlg::LoginDlg(QWidget*parent):QDialog(parent){resize(400,280);//重設(shè)窗口大小labUser=newQLabel(this);labUser->move(65,60);labUser->setText(tr("賬號:"));ledUser=newQLineEdit(this);ledUser->move(130,57);ledUser->setPlaceholderText(tr("輸入賬號名稱"));labPassword=newQLabel(this);labPassword->move(65,120);labPassword->setText(tr("密碼:"));ledPassword=newQLineEdit(this);ledPassword->move(130,117);ledPassword->setPlaceholderText(tr("請輸入密碼"));btnLogin=newQPushButton(this);btnLogin->move(60,190);btnLogin->setText(tr("登錄"));btnExit=newQPushButton(this);btnExit->move(220,190);btnExit->setText(tr("退出"));}LoginDlg::~LoginDlg(){}修改main.cpp文件#include"mainwindow.h"#include<QApplication>#include"logindialog.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;
LoginDlgdlg;if(dlg.exec()==QDialog::Accepted){w.show();returna.exec();}elsereturn0;}界面已和前例一樣,但點擊按鈕還無反應(yīng)若出現(xiàn)錯誤“l(fā)ink2001錯誤無法解析外部符號metaObject”的解決辦法(4)實現(xiàn)信號和槽的功能修改LoginDlg.h,聲明一個槽:……classLoginDlg:publicQDialog{……QPushButton*btnExit;privateslots:voidLogin();};修改LoginDlg.cpp中的構(gòu)造函數(shù),連接槽:LoginDlg::LoginDlg(QWidget*parent):QDialog(parent){……QPushButton*btnExit;connect(btnLogin,&QPushButton::clicked,this,&LoginDlg::Login);connect(btnExit,&QPushButton::clicked,this,&LoginDlg::close);
};在LoginDlg.cpp末尾添加槽函數(shù)Login()的定義voidLoginDlg::Login(){//判斷用戶名和密碼是否正確,
if(ledUser->text()==tr("zhang")&&ledPassword->text()==tr("12345678")){accept();}else//如果錯誤則彈出警告對話框
{QMessageBox::warning(this,tr("警告!"),tr("用戶名或密碼錯誤!"),QMessageBox::Yes);ledUser->clear();ledPassword->clear();ledUser->setFocus();}}OK!第3節(jié)菜單、工具欄和狀態(tài)欄菜單工具欄狀態(tài)欄簡易寫字本例子例7-5一個帶菜單、工具欄、狀態(tài)欄的簡易文本編輯器(界面)通過例子演示菜單、工具欄、狀
態(tài)欄的制作(1)新建項目新建QtWidgetsApplication,項目名稱為mymainwindow,基類選擇QMainWindow,類名為MainWindow。3.1菜單(2)創(chuàng)建菜單創(chuàng)建完項目后,雙擊mainwindow.ui文件進入設(shè)計模式。在這里可以看到界面左上角的“在這里輸入”,我們可以在這里添加菜單。雙擊“在這里輸入”,將其更改為“文件(&F)”,按下回車鍵結(jié)束。&——加速鍵定義字符。使得菜單可以用同時按Alt和字母快捷訪問。顯示為下劃線。按同樣的方法,在文件菜單中添加“新建(&N)”菜單項。(3)添加菜單圖標Qt中的一個菜單被看做是一個Action,我們在下面的Action編輯器(ActionEditor)中可以看到剛才添加的“新建”菜單。雙擊該條目,會彈出編輯動作對話框,這里可以進行各項設(shè)置點擊下拉框可以使用“選擇資源”或“選擇文件”兩種方式添加菜單圖標。下面講解“選擇資源”的方式。向項目中添加新文件,模板選擇Qt分類中的Qt資源文件(QtResourceFile)。然后將名稱設(shè)置為MenuIcons。添加完文件后會自動打開該資源文件,首先需要添加前綴,點擊“AddPrefix”,默認的前綴是“/new/prefix1”,這個可以隨意修改(不要出現(xiàn)中文字符),修
改為“/MenuImages”在項目目錄中新建一個文件夾,放入需要的圖標文件點擊“AddFiles”,選入要用到的圖標。完成后點保存。啟用圖標打開mainwindow.ui并切換到設(shè)計視圖,在下面ActionEditor窗口,中雙擊菜單Action,在彈出的對話框中選擇合適圖標編譯運行,得到如下效果按上述方法添加完整菜單,并在ActionEditor窗口中指定圖標與快捷鍵。如圖3.2工具欄(4)向工具欄添加菜單圖標在窗口中添加工具欄將ActionEditor中的Action拖動到工具欄中作為快捷圖標使用最終工具欄如下圖3.3文本編輯器與布局(5)加入文本編輯器拖入一個文本編輯器TextEdit部件在窗口空白處右擊,在彈出的快捷菜單中選擇“布局—柵格布局”。文本編輯器就會充滿中央?yún)^(qū)域。3.4實現(xiàn)功能代碼(6)本小節(jié)實現(xiàn)類似記事本的各種文本編輯功能打開mainwindow.h,在類定義中添加代碼:classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();public:voidNewFile();//新建文件操作
boolIsNeedSave();//判斷是否需要保存
boolSave();//保存操作
boolSaveAs();//另存為操作
boolSaveFile(constQString&sFileName);//保存文件
boolOpenFile(constQString&sFileName);//加載文件private:Ui::MainWindow*ui;private:boolm_bSaved;//文件是否保存過
QStringm_sFilePathName;//文件的保存路徑};在MainWindow.cpp頂部加入相關(guān)的頭文件#include"mainwindow.h"#include"ui_mainwindow.h"#include<QMessageBox>#include<QPushButton>#include<QFileDialog>#include<QTextStream>……在構(gòu)造函數(shù)中加入初始化代碼MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);m_bSaved=false;//初始化文件為未保存狀態(tài)
m_sFilePathName=tr("未命名.txt");//初始化文件名
setWindowTitle(m_sFilePathName);//設(shè)置窗口標題}在MainWindow.cpp添加NewFile()定義voidMainWindow::NewFile(){if(IsNeedSave()){m_bSaved=false;m_sFilePathName=tr("未命名.txt");setWindowTitle(m_sFilePathName);ui->textEdit->clear();ui->textEdit->setVisible(true);}}在MainWindow.cpp添加IsNeedSave()定義boolMainWindow::IsNeedSave(){if(ui->textEdit->document()->isModified()){//如果文檔被更改了//定義一個提示対話框
QMessageBoxMsgBox;MsgBox.setWindowTitle(tr("警告"));MsgBox.setIcon(QMessageBox::Warning);MsgBox.setText(m_sFilePathName+tr("尚未保存,是否保存?"));QPushButton*yesBtn=MsgBox.addButton(tr("是(&Y)"),QMessageBox::YesRole);MsgBox.addButton(tr("否(&N)"),QMessageBox::NoRole);QPushButton*cancelBtn=MsgBox.addButton(tr("取消"),QMessageBox::RejectRole);MsgBox.exec();if(MsgBox.clickedButton()==yesBtn)returnSave();elseif(MsgBox.clickedButton()==cancelBtn)returnfalse;}returntrue;//如果文檔沒有被更改,則直接返回true}在MainWindow.cpp添加Save()和SaveAs()定義boolMainWindow::Save(){if(!m_bSaved){returnSaveAs();}else{returnSaveFile(m_sFilePathName);}}boolMainWindow::SaveAs(){QStringsFilePathName=QFileDialog::getSaveFileName(this,tr("另存為"),m_sFilePathName);if(sFilePathName.isEmpty())returnfalse;returnSaveFile(sFilePathName);}在MainWindow.cpp添加SaveFile()定義boolMainWindow::SaveFile(constQString&sFilePathName){QFilefile(sFilePathName);if(!file.open(QFile::WriteOnly|QFile::Text)){
//%1和%2分別對應(yīng)后面arg兩個參數(shù),/n為換行
QMessageBox::warning(this,tr("多文檔編輯器"),tr("無法寫入文件%1:/n%2").arg(sFilePathName).arg(file.errorString()));returnfalse;}QTextStreamout(&file);QApplication::setOverrideCursor(Qt::WaitCursor);//鼠標指針變?yōu)榈却隣顟B(tài)out<<ui->textEdit->toPlainText();QApplication::restoreOverrideCursor();//鼠標指針恢復原來的狀態(tài)m_bSaved=true;m_sFilePathName=QFileInfo(sFilePathName).canonicalFilePath();//獲得文件的標準路徑setWindowTitle(m_sFilePathName);returntrue;}3.5菜單響應(yīng)(7)在ActionEditor中設(shè)置菜單響應(yīng)上圖操作后,QT會為MainWindow類添加on_action_N_triggered()槽函數(shù)為on_action_N_triggered()槽函數(shù)添加代碼//新建動作voidMainWindow::on_action_N_triggered()//橙色代碼表示從ActionEditor設(shè)置生成{NewFile();//黃色代碼為手動鍵入}(8)同樣操作,為“保存”等各個菜單項添加槽函數(shù)和代碼//保存動作voidMainWindow::on_action_S_triggered(){Save();}//另存為動作voidMainWindow::on_action_A_triggered(){SaveAs();}//打開動作voidMainWindow::on_action_O_triggered(){if(IsNeedSave()){QStringsFilePathName=QFileDialog::getOpenFileName(this);//如果文件名不為空,則加載文件
if(!sFilePathName.isEmpty()){OpenFile(sFilePathName);ui->textEdit->setVisible(true);}}}//關(guān)閉動作voidMainWindow::on_action_C_triggered(){
IsNeedSave();//若未存盤則先存盤
NewFile();//新建一個空白文檔}//撤銷動作voidMainWindow::on_action_Z_triggered(){ui->textEdit->undo();//可看到,undo復制粘貼等功能都直接利用了textEdit自帶的功能}//剪切動作voidMainWindow::on_action_X_triggered(){ui->textEdit->cut();}//復制動作voidMainWindow::on_action_C_2_triggered(){ui->textEdit->copy();}//粘貼動作voidMainWindow::on_action_V_triggered(){ui->textEdit->paste();}//退出動作voidMainWindow::on_action_X_2_triggered(){on_action_C_triggered();//先執(zhí)行關(guān)閉操作,再退出程序qApp->quit();//qApp是指向應(yīng)用程序的全局指針}編譯運行,程序已能實現(xiàn)記事本的
文本編輯功能3.6狀態(tài)欄動作狀態(tài)提示
(9)在Action編輯器中選中動作,然后在右面的屬性編輯器中對其statusTip屬性進行更改。臨時狀態(tài)信息使用showMessage()函數(shù)可以為狀態(tài)欄添加一個臨時信息,它會出現(xiàn)在狀態(tài)欄的最左邊(10)在構(gòu)造函數(shù)中添加代碼:MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);m_bSaved=false;//初始化文件為未保存狀態(tài)
m_sFilePathName=tr("未命名.txt");//初始化文件名
setWindowTitle(m_sFilePathName);//設(shè)置窗口標題
ui->statusbar->showMessage(tr("歡迎使用TextPad寫字本!"));}持久狀態(tài)信息使用addPermanentWidget()函數(shù)可以為狀態(tài)欄添加一個持久信息,它會出現(xiàn)在狀態(tài)欄的最右邊(11)在MainWindow.cpp頂部及構(gòu)造函數(shù)中添加代碼:……#include<QTextStream>#include<QLabel>MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);m_bSaved=false;//初始化文件為未保存狀態(tài)
m_sFilePathName=tr("未命名.txt");//初始化文件名
setWindowTitle(m_sFilePathName);//設(shè)置窗口標題
ui->statusbar->showMessage(tr("歡迎使用TextPad寫字本!"));QLabel*labPermanent=newQLabel;labPermanent->setText(tr("版本:1.0"));ui->statusbar->addPermanentWidget(labPermanent);}至此,一個簡易的文本編輯寫字本已基本完成。還有搜索和版本信息菜單項的功能請同學們自行實現(xiàn)。OK!第4節(jié)鼠標與鍵盤鼠標事件處理鍵盤事件處理4.1鼠標事件處理通過重寫Qt事件處理函數(shù)來實現(xiàn)鼠標和鍵盤事件處理例7-6鼠標鍵盤事件響應(yīng)(1)新建QtWidgets應(yīng)用,項目名稱為“MouseAndKey”(2)完成項目創(chuàng)建后,在設(shè)計模式向界面上拖入一個Label(3)在MainWindow.h文件添加鼠標按下事件處理函數(shù)聲明:classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();protected:voidmousePressEvent(QMouseEvent*);private:Ui::MainWindow*ui;};(4)在MainWindow.cpp中添加頭文件及鼠標處理函數(shù)定義#include"mainwindow.h"#include"ui_mainwindow.h"#include<QMouseEvent>……MainWindow::~MainWindow(){deleteui;}voidMainWindow::mousePressEvent(QMouseEvent*e){ui->label->setText(tr("(%1,%2)").arg(e->x()).arg(e->y()));}同理,除了鼠標按下事件,還有鼠標釋放、雙擊、移動、滾輪等事件,其處理方式與這個例子相似4.2鍵盤事件處理(5)在MainWindow.h文件添加鍵盤按下事件處理函數(shù)聲明:classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();protected:voidmousePressEvent(QMouseEvent*);voidkeyPressEvent(QKeyEvent*);private:Ui::MainWindow*ui;};(6)在MainWindow.cpp中添加頭文件及鍵盤處理函數(shù)定義……#include<QMouseEvent>#include<QKeyEvent>……voidMainWindow::keyPressEvent(QKeyEvent*e){//打印出按鍵字符
QStringsMsg;sMsg=QString::asprintf("Keypressed:%c",e->key());ui->label->setText(sMsg);//移動標簽
intnX=ui->label->x();intnY=ui->label->y();switch(e->key()){caseQt::Key_W:ui->label->move(nX,nY-5);break;caseQt::Key_S:ui->label->move(nX,nY+5);break;caseQt::Key_A:ui->label->move(nX-5,nY);break;caseQt::Key_D:ui->label->move(nX+5,nY);break;}}
同理,還有鍵盤釋放事件,處理相似OK!第5節(jié)簡單繪圖常用繪圖類簡單繪圖示例5.1繪圖常用類QPainter類可以繪制一切想要的圖形,從最簡單的一條直線到其他任何復雜的圖形,它還可以用來繪制文本和圖片。重繪事件QPainter一般在一個部件的重繪事件(PaintEvent)處理函數(shù)paintEvent()中進行繪制。QPen類畫筆類??梢钥刂茍D形的顏色、線寬和線型。QBrush類
畫刷類。為封閉圖形填充顏色和圖案。5.2例7-7簡單繪圖示例(1)新建QtWidgets應(yīng)用,項目名稱為SimpleDraw(2)在mainwindow.h文件中添加重繪事件處理函數(shù)的聲明:classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=nullptr);~MainWindow();protected:voidpaintEvent(QPaintEvent*);private:Ui::MainWindow*ui;};(3)在MainWindow.cpp中添加頭文件及重繪事件函數(shù)定義……#include<QPainter>……MainWindow::~MainWindow(){deleteui;}voidMainWindow::paintEvent(QPaintEvent*){QPainterpainter(this);painter.drawLine(QPointF(100,100),QPointF(200,200));//簡單畫線QPenpen;//畫筆
pen.setColor(QColor(255,0,0));QBrushbrush(QColor(0,0,255,128));//畫刷。顏色第四個參數(shù)為透明度
painter.setPen(pen);//選擇畫筆
painter.setBrush(brush);//選擇畫刷
painter.drawRect(200,100,100,100);//繪制矩形pen.setColor(QColor(255,0,255));pen.setWidth(5);brush.setColor(QColor(255,255,0));brush.setStyle(Qt::CrossPattern);//CrossPattern為十字線填充,更多圖案參見幫助
painter.setPen(pen);painter.setBrush(brush);painter.drawEllipse(300,100,100,100);//繪制圓
pen.setColor(QColor(0,128,128));pen.setStyle(Qt::DashLine);//DashLine為虛線。更多線型參見幫助
painter.setPen(pen);painter.drawLine(QPointF(400,200),QPointF(500,100));//繪制虛線}OK!小結(jié)MFC與QT的比較開發(fā)速度MFC√運行效率MFC√代碼風格
QT封裝哲學√適用平臺MFC:Windows√QT:Window、Android、iOS…--eg./naibozhuan3744/article/details/78909086/作業(yè)對照PPT,重做例7-5TextPad程序C++程序設(shè)計第8章視頻與音頻第1節(jié)音視頻開發(fā)概述第2節(jié)DirectShow音視頻開發(fā)第3節(jié)SDL多媒體開發(fā)庫第4節(jié)FFMpeg音視頻開發(fā)(一)第5節(jié)FFMpeg音視頻開發(fā)(二)第1節(jié)音視頻開發(fā)概述音視頻開發(fā)應(yīng)用領(lǐng)域常用的音視頻開發(fā)庫1.1音視頻開發(fā)應(yīng)用領(lǐng)域音視頻播放軟件音視頻采集、錄制視頻監(jiān)控音視頻編輯、格式轉(zhuǎn)化軟件網(wǎng)絡(luò)直播數(shù)字電視1.2常用的音視頻開發(fā)庫(1)微軟:VideoForWindows(VFW)→DirectShow
→MediaFoundation特征:Windows系統(tǒng)適用
難度:★★常用的音視頻開發(fā)庫(2)FFMpeg全稱:FastForwardMovingpictureexpertgroup特征:
功能強大
格式覆蓋全
跨平臺
難度:★★★★官網(wǎng):/常用的音視頻開發(fā)庫(3)VLC全稱:VideoLanClient特征:支持大多數(shù)音視頻格式
跨平臺官網(wǎng):/常用的音視頻開發(fā)庫(4)Gstreamer全稱:VideoLanClient特征:支持大多數(shù)音視頻格式
跨平臺官網(wǎng):/第2節(jié)DirectShow音視頻開發(fā)DirectShow簡介DirectShow構(gòu)架最簡單的DirectShow播放器MFC圖形界面DirectShow2.1DirectShow簡介DirectShow(簡稱DShow)是一個Windows平臺上的流媒體框架,提供了高質(zhì)量的多媒體流采集和回放功能。它支持多種多樣的媒體文件格式,包括ASF、MPEG、AVI、MP3和WAV等多種文件。VideoForWindows(VFW)→DirectShow
→MediaFoundation開發(fā)語言:C++2.2DirectShow架構(gòu)DirectShow是一個開放性的應(yīng)用框架,也是一套基于COM的編程接口。DirectShow使用一種交FilterGraph的模型來管理整個數(shù)據(jù)流的處理過程;參與數(shù)據(jù)處理的各個功能模塊叫做Filter;各個Filter在FilterGraph中按一定的順序連接成一條"流水線"協(xié)同工作。Filter,它是最基本的軟件構(gòu)件,過濾器通常在多媒體流中執(zhí)行一個操作。各個Filter在FilterGraph中按一定的順序連接成一條"流水線"協(xié)同工作。DirectShow的Filter與各種設(shè)備進行通信并對它們進行相應(yīng)的控制,這些設(shè)備包括本地文件系統(tǒng)、電視卡、視頻采集卡、VFW編解碼器、顯示器和聲卡。通過這種方式,DirectShow成功的隔離了應(yīng)用程序和各種復雜設(shè)備。2.3最簡單的DirectShow播放器例8-1一個最簡單的基于DirectShow的播放器2.3.1流程1.最簡單的基于DirectShow的視頻播放器的流程圖如右圖CoInitialize()CoCreateInstance(…,pGraph)pGraph->QueryInterface(…,pControl)pGraph->QueryInterface(…,pEvent)pGraph->RenderFile(“xxxx.mp4”)pControl->Run()pEvent->WaitForCompletionCoUnInitialize()成員變量:IGraphBuilder*pGraph;IMediaControl*pControl;IMediaEvent*pEvent;2.3.1流程2.流程圖中涉及到幾個接口:IGraphBuilder:繼承自IFilterGraph,用于構(gòu)建FilterGraph。相比于IFilterGraph來說IGraphBuilder提供了一些更加“智能”的方法,例如RenderFile()方法。IMediaControl:提供和播放控制有關(guān)的一些接口。IMediaEvent:用來處理FilterGraph發(fā)出的事件。流程3.流程圖中關(guān)鍵函數(shù)CoInitialize():初始化COM運行環(huán)境。CoCreateInstance(…,pGraph):用指定的類標識符創(chuàng)建一個Com對象。在該播放器中類標識符為“CLSID_FilterGraph”,用于創(chuàng)建IGraphBuilder。pGraph->QueryInterface(…,pControl):通過QueryInterface()查詢某個組件是否支持某個特定的接口。在這里查詢IMediaControl接口。pGraph->QueryInterface(…,pEvent):同上。在這里查詢IMediaEvent接口。pGraph->RenderFile("xxxx.mp4"):為指定的文件智能的構(gòu)建一個FilterGraph。pControl->Run():開始運行FilterGraph中的所有Filter。pEvent->WaitForCompletion():等待FilterGraph處理完所有數(shù)據(jù)。CoUninitialize():釋放CoInitialize()初始化的COM運行環(huán)境。2.3.2步驟啟動VisualStudio(如VS2022),創(chuàng)建一個控制臺項目。項目名稱可取為SimpleDShowPlayer把cpp文件中的代碼替換成以下代碼:#include<DShow.h>#pragmacomment(lib,“strmiids.lib”)//使用DirectShow需要這個庫文件//請嘗試去掉這句,而用這種方法替代:菜單“項目--***屬性”,彈出對話框中找//到“配置屬性--鏈接器--輸入--附加依賴項”,添加“strmiids.lib”。具有同樣效果//用宏定義定義釋放的過程#defineSAFE_RELEASE(filter){if(NULL!=filter){filter->Release();filter=NULL;}}intmain(){IGraphBuilder*pGraphBuilder=NULL; //Filtergraph管理器
IMediaControl*pMediaControl=NULL; //控制視頻/音頻的播放、暫停與停止
IMediaEvent*pMediaEvent=NULL; //捕獲播放過程中的事件CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);//初始化COM運行環(huán)境
//創(chuàng)建Filtergraph管理器對象HRESULThr=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&pGraphBuilder);if(FAILED(hr)){printf("CoCreateInstanceFailed!\n");goto__exit;}
//獲取IMediaControl接口hr=pGraphBuilder->QueryInterface(IID_IMediaControl,(void**)&pMediaControl);if(FAILED(hr)){printf("QueryMediaControlInterfaceFailed!\n");goto__exit;}
//獲取IMediaEvent接口hr=pGraphBuilder->QueryInterface(IID_IMediaEvent,(void**)&pMediaEvent);if(FAILED(hr)){printf("QueryMediaEventInterfaceFailed!\n");goto__exit;}
//打開視頻文件
hr=pGraphBuilder->RenderFile(L“..\\..\\VideoForTest\\Megamind.avi”,NULL);//可改路徑文件
if(FAILED(hr)){printf("RenderFileFailed!\n");goto__exit;}
//視頻播放hr=pMediaControl->Run();if(FAILED(hr)){printf("RunFailed!\n");goto__exit;}{longcode=0;hr=pMediaEvent->WaitForCompletion(INFINITE,&code);//等待視頻播放完畢
if(FAILED(hr)){printf("WaitForCompletionFailed!\n");goto__exit;}}__exit:
//清理變量回收內(nèi)存SAFE_RELEASE(pMediaEvent);SAFE_RELEASE(pMediaControl);SAFE_RELEASE(pGraphBuilder);CoUninitialize();system("pause");return0;}編譯,運行--OK!2.4圖形界面DirectShow播放器例8-2一個基于MFC圖形界面的DirectShow的播放器參看課件提供的代碼自行學習,課堂上不詳細講述了。第3節(jié)SDL多媒體開發(fā)庫SDL簡介SDL開發(fā)設(shè)置SDL顯示流程SDL顯示圖片SDL事件驅(qū)動SDL鍵盤事件3.1SDL簡介SDL是SimpleDirectMediaLayer(簡易直控媒體層)的縮寫。它是一個跨平臺的多媒體庫,以用于直接控制底層的多媒體硬件的接口。這些多媒體功能包括了音頻、鍵盤和鼠標(事件)、游戲搖桿等。其最為重要的是提供了2D圖形幀緩沖(framebuffer)的接口,以及為OpenGL與各種操作系統(tǒng)之間提供了統(tǒng)-的標準接口以實現(xiàn)3D圖形。從這些屬性我們可以看出,SDL基本上可以認為是為以電腦游戲為核心開發(fā)的多媒體庫。C語言寫成,可在C++下工作官網(wǎng):/最新版本:SDL2.0第4節(jié)FFMpeg將會用到SDL顯示視頻圖像,因此有必要先學習一下SDL。3.2SDL開發(fā)設(shè)置從官網(wǎng)下載最新的SDL2(/download-2.0.php),或者從課件資料中拷貝SDL2,解壓,放到某個方便記憶的目錄位置,例如“D:\SDL2\SDL2”SDL開發(fā)設(shè)置以后在每一個需要SDL的VisualStudtio工程中,菜單“項目–xxx屬性”,在彈出的屬性頁對話框中,在配置屬性樹中點“VC++目錄”,然后在“包含目錄”中添加SDL中的include目錄,如“D:\SDL2\SDL2\include”;再在“庫目錄”中添加SDL中的lib目錄,如“D:\SDL2\SDL2\lib\x64”。請根據(jù)VS中編譯的版本是x64還是x86來正確選擇lib下的x64或x86目錄。SDL開發(fā)設(shè)置再在“鏈接器-輸入-附加依賴項”中添加“SDL2.lib;SDL2main.lib;”。把lib目錄下(注意正確選擇x64或x86目錄)的SDL2.dll拷貝工程目錄下3.3SDL2.0顯示流程SDL_Init()SDL_CreateWindow()SDL_CreateRenderer()SDL_CreateTexture()SDL_UpdateTexture()SDL_RenderCopy()SDL_RenderPresent()Decode()YUV/RGB顯示主要函數(shù)簡介SDL_Init():初始化SDL系統(tǒng)SDL_CreateWindow():創(chuàng)建窗口SDL_WindowSDL_CreateRenderer():創(chuàng)建渲染器SDL_RendererSDL_CreateTexture():創(chuàng)建紋理SDL_TextureSDL_UpdateTexture():設(shè)置紋理的數(shù)據(jù)SDL_RenderCopy():將紋理的數(shù)據(jù)拷貝給渲染器SDL_RenderPresent():顯示SDL_Delay():工具函數(shù),用于延時。SDL_Quit():退出SDL系統(tǒng)3.4SDL顯示圖片例8-3使用SDL顯示一張bmp圖片步驟:(1)打開VS,創(chuàng)建一個控制臺工程。工程起名為“HelloSDL”(2)按照3.2節(jié)設(shè)置好SDL開發(fā)環(huán)境(3)打開HelloSDL.cpp,把原來的代碼替換成以下代碼:#defineSDL_MAIN_HANDLED#include<iostream>#include<SDL.h>usingnamespacestd;intmain(){//初始化SDLif(SDL_Init(SDL_INIT_VIDEO)){cout<<"SDL_InitError:"<<SDL_GetError()<<endl;return-1;}//創(chuàng)建窗口
SDL_Window*pWin=SDL_CreateWindow("HelloWorld!",100,100,640,480,SDL_WINDOW_SHOWN);if(pWin==nullptr){cout<<"SDL_CreateWindowError:"<<SDL_GetError()<<endl;return-1;}
//創(chuàng)建渲染器
SDL_Renderer*pRen=SDL_CreateRenderer(pWin,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC);//第三個參數(shù)是:開啟硬件//加速|(zhì)控制屏幕幀率不超過電腦默認刷新率,如果改為0//的話CPU和GPU占用率會比較高
if(pRen==nullptr){SDL
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 三農(nóng)行業(yè)培訓教程與作業(yè)指導書
- 2025年中國立體車庫減速電機行業(yè)發(fā)展前景及投資戰(zhàn)略咨詢報告
- 農(nóng)村網(wǎng)店轉(zhuǎn)讓合同范本
- 公司經(jīng)紀合同范本
- 農(nóng)村電力合同范例
- 出版教輔材料合同范本
- sm公司合同范例
- 養(yǎng)獵養(yǎng)殖合同范例
- 2025年度建筑工程項目環(huán)保驗收合同
- 醫(yī)療管理聘用合同范例
- 2025年1月浙江省高考政治試卷(含答案)
- 教體局校車安全管理培訓
- 湖北省十堰市城區(qū)2024-2025學年九年級上學期期末質(zhì)量檢測綜合物理試題(含答案)
- 行車起重作業(yè)風險分析及管控措施
- 健康體檢中心患者身份登記制度
- 國產(chǎn)氟塑料流體控制件生產(chǎn)企業(yè)
- 空氣能安裝合同
- 初二上冊的數(shù)學試卷
- 2025年上半年重慶三峽融資擔保集團股份限公司招聘6人高頻重點提升(共500題)附帶答案詳解
- 四大名繡課件-高一上學期中華傳統(tǒng)文化主題班會
- 大模型關(guān)鍵技術(shù)與應(yīng)用
評論
0/150
提交評論