嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)-基于ARM Cortex-A9和Linux 課件 第11章 Qt編程及嵌入式Qt開(kāi)發(fā)_第1頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)-基于ARM Cortex-A9和Linux 課件 第11章 Qt編程及嵌入式Qt開(kāi)發(fā)_第2頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)-基于ARM Cortex-A9和Linux 課件 第11章 Qt編程及嵌入式Qt開(kāi)發(fā)_第3頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)-基于ARM Cortex-A9和Linux 課件 第11章 Qt編程及嵌入式Qt開(kāi)發(fā)_第4頁(yè)
嵌入式系統(tǒng)設(shè)計(jì)與開(kāi)發(fā)-基于ARM Cortex-A9和Linux 課件 第11章 Qt編程及嵌入式Qt開(kāi)發(fā)_第5頁(yè)
已閱讀5頁(yè),還剩115頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第十一章Qt編程及嵌入式Qt開(kāi)發(fā)北京航空航天大學(xué)電工電子中心2025年6月提綱Qt編程基礎(chǔ)圖形界面設(shè)計(jì)信號(hào)和槽機(jī)制Qt程序綜合實(shí)驗(yàn)—電子鐘設(shè)計(jì)Qt開(kāi)發(fā)環(huán)境的搭建Qt是一個(gè)1991年由QtCompany開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架。它既可以開(kāi)發(fā)GUI程序,也可用于開(kāi)發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣?,使用特殊的代碼生成擴(kuò)展(稱為元對(duì)象編譯器(MetaObjectCompiler,moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。2008年,QtCompany科技被諾基亞公司收購(gòu),Qt也因此成為諾基亞旗下的編程語(yǔ)言工具。2012年,Qt被Digia收購(gòu)。2014年4月,跨平臺(tái)集成開(kāi)發(fā)環(huán)境QtCreator3.1.0正式發(fā)布,實(shí)現(xiàn)了對(duì)于iOS的完全支持,新增WinRT、Beautifier等插件,廢棄了無(wú)Python接口的GDB調(diào)試支持,集成了基于Clang的C/C++代碼模塊,并對(duì)Android支持做出了調(diào)整,至此實(shí)現(xiàn)了全面支持iOS、Android、WP,它提供給應(yīng)用程序開(kāi)發(fā)者建立藝術(shù)級(jí)的圖形用戶界面所需的所有功能?;旧?,Qt同XWindow上的Motif,Openwin,GTK等圖形界面庫(kù)和Windows平臺(tái)上的MFC,OWL,VCL,ATL是同類型的東西。QT和QTCreatorQt是跨平臺(tái)的應(yīng)用程序和UI框架。它包括跨平臺(tái)類庫(kù)、集成開(kāi)發(fā)工具和跨平臺(tái)IDE。使用Qt只需一次性開(kāi)發(fā)應(yīng)用程序,無(wú)須重新編寫(xiě)源代碼,便可跨不同桌面和嵌入式操作系統(tǒng)部署這些應(yīng)用程序。QTQt的用途Qt支持的平臺(tái)QT簡(jiǎn)介QT簡(jiǎn)介QtCreator是專為滿足Qt開(kāi)發(fā)人員需求而量身定制的跨平臺(tái)集成開(kāi)發(fā)環(huán)境(IDE)。QtCreator可在Windows、Linux/X11和MacOSX桌面操作系統(tǒng)上運(yùn)行,供開(kāi)發(fā)人員針對(duì)多個(gè)桌面和移動(dòng)設(shè)備平臺(tái)創(chuàng)建應(yīng)用程序。QtCreator簡(jiǎn)介QtCreator包括:高級(jí)C++和JavaScript代碼編輯器集成用戶界面設(shè)計(jì)器項(xiàng)目和構(gòu)建管理工具gdb和CDB調(diào)試程序的支持版本控制的支持移動(dòng)用戶界面模擬器為桌面和移動(dòng)目標(biāo)平臺(tái)提供支持QTCreator簡(jiǎn)介

除此之外,還有一個(gè)開(kāi)發(fā)套件叫QtSDK,包括Qt庫(kù)、QtCreatorIDE和Qt工具,全部都集成在一個(gè)易于安裝的文件包里。QT數(shù)據(jù)類型QString類如有下特點(diǎn):采用Unicode編碼,所以一個(gè)QString類對(duì)象占用兩個(gè)字節(jié)。采用隱式共享技術(shù)來(lái)節(jié)省內(nèi)存和減少不必要的數(shù)據(jù)備份。跨平臺(tái)使用,不用考慮字符串的平臺(tái)兼容性。QString類直接支持字符串和數(shù)字之間的相互轉(zhuǎn)換。QString類直接支持字符串之間的大小比較(按照字典順序)。QString類直接支持不同編碼下的字符串轉(zhuǎn)換。QString類直接支持std::string和std::wstring之間的相互轉(zhuǎn)換。QString類直接支持正則表達(dá)式的使用。QT字符串QT字符串--數(shù)字和QString互相轉(zhuǎn)換使用static的函數(shù)number()可以把數(shù)字轉(zhuǎn)換成字符串。例如:QStringstr=QString::number(123.4);也可以使用非static函數(shù)setNum()來(lái)實(shí)現(xiàn)相同的目的:QStringstr;str.setNum(123.4);QString轉(zhuǎn)為int;QStringstr=“123”;intd=str.toInt();QT字符串--

char*和QString互相轉(zhuǎn)換將char*類型的C語(yǔ)言風(fēng)格的字符串轉(zhuǎn)換成QString類的對(duì)象也很常見(jiàn)。char*c_str=“HelloWords!”; //QStringstr(c_str); //char*轉(zhuǎn)換為QStringQString轉(zhuǎn)換為char*分為兩步,首先調(diào)用toAscii()獲得一個(gè)QByteArray類的對(duì)象,然后調(diào)用它的data()或者constData()函數(shù),為了方便起見(jiàn),Qt提供了一個(gè)宏qPrintable(),等價(jià)于toAscii().ConstData()。例如:printf(“ΜSer:%s/n”,str.toAscii().data());printf(“ΜSer:%s/n”,qPrintable(str));QT字符串--截?cái)嘧址畍oidtruncate(intposition);

//從位置position處截?cái)?,位置從索引?開(kāi)始voidchop(intposition); //截掉最后的n個(gè)字符QT字符串--清空voidclear();//清空QString類對(duì)象的內(nèi)容,使之成為空字符串QT字符串--字符串的比較intcompare(constQString&s1,constQString&s2);inta=QString::compare(“def”,“abc”); //a>0intb=QString::compare(“abc”,“def”); //b<0intc=QString::compare(“abc”,“abc”); //c=0QT字符串--判斷是否以某個(gè)字符串開(kāi)頭或結(jié)尾函數(shù)startsWith()用于判斷是否以某個(gè)字符串開(kāi)頭,函數(shù)endsWith()用于判斷是否以某個(gè)字符串結(jié)束。比如:QStringstr1=“d:\zcbBook\QT5.12Study\qw.cpp”;boolN=str1.endsWith(“.cpp”,Qt::CaseInsensitive);//N=trueN=str1.endsWith(“.cpp”,Qt::Casesensitive);

//N=falseN=str1.startsWith(“D”);

//N=true,默認(rèn)為不區(qū)分大小寫(xiě)又比如,以下兩句話等效:if(ur1.startsWith(“http:”)&&ur1.endsWith(“.png”)){}if(ur1.left(5)==“http:”&&ur1.right(4)==“.png”){}QT字符串--判斷是否包含某個(gè)字符串QStringstr1=“D:\北航云盤(pán)\07879\教材相關(guān)2020_0602\main.cpp”;N=str1.contains(“.CPP”,Qt::Casesensitive); //N=falseQT字符串--判斷字符串是否為空QStringstr1,str2=“”;

N=str1.isNull(); //N=true 未賦值字符串變量N=str2.isNull(); //N=false 只有“\0”的字符串也不是NullN=str1.isEmpty(); //N=trueN=str2.isEmpty(); //N=true上述例子給出了isNull()和isEmpty()的區(qū)別。對(duì)于“\0”,isNull()返回假,而isEmpty()返回真。QT字符串--移除字符成員函數(shù)remove()可以移除字符串中一個(gè)或者多個(gè)字符,函數(shù)原型聲明如下:QString&remove(intposition,intn);其中,參數(shù)position表示要被移除字符的起始索引位置;n表示要移除字符的個(gè)數(shù)。函數(shù)返回移除字符后字符串的引用。QStringtest=“Hi,Beihang!”; //字符串賦初值QStringtmp=test.remove(2,4); //從索引值為2的字符開(kāi)始,移除4個(gè)字符qDebug()<<“test”<<test; //輸出HihangqDebug()<<“tmp”<<tmp; //輸出HihangQT字符串--字母大小寫(xiě)的轉(zhuǎn)換使用成員函數(shù)toUpper()和toLower(),將字符串內(nèi)的字母全部轉(zhuǎn)換為大寫(xiě)形式和小寫(xiě)形式。QStringstr1=“Hi,Beihang!”,str2;str2=str1.toUpper(); //str1=“HI,BEIHANG”str2=str1.toLower(); //str1=“hi,beihang”QT字符串--獲取長(zhǎng)度共有三個(gè)成員函數(shù)count()、size()、length()返回字符串中字符的個(gè)數(shù)。示例如下:QStringstr1=“Hello北航”;N=str1.count(); //N=7N=str1.size(); //N=7N=str1.length(); //N=7QT字符串--復(fù)制運(yùn)算賦值運(yùn)算符是=,比如:QStringstr=“abcde”;QT字符串--訪問(wèn)某個(gè)元素QString元素的訪問(wèn)共有4種方式,兩種可讀可寫(xiě)方式([]、data[])和兩種可讀方式(at()、constData[])。QStringstr=“World”; //intn=str.size(); //n=5str.data()[0]; //返回Wstr.data()[4]; //返回d提綱Qt編程基礎(chǔ)圖形界面設(shè)計(jì)信號(hào)和槽機(jī)制Qt程序綜合實(shí)驗(yàn)—電子鐘設(shè)計(jì)Qt開(kāi)發(fā)環(huán)境的搭建界面是嵌入式系統(tǒng)的重要組成部分,其地位和作用也越來(lái)越重要。這得益于嵌入式系統(tǒng)硬件的發(fā)展和軟件技術(shù)的發(fā)展。雖然能夠設(shè)計(jì)界面的軟件有很多種,但Qt是嵌入式系統(tǒng)最為常用的圖形界面開(kāi)發(fā)軟件。即便Qt具有網(wǎng)絡(luò)編程、多媒體應(yīng)用、數(shù)據(jù)庫(kù)編程功能,Qt最大的作用還是在圖形用戶界面設(shè)計(jì)上,它有大量的用于圖形設(shè)計(jì)的類庫(kù),便于使用、易于擴(kuò)展。圖形界面設(shè)計(jì)Qt的窗口類WidgetQt的窗口類Widget本書(shū)例程中使用的QMainWindow是QWidget的直接繼承子類;QLineEdit是QWidget的直接繼承子類;QLabel繼承于QFrame,QFrame是QWidget的直接繼承子類;QPushButton繼承于QAbstractButton,QAbstractButton是QWidget的直接繼承子類。Qt的窗口類WidgetQt里有個(gè)概念叫窗口,窗口又稱為頂層部件,Qt把沒(méi)有嵌入到其他部件的部件叫窗口,很顯然,窗口是沒(méi)有父部件的部件。在Qt類庫(kù)中,就界面而言,QWidget、QMainWindow和QDialog是常見(jiàn)的三種窗口,其中尤以QWidget為最多??梢暬翱诮缑嬖O(shè)計(jì)Qt里有一個(gè)概念叫控件,控件又叫部件,有時(shí)也稱組件,是完成一段特定功能的程序代碼。比如,用于發(fā)送信息的QPushButton按鈕。很顯然這些控件被加入到某一窗口,以完成更加復(fù)雜的工程。這些控件添加到窗口里有幾種方法:使用可視化控件。通過(guò)拖拽控件,例如,添加按鈕。在Buttons下面找到PushButton按鈕,將鼠標(biāo)放在控件上,單擊鼠標(biāo)左鍵,就可將按鈕拖拽到窗口里,這種設(shè)計(jì)方法簡(jiǎn)單,同時(shí),控件可以放在你希望的任何位置,字體可大可小。代碼化設(shè)計(jì)。界面的底層既然是由C++實(shí)現(xiàn)的,底層實(shí)現(xiàn)的功能比可視化設(shè)計(jì)更加強(qiáng)大和靈活。某些界面效果是可視化界面設(shè)計(jì)無(wú)法完成的。特別復(fù)雜的邏輯功能,語(yǔ)言表達(dá)的能力遠(yuǎn)遠(yuǎn)超過(guò)可視化界面。

Qt中常用的控件常見(jiàn)的工具條上面的幾個(gè)工具條分別是:EditWidgetF3、EditSignals/SlotsF4、EditBuddies、EditTabOrder、水平布局(H)Ctrl+H、垂直布局(V)Ctrl+H、使用分裂器水平布局(P)、使用分裂器垂直布局(L)、在窗體布局中布局(F)、柵格布局器(G)Ctrl+G、打破布局(B)、調(diào)整大?。⊿)Ctrl+J。Qt控件--QPushButtonQPushButton類是QAbstractButton類的子類,通常用于執(zhí)行命令或觸發(fā)事件。單擊該按鈕通常是通知程序進(jìn)行一個(gè)操作,比如彈出框、下一步、狀態(tài)機(jī)事件遷移、確認(rèn)、退出等,大多數(shù)對(duì)話框程序中幾乎都有這種按鈕。⑴

按鈕的主要屬性有:name:該控件對(duì)應(yīng)源代碼中的名字。text:該控件對(duì)應(yīng)圖形界面中顯示的名字。font:設(shè)置text的字體。enable:該控件是否可用。⑵

按鈕常用的信號(hào)有:voidpressed();當(dāng)按下該按鈕時(shí)發(fā)射信號(hào)。voidclicked();當(dāng)單擊該按鈕時(shí)發(fā)射信號(hào)。voidreleased();當(dāng)發(fā)射按鈕時(shí)發(fā)射信號(hào)。Qt控件--QPushButton⑶

按鈕常用的成員函數(shù)有:構(gòu)造函數(shù)QPushButton():QPushButton(constQString&text,QWidget*parent,const*name=0);構(gòu)造一個(gè)名稱為name、父對(duì)象為parent并且文本為text的按鈕。比如:QPushButton*button=newQPushButton(tr(“確定”),this);setText()函數(shù):voidsetText(constQString&);設(shè)置該按鈕上顯示的文本。text()函數(shù):QStringtext()const;返回該按鈕上顯示的文本。Qt控件--QlabelQLabel類是QFrame類的子類,用于簡(jiǎn)單的界面顯示。QLabel共66個(gè)屬性:6個(gè)繼承自QFrame,59個(gè)繼承自QWidget,1個(gè)繼承自QObject。19個(gè)公共槽函數(shù)繼承自QWidget,1個(gè)公共槽函數(shù)繼承自QObject。⑴QLabel的主要屬性有:text:QString文本內(nèi)容。pixmap:加載圖片。scaledContents:bool默認(rèn)為false,當(dāng)設(shè)為true時(shí),自動(dòng)填滿空間。openExternalLinks:bool指定是否使用QDesktopServicesQlabel。hasSelectedText:constbool默認(rèn)為false,當(dāng)有內(nèi)容被選中時(shí)為true。margin:int邊緣的寬度。indent:int縮進(jìn),以像素為單位,默認(rèn)為-1。Qt控件--Qlabel⑵PublicSlots:voidclear(); //清零QLAbelvoidsetMovie(QMovie*movie); //在QLabel上播放沒(méi)有聲音的動(dòng)畫(huà)voidsetNum(intnum); //顯示整型數(shù)voidsetNum(doublenum); //顯示double型的數(shù)voidsetPixmap(constQPixmap&);

//顯示圖畫(huà)voidsetText(constQString&); //顯示字符串Qt控件--Qlabel⑶QLabel常用信號(hào)有:voidlinkActivated(constQString&link); //當(dāng)用戶單擊一個(gè)鏈接時(shí)發(fā)出這個(gè)信號(hào)voidlinkHovered(constQString&link); //當(dāng)用戶將鼠標(biāo)懸停于一個(gè)鏈接時(shí),發(fā)出這個(gè)信號(hào)。Qt控件--Qlabel⑷QLabel常用公有函數(shù)有:QStringtext()const; //讀取文本QMovie*movie()const; //返回Move的指針,沒(méi)有返回0voidsetSelection(intstart,intlength);//設(shè)置選中的文本,開(kāi)始位和長(zhǎng)度pixmap()const; //返回pixmap的指針,沒(méi)有返回0QWidget*buddy()const; //返回交互的控件指針,單擊一個(gè)控件另一

個(gè)控件也會(huì)單擊voidsetTextFormat(Qt::TextFormat);//設(shè)置文本格式QLineEdit類是QWidget類的子類,通常用于簡(jiǎn)單文本輸入,例如鍵盤(pán)上輸入文本或數(shù)據(jù)到QLabel上。QLineEdit共60個(gè)屬性:59個(gè)繼承自QWidget,1個(gè)繼承自QObject。

行編輯框(QLineEdit)的主要屬性有:inputMask //掩碼(默認(rèn)格式)text //文本maxLength //最大長(zhǎng)度echoMode //回響模式(輸入的文字的樣子)cursorPosition //鼠標(biāo)位置aligment //對(duì)齊方式dragEnabled //拖拽使能readOnly //只讀placeHolderText //提示信息cursorMoveStyle //鼠標(biāo)移動(dòng)形式clearButtonEnabled //清零按鈕使能Qt控件--QLineEdit⑵

行編輯框常用信號(hào)有:voidcursorPositionChanged(intold,intnew);//當(dāng)光標(biāo)位置改變時(shí),發(fā)射信號(hào)。old表示舊位置,new表示新位置。voideditingFinished(); //當(dāng)編輯完成時(shí)按回車(chē)鍵,發(fā)射信號(hào)voidreturnFinished(); //光標(biāo)在行編輯框內(nèi)按回車(chē)鍵,發(fā)射信號(hào)voidselectionChanged(); //選擇的文本發(fā)生改變時(shí),發(fā)射信號(hào)voidtextChanged(constQString&text);//當(dāng)內(nèi)容改變后,發(fā)射信號(hào)。通過(guò)text,可以在槽函數(shù)中獲取編輯框中的內(nèi)容voidtextEdited(constQString&text);//當(dāng)文本被編輯時(shí),發(fā)射信號(hào)。當(dāng)調(diào)用setText()函數(shù)改變文本時(shí),textEdited()也會(huì)發(fā)射信號(hào)Qt控件--QLineEdit⑶行編輯框常用的成員函數(shù)有:voidsetText(QString); //設(shè)置編輯框內(nèi)的文本voidsetReadOnly(bool); //設(shè)置編輯框?yàn)橹蛔x模式,無(wú)法進(jìn)行編輯voidsetEnabel(bool); //設(shè)置是否激活行編輯框boolisModified(); //判斷文本是否被修改voidselectAll(); //選中框內(nèi)所有文本QStringdisplayText(); //返回顯示的文本QStringselectedText(); //返回被選中的文本QStringtext()const; //返回輸入框的當(dāng)前文本voidsetMaxLength(int); //設(shè)置文本的最大允許長(zhǎng)度voidsetPlaceholderText(QString); //設(shè)置占位符voidsetEchoMode(QLineEdit::EchoMode);//設(shè)置輸入方式,比如參數(shù)是QLineEdit::PassWord的時(shí)候,則輸入的內(nèi)容以星號(hào)表示,即密碼輸入方式Qt控件--QLineEditQt控件--QTimerQTimer繼承自QObject,它不是嚴(yán)格意義上的控件,它是Qt的類。它是一個(gè)定時(shí)器,通過(guò)設(shè)置定時(shí)時(shí)間,產(chǎn)生溢出,發(fā)出信號(hào),執(zhí)行對(duì)應(yīng)的周期時(shí)間處理函數(shù)。⑴

QTimer的主要屬性有:active:constbool //如果定時(shí)器正在運(yùn)行為true,其他為falsesingleShot:bool //發(fā)射一次信號(hào)設(shè)為true,定時(shí)器只運(yùn)行一次interval:int //用來(lái)設(shè)置定時(shí)器間隔remainingTime:int //剩余時(shí)間,初始化為-1,啟動(dòng)后直到為0timerType:Qt::TimerType //定時(shí)器準(zhǔn)確性設(shè)置,默認(rèn)屬性為粗

糙定時(shí)器(%5誤差)Qt控件--QTimer⑵

QTimer常用的信號(hào):voidtimeout();//定時(shí)溢出信號(hào),通過(guò)信號(hào)和槽的關(guān)聯(lián),執(zhí)行相關(guān)操作。⑶

QTimer的公共槽函數(shù)voidstart(intmsec);

//周期性啟動(dòng),時(shí)間間隔的單位是毫秒voidstart(); //定時(shí)器啟動(dòng)voidstop(); //定時(shí)器停止⑷

公有函數(shù)QTimer(QObject*parent=0);//構(gòu)造函數(shù)inttimerId()const; //返回id,如果正在運(yùn)行返回-1提綱Qt編程基礎(chǔ)圖形界面設(shè)計(jì)信號(hào)和槽機(jī)制Qt程序綜合實(shí)驗(yàn)—電子鐘設(shè)計(jì)Qt開(kāi)發(fā)環(huán)境的搭建信號(hào)和槽機(jī)制—基本概念信號(hào)和槽機(jī)制是Qt的核心機(jī)制。它是Qt的核心特性,也是Qt區(qū)別于其他工作包的重要地方。信號(hào)和槽是一種高級(jí)接口,應(yīng)用于對(duì)象之間的通信,信號(hào)和槽是Qt自定義的一種通信機(jī)制,獨(dú)立于標(biāo)準(zhǔn)的C/C++語(yǔ)言。因此要正確地處理信號(hào)和槽,必須借助一個(gè)稱為moc(metaobjectcompiler)的Qt工具,該工具是一個(gè)C++預(yù)處理程序,它為高層次的事件處理自動(dòng)生成所需要的附加代碼。從計(jì)算機(jī)程序的角度看,對(duì)象之間必須進(jìn)行某種關(guān)聯(lián)。比如,敲擊鍵盤(pán),顯示對(duì)象必須做出響應(yīng)。Qt對(duì)它們的描述是信號(hào)和槽,擊打鍵盤(pán)發(fā)出的信號(hào),信號(hào)的本質(zhì)也是函數(shù),信號(hào)可以由widget發(fā)出,widget所發(fā)信號(hào)是由Qt的事件產(chǎn)生。如果使用系統(tǒng)預(yù)定義的控件,那么我們關(guān)心的是信號(hào);如果使用的是自定義控件,那么我們關(guān)心的是事件。信號(hào)和槽機(jī)制—基本概念事件信號(hào)槽元對(duì)象編譯器基本概念—事件事件是由程序內(nèi)部或外部產(chǎn)生的事情或某種操作的總稱。Qt常見(jiàn)的事件有:定時(shí)器事件(QTimerEvent)滾動(dòng)事件(QScrollEvent)窗口尺寸改變事件(QResizeEvent)鍵盤(pán)事件(QKeyEvent)鼠標(biāo)事件(QMouseEvent)等Qt中的事件循環(huán)是由QApplication.exec()開(kāi)始的。當(dāng)該語(yǔ)句執(zhí)行后,應(yīng)用程序便建立了一個(gè)事件循環(huán)機(jī)制,該機(jī)制不斷地從系統(tǒng)的消息隊(duì)列中獲取與應(yīng)用程序有關(guān)的消息,并根據(jù)事件攜帶的信息將事件對(duì)應(yīng)到目的窗口或控件。signals是Qt的概念,它的引入是為了方便事件的處理。signals封裝了一些事件操作的標(biāo)準(zhǔn)預(yù)處理,使得用戶不必去關(guān)心底層事件,只需要處理封裝好的信號(hào)就行了。signals的本質(zhì)也是函數(shù),該函數(shù)是void類型,沒(méi)有函數(shù)體??梢詻](méi)有參數(shù),也可以有一個(gè)或者多個(gè)參數(shù)。Qt定義了很多預(yù)處理信號(hào),且在某些事件處理函數(shù)中會(huì)發(fā)送預(yù)定義的信號(hào)。例如,QPushButton類的按鈕按下的時(shí)候可以發(fā)送clicked()信號(hào),從用戶的角度看,clicked()信號(hào)可以直接拿來(lái)關(guān)聯(lián)槽函數(shù),編寫(xiě)相關(guān)的響應(yīng)槽函數(shù)即可。至于clicked()信號(hào)的生成過(guò)程是由Qt自動(dòng)完成的,無(wú)須用戶關(guān)心。在頭文件中聲明信號(hào)如下:signals:voidgetText(); voidgetText(constQString&string1);voidgetText(constQString&string1,constQString&string2);上述的三個(gè)信號(hào)量同名,第一個(gè)信號(hào)量不帶參數(shù),第二個(gè)信號(hào)量帶一個(gè)參數(shù),第三個(gè)信號(hào)量帶兩個(gè)參數(shù)。從形式上講信號(hào)的聲明與普通的C++函數(shù)是一樣的,但是信號(hào)卻沒(méi)有函數(shù)體定義,另外,信號(hào)的返回類型都是void,不要指望能從信號(hào)返回什么有用信息。基本概念—信號(hào)基本概念—槽槽的本質(zhì)是類的成員函數(shù),可以是public、private、protected中的任意一種。一個(gè)信號(hào)可以關(guān)聯(lián)一個(gè)槽,一個(gè)信號(hào)關(guān)聯(lián)多個(gè)槽,多個(gè)信號(hào)可以關(guān)聯(lián)同一個(gè)槽,一個(gè)信號(hào)甚至能夠和另一個(gè)信號(hào)相關(guān)聯(lián)。槽函數(shù)功能的定義相當(dāng)靈活,可大可小。對(duì)多個(gè)信號(hào)的處理,當(dāng)然可以在多個(gè)槽函數(shù)中進(jìn)行,也可以在一個(gè)槽函數(shù)中進(jìn)行。槽的聲明也是在頭文件中進(jìn)行的。例如,下面聲明了兩個(gè)槽:privateslots:voidQlabel_response(); voidWriteTextToLabel(constQString&string);privateslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著只有類自己可以將信號(hào)與之相連接。這適用于

聯(lián)系非常緊密的類。protectedslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著當(dāng)前類及其子類可以將信號(hào)與之相連接。這適用于那些槽,它們是類實(shí)現(xiàn)的一部分,但是其界面接口卻面向外部。publicslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著任何對(duì)象都可將信號(hào)與其相連接。用戶可以創(chuàng)建彼此互不了解的對(duì)象,將它們的信號(hào)與槽進(jìn)行連接以便信息能夠正確的傳遞?;靖拍睢獙?duì)象編譯器Qt中有個(gè)重要的概念叫元對(duì)象編譯器。它是Qt對(duì)C++的發(fā)展,元對(duì)象包含全部信號(hào)和槽的名字以及指向這些函數(shù)的指針。當(dāng)用戶需要使用moc的時(shí)候,要在類聲明的使用調(diào)用宏Q_OBJECT。調(diào)用了Q_OBJECT就能夠使用Qt的信號(hào)與槽機(jī)制。moc并不擴(kuò)展#include或者#define宏定義,它只是簡(jiǎn)單地跳過(guò)所遇到的任何預(yù)處理指令,所以宏定義不能用在信號(hào)與槽的參數(shù)中。信號(hào)和槽機(jī)制信號(hào)和槽機(jī)制信號(hào)和槽是Qt為解決對(duì)象間通信問(wèn)題的解決方案。信號(hào)和槽只能在QObject和QObject派生類中使用。自定義的類,如果基類不是QObject和QObject派生類,就不能使用信號(hào)和槽機(jī)制。信號(hào)和槽是Qt框架的重要特性,它摒棄了傳統(tǒng)回調(diào)函數(shù)機(jī)制,采用簡(jiǎn)潔而靈活的連接方式,可以攜帶任意數(shù)量和任意參數(shù)的數(shù)據(jù),是可視化編程界面在發(fā)展歷程中的一大成就。當(dāng)對(duì)象改變其狀態(tài)時(shí),信號(hào)就由該對(duì)象發(fā)射(emit)出去,信號(hào)的發(fā)送對(duì)象并不知道誰(shuí)在關(guān)聯(lián)這個(gè)信號(hào)。這就給信號(hào)發(fā)送的設(shè)計(jì)提供了極大的便利。這是真正的信息封裝,確保對(duì)象被當(dāng)做一個(gè)真正的軟件組件來(lái)使用。上圖是信號(hào)與槽關(guān)聯(lián)方式結(jié)構(gòu)示意圖。圖中信號(hào)和槽關(guān)聯(lián)方式多樣:一個(gè)信號(hào)和一個(gè)槽關(guān)聯(lián),一個(gè)信號(hào)和多個(gè)槽關(guān)聯(lián),多個(gè)信號(hào)和一個(gè)槽關(guān)聯(lián)。完成信號(hào)和槽關(guān)聯(lián)后,該機(jī)制隱藏復(fù)雜的底層實(shí)現(xiàn)。信號(hào)和槽的關(guān)聯(lián)該函數(shù)的定義如下:boolQObject::connect(constQOject*sender,constchar*signal,constQObject*receiver,constchar*member)[static]這個(gè)函數(shù)的作用就是將sender對(duì)象中的信號(hào)signal與接收者receiver中的member槽函數(shù)聯(lián)系起來(lái)。當(dāng)指定信號(hào)signal時(shí),必須使用Qt的宏SIGNAL();當(dāng)指定槽函數(shù)時(shí),必須使用宏SLOT()。如果發(fā)射者與接收者屬于同一個(gè)對(duì)象,那么在connect調(diào)用中接收者參數(shù)可以省略。例如,下面定義了兩個(gè)對(duì)象:標(biāo)簽對(duì)象label和滾動(dòng)條對(duì)象scroll,并將valueChanged()信號(hào)與標(biāo)簽對(duì)象的setNum()相關(guān)聯(lián),另外信號(hào)還攜帶一個(gè)整型參數(shù),這樣標(biāo)簽總是顯示滾動(dòng)條所處位置的值。QLabel*label =newQLabel;QScrollBar*scroll=newQScrollBar;QObject::connect(scroll,SIGNAL(valueCbanged(int)),label,SLOT(setNum(int)));信號(hào)和槽的斷開(kāi)當(dāng)信號(hào)與槽沒(méi)有必要繼續(xù)保持關(guān)聯(lián)時(shí),可以使用disconnect函數(shù)來(lái)斷開(kāi)連接。其定義如下:boolQObject::disconnect(constQObject*sender,constchar*signal,constObject*receiver,constchar*member)[static]這個(gè)函數(shù)斷開(kāi)發(fā)射者中的信號(hào)與接收者中的槽函數(shù)之間的關(guān)聯(lián)。取消一個(gè)連接不是很常用,因?yàn)镼t會(huì)在一個(gè)對(duì)象被刪除后自動(dòng)取消這個(gè)對(duì)象所包含的所有連接。有三種情況必須使用disconnect()函數(shù)。(1)斷開(kāi)與某個(gè)對(duì)象相關(guān)聯(lián)的任何對(duì)象。這似乎有點(diǎn)不可理解,事實(shí)上,當(dāng)在某個(gè)對(duì)象中定義了一個(gè)或者多個(gè)信號(hào)時(shí),這些信號(hào)與另外若干個(gè)對(duì)象中的槽相關(guān)聯(lián),如果要切斷這些關(guān)聯(lián)的話,就可以利用這個(gè)方法,非常簡(jiǎn)潔。disconnect(myObject,0,0,0);或者myObject→disconnect();信號(hào)和槽的斷開(kāi)(2)斷開(kāi)與某個(gè)特定信號(hào)的任何關(guān)聯(lián)。disconnect(myObject,SIGNAL(mySignal()),0,0);或者myObject→disconnect(SIGNAL(mySignal()));(3)斷開(kāi)兩個(gè)對(duì)象之間的關(guān)聯(lián)。disconnect(myObject,SIGNAL0,myReceiver(),0);或者myObject→disconnectmyReceiver();在disconnect函數(shù)中0可以用作一個(gè)通配符,分別表示任何信號(hào)、任何接收對(duì)象和接收對(duì)象中的任何槽函數(shù)。但是發(fā)射者sender不能為0,其他三個(gè)參數(shù)的值都可以等于0。信號(hào)和槽示例--頭文件(.h)信號(hào)和槽示例--源文件(.cpp)示例給出了完整的頭文件和源文件。文件中定義了一個(gè)信號(hào)量和一個(gè)槽函數(shù),對(duì)信號(hào)和槽進(jìn)行了關(guān)聯(lián),槽函數(shù)在調(diào)試區(qū)打印了一句話。信號(hào)和槽的聲明在頭文件里進(jìn)行,頭文件的開(kāi)始部分加上Q_OBJECT宏定義語(yǔ)句,告訴編譯器在編譯之前必須要應(yīng)用moc工具進(jìn)行擴(kuò)展,否則無(wú)法使用信號(hào)與槽。關(guān)鍵字signals指出了隨后開(kāi)始信號(hào)的聲明,不存在單數(shù)形式的signal,屬性沒(méi)有public、private和protected。信號(hào)量的本質(zhì)是函數(shù),它的聲明左邊是void類型(必須是void類型),右邊是括號(hào),括號(hào)內(nèi)可以有一個(gè)或多個(gè)參數(shù),也可以不帶參數(shù),如文中的signals:voidmy_signal()。信號(hào)也可以使用C++中虛函數(shù)的形式進(jìn)行聲明,即同名參數(shù)不同。信號(hào)和槽示例關(guān)鍵字slots指出隨后開(kāi)始槽的聲明,和普通的成員函數(shù)一樣,槽函數(shù)可以是public、private和protected中的一種。槽函數(shù)不同于普通成員函數(shù)有兩點(diǎn):一是它必須是void類型,沒(méi)有返回值;二是它可以關(guān)聯(lián)信號(hào)。signals和slots是Qt的關(guān)鍵字,不是C++的關(guān)鍵字。斷開(kāi)信號(hào)和槽連接時(shí)可以使用disconnect函數(shù),讀者可以參考有關(guān)文獻(xiàn)。有時(shí),disconnect函數(shù)不是顯性表示出來(lái)的,它可以在析構(gòu)類的時(shí)候被調(diào)用。信號(hào)和槽示例示例使用三個(gè)connect語(yǔ)句,connect(this,SIGNAL(test_signal()),this,SLOT(test_slot()))是使用最多的形式,SIGNAL、SLOT形式的信號(hào)和槽能夠清楚表達(dá)參數(shù)的個(gè)數(shù)和類型,因此支持同名不同參數(shù)的信號(hào)(比如信號(hào)沒(méi)有參數(shù)或者有一個(gè)參數(shù)或者有多個(gè)參數(shù))。connect(this,&MainWindow::test_signal,this,&MainWindow::test_slot)是指針形式,信號(hào)和槽都是由指針指向。需要注意,兩者相比,指針指向信號(hào)和槽的時(shí)候要加上類名。connect(this,&MainWindow::test_signal,[&](){doEverything();});這是lambda表達(dá)式形式的匿名函數(shù),也經(jīng)常出現(xiàn)在各種設(shè)計(jì)中。大家對(duì)以上幾種connect對(duì)比學(xué)習(xí),體會(huì)各種設(shè)計(jì)的優(yōu)缺點(diǎn)。信號(hào)和槽示例信號(hào)和槽小結(jié)--信號(hào)和槽機(jī)制的優(yōu)點(diǎn)信號(hào)和槽的機(jī)制是類型安全的:一個(gè)信號(hào)的簽名必須與它的接收槽的簽名相匹配(實(shí)際上一個(gè)槽的簽名可以比它接收的信號(hào)的簽名少,因?yàn)樗梢院雎灶~外的簽名)。因?yàn)楹灻且恢碌模幾g器就可以幫助用戶檢測(cè)類型不匹配。信號(hào)和槽是寬松地聯(lián)系在一起的。一個(gè)發(fā)射信號(hào)的類不用知道也不用注意哪個(gè)槽要接收這個(gè)信號(hào),Qt的信號(hào)和槽的機(jī)制可以保證如果把一個(gè)信號(hào)和一個(gè)槽連接起來(lái),槽會(huì)在正確的時(shí)間使用信號(hào)的參數(shù)而被調(diào)用,信號(hào)和槽可以使用任何數(shù)量和任何類型的參數(shù)。它們是完全類型安全的:不會(huì)再有回調(diào)核心轉(zhuǎn)儲(chǔ)(coredump)。信號(hào)和槽小結(jié)--信號(hào)和槽使用時(shí)注意事項(xiàng)信號(hào)與槽機(jī)制是比較靈活的,但有些局限性必須了解,這樣在實(shí)際的使用過(guò)程中可以做到有的放矢,避免產(chǎn)生一些錯(cuò)誤。下面就介紹一下這方面的情況。信號(hào)與槽的效率是非常高的,但是與真正的回調(diào)函數(shù)比較起來(lái),由于增加了靈活性,因此在速度上還是有所損失,當(dāng)然這種損失相對(duì)來(lái)說(shuō)是比較小的,通過(guò)在一臺(tái)i586-133的機(jī)器上測(cè)試完成一個(gè)信號(hào)傳輸?shù)臅r(shí)間是10μS(運(yùn)行Linux),可見(jiàn)這種機(jī)制所提供的簡(jiǎn)潔性、靈活性還是值得的,但如果要追求高效率的話,如在實(shí)時(shí)系統(tǒng)中就要盡量少用這種機(jī)制。信號(hào)與槽機(jī)制與普通函數(shù)的調(diào)用一樣,如果使用不當(dāng)?shù)脑?,在程序?zhí)行時(shí)也有可能產(chǎn)生死循環(huán)。因此,在定義槽函數(shù)時(shí)一定要注意避免間接形成無(wú)限循環(huán),即在槽中再次發(fā)射所接收到的同樣信號(hào)。例如,在前面給出的例子中如果在mySlot()槽函數(shù)中加上語(yǔ)句emitmySignal()即可形成死循環(huán)。如果一個(gè)信號(hào)與多個(gè)槽相聯(lián)系的話,那么,當(dāng)這個(gè)信號(hào)被發(fā)射時(shí),與之相關(guān)的槽被激活的順序?qū)⑹请S機(jī)的。宏定義不能用在signal和slot的參數(shù)中,信號(hào)和槽小結(jié)--信號(hào)和槽的四種實(shí)現(xiàn)方式信號(hào)和槽是Qt連接信號(hào)和槽函數(shù)的樞紐,connect只是連接信號(hào)和槽的一種方式。下面補(bǔ)充說(shuō)明一下。(1)以QPushButton按鈕為例,在左側(cè)的工具欄里拖拽一個(gè)按鈕,對(duì)象名改為“PushButton”,鼠標(biāo)放在按鈕上,單擊右鍵,選擇“轉(zhuǎn)到槽…”,在轉(zhuǎn)到槽選擇面板上,選擇需要進(jìn)行的操作,比如單擊clicked()。(2)操作同上,將按鈕拖拽到ui頁(yè)面,選擇菜單“編輯”,找到EditSignals/Slots(或者按快捷鍵F4),或者在工具欄里找到EditSignals/Slots,然后拖拽按鈕并釋放,彈出配置連接。QPushButton(QPushButton)下選clicked(bool),Mainwindow(QMainwindow)下選setAnimated(bool)。信號(hào)和槽小結(jié)--信號(hào)和槽的四種實(shí)現(xiàn)方式(3)自定義方式。這種方式編程時(shí)比較自由,特別是當(dāng)程序很大或者信號(hào)和槽間的連接關(guān)系特別復(fù)雜的時(shí)候,常常采用connect函數(shù)連接的方式。在頭文件的私有槽函數(shù)(privatedslots)中添加:voidon_button1_clicked();在cpp文件下面的構(gòu)造函數(shù)里添加connect(ui->PushButton,SIGNAL(clicked(),this,SLOT(on_button1_clicked()));接著實(shí)現(xiàn)槽函數(shù)即可。(4)不用寫(xiě)connect。Qt信號(hào)和槽的命名是有規(guī)則的。槽函數(shù)名組成為:on_對(duì)象名_信號(hào),以按鈕為例,如果對(duì)象名為PushButton,在你寫(xiě)槽函數(shù)時(shí)按此規(guī)則,在頭文件中添加:privateslots:voidon_PushButton_clicked();在cpp文件的構(gòu)造函數(shù)里就不要寫(xiě)構(gòu)造函數(shù)了。不難看出,方法⑷和方法⑴有異曲同工之妙。從信號(hào)與槽關(guān)聯(lián)效果上看,兩種完全同效。方法⑴簡(jiǎn)單,是系統(tǒng)自動(dòng)完成的;方法⑷有點(diǎn)復(fù)雜,是程序員手工完成的。提綱Qt編程基礎(chǔ)圖形界面設(shè)計(jì)信號(hào)和槽機(jī)制Qt程序綜合實(shí)驗(yàn)—電子鐘設(shè)計(jì)Qt開(kāi)發(fā)環(huán)境的搭建Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—需求說(shuō)明本實(shí)驗(yàn)虛擬機(jī)的版本是VMwareWorkstation15pro,Ubantu的版本是18.04,Qt的版本是5.12.8。通過(guò)設(shè)計(jì)一個(gè)圖形化的用戶界面實(shí)現(xiàn)電子鐘來(lái)說(shuō)明Qt程序設(shè)計(jì)與實(shí)現(xiàn)的過(guò)程。這個(gè)應(yīng)用程序應(yīng)該具如下基本功能:設(shè)計(jì)電子鐘的用戶界面。界面包括顯示時(shí)間的時(shí)、分、秒、毫秒,毫秒顯示的單位是10mS,便于顯示的直觀。具有啟動(dòng)/停止、暫停、復(fù)位功能。通過(guò)啟動(dòng)/停止按鈕,實(shí)現(xiàn)電子鐘的啟停,暫停后可以繼續(xù)計(jì)時(shí),復(fù)位鍵可實(shí)現(xiàn)清零。當(dāng)秒表使用??墒謩?dòng)設(shè)置電子鐘的時(shí)間??墒謩?dòng)設(shè)置時(shí)間,通過(guò)界面的功能鍵,切換為計(jì)時(shí)狀態(tài)和設(shè)置狀態(tài),用一個(gè)Qlabel顯示電子鐘的工作狀態(tài)。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—界面設(shè)計(jì)界面使用8個(gè)QLabel。該類對(duì)象包括dot1~dot3,分別是“時(shí)”“分”“秒”之間的“:”以及“秒”與“毫秒”之間的“.”;label_hour、label_minus、label_second、label_ms,用于顯示電子鐘的“時(shí)”“分”“秒”“毫秒”;label_status是電子鐘的功能顯示,用于指示電子鐘(包括秒表)工作狀態(tài)以及時(shí)間調(diào)整狀態(tài)。這8個(gè)QLabel的.text屬性,即編程界面顯示的字符分別是hour:minus:second.ms、Status。類對(duì)象(objectName)用于編程,.text用于靜態(tài)顯示。界面使用4個(gè)QPushButton。該類對(duì)象包括Start_Button、Reset_Button、Pause_Button、FUN_Button,對(duì)應(yīng)的.text是Start、Reset、Pause和FUNKey。FUN_Button共有四種模態(tài),每按下一次,由Status顯示,依次切換“電子鐘狀態(tài)”“設(shè)置時(shí)”“設(shè)置分”“設(shè)置秒”?!半娮隅姞顟B(tài)”可啟停、暫停、復(fù)位電子鐘。設(shè)置時(shí)間時(shí)對(duì)應(yīng)的指示對(duì)象在閃爍。FUN_Button開(kāi)機(jī)默認(rèn)值是“電子鐘狀態(tài)”。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—界面設(shè)計(jì)界面使用一個(gè)QLineEdit。類對(duì)象是LineEditButton,用于QString數(shù)據(jù)類型數(shù)據(jù)的輸入。將鼠標(biāo)放在該控件上,即可由鍵盤(pán)輸入“時(shí)”、“分”、“秒”數(shù)據(jù),相關(guān)代碼將進(jìn)行對(duì)應(yīng)的限幅處理,即“時(shí)”的最大值是23,“分”“秒”的最大值是59。輸入的數(shù)據(jù)由鍵盤(pán)上的“Enter”結(jié)束。同時(shí)“Enter”鍵清空LineEditButton,便于下一次數(shù)據(jù)的輸入。界面使用了控件QLabel、QPushButton和QLineEdit,同時(shí)在程序里使用了QTimer定時(shí)器,通過(guò)編寫(xiě)對(duì)應(yīng)的程序,完成電子鐘運(yùn)行時(shí)的各種操作。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—界面設(shè)計(jì)Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—文件結(jié)構(gòu)電子鐘是通過(guò)一個(gè)項(xiàng)目來(lái)完成的,這個(gè)項(xiàng)目的名字叫ClockW,項(xiàng)目?jī)?nèi)的文件結(jié)構(gòu)如上圖所示。除了這個(gè).pro文件,還包括一個(gè).h的頭文件,兩個(gè).cpp的源文件,一個(gè).ui的界面文件。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—

項(xiàng)目文件這個(gè)文件是創(chuàng)建項(xiàng)目時(shí)候由軟件自動(dòng)生成的。第一行表明這個(gè)項(xiàng)目使用的模塊。core模塊包含了Qt的核心模塊,gui模塊包含了窗口系統(tǒng)集成、事件處理、OpenGL和OpenGLES集成、2D圖形、基本圖像、字體和文本等功能。第二行添加了widgets模塊,Qtwidgets模塊提供了經(jīng)典的桌面用戶界面的Ui元素集合,所有Qt界面部件都應(yīng)該在這個(gè)模塊中。第三行表明使用c++11的標(biāo)準(zhǔn)進(jìn)行編譯。第四行定義編譯選項(xiàng)。第五行是源文件。第六行是頭文件。第七行是界面文件。第八行~第十行指定目標(biāo)路徑。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—頭文件Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—頭文件Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—頭文件這個(gè)頭文件名字和頭文件的框架可以在新建項(xiàng)目時(shí)自動(dòng)生成,上述代碼非斜體部分語(yǔ)句均為創(chuàng)建項(xiàng)目時(shí)自動(dòng)生成。常量、變量、槽函數(shù)以及信號(hào)量為用戶自己定義。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—頭文件namespace是C++保留字,是一個(gè)由程序設(shè)計(jì)者命名的內(nèi)存區(qū)域。為避免產(chǎn)生命名沖突,將Ui的MainWindow實(shí)體放在命名空間里,從而與其他全局實(shí)體分割開(kāi)來(lái)。例如,ui->label_mS->setText("00"),該行代碼中的label_mS是QLabel的類對(duì)象,前面加上的“ui->”稱為被限定名(qualifiedname)。細(xì)心的讀者會(huì)發(fā)現(xiàn)這個(gè)ui不是上文中的Ui。是的,它們之間的關(guān)系是:Ui是類,ui是它的對(duì)象指針,指向Ui的成員函數(shù)MainWindow。本實(shí)驗(yàn)中,所有的拖拽的控件都可由ui指針指向。例如,復(fù)位按鍵,它在程序中出現(xiàn)的表示方法是ui->Reset_Button。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—頭文件#include<QMainWindow>是包含QMainWindow類的頭文件。#include<QTimer>添加了控件QTimer的頭文件。#include<QDebug>包含QDebug頭文件,為了使用QDebug功能,打印調(diào)試語(yǔ)句用。Q_OBJECT是宏定義,程序需要使用信號(hào)和槽的時(shí)候,必須有這個(gè)宏定義,否則不支持信號(hào)與槽機(jī)制。頭文件定義了四個(gè)槽函數(shù)和兩個(gè)私有成員函數(shù)。用signals定義了一個(gè)信號(hào)量,特別需要說(shuō)明,signals不屬于public、private和protected中的任何一種,他們之間是平行關(guān)系。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—main.cppmain函數(shù)包含兩個(gè)頭文件。main函數(shù)開(kāi)始的部分執(zhí)行QApplicationa(argc,argv[]),argc是命令行變量的數(shù)量,argv是命令行變量的數(shù)組,當(dāng)該語(yǔ)句執(zhí)行后,應(yīng)用程序便建立了一個(gè)事件循環(huán)機(jī)制,該機(jī)制不斷地從系統(tǒng)的消息隊(duì)列中獲取與應(yīng)用程序有關(guān)的消息,并根據(jù)事件攜帶的信息將事件發(fā)送到目的的窗口或控件。main程序里定義了一個(gè)窗口控件w,并引用了w的顯示函數(shù),顯示電子鐘的時(shí)間和操作的控件。通過(guò)調(diào)用QApplication.exec()啟動(dòng)事件主循環(huán)。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—mainwindow.cppQt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—mainwindow.cppmainWindow的構(gòu)造器函數(shù),用于項(xiàng)目的初始化。ui->setupUi(this)用于初始化界面。this->setWindowTitle(“可設(shè)置電子鐘”)設(shè)置窗口的標(biāo)題欄。flashtimer=newQTimer;是創(chuàng)建的閃爍定時(shí)器,這種動(dòng)態(tài)創(chuàng)建定時(shí)器的方法要明顯好于靜態(tài)定義QTimerflashtimer,因?yàn)閯?dòng)態(tài)創(chuàng)建的定時(shí)器在執(zhí)行析構(gòu)函數(shù)的時(shí)候資源就釋放了。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—mainwindow.cppui->label_status->setText("…”)設(shè)置電子鐘工作狀態(tài)的初始值,大的狀態(tài)分,電子鐘可工作在運(yùn)行狀態(tài)和參數(shù)修改狀態(tài)(參數(shù)修改狀態(tài)分為修改時(shí)、修改分、修改秒),運(yùn)行狀態(tài)分為啟動(dòng)(停止)、暫停和復(fù)位狀態(tài)。程序運(yùn)行后初始處于運(yùn)行狀態(tài)的暫停態(tài)。相關(guān)的初始變量和輔助變量清零,電子鐘顯示狀態(tài)清零。flashtimer->setInterval(500),時(shí)間設(shè)定時(shí)閃爍定時(shí)器設(shè)為500mS。每500mS定時(shí)器產(chǎn)生一次溢出,溢出信號(hào)觸發(fā)關(guān)聯(lián)的槽函數(shù),槽函數(shù)里閃爍被修改參數(shù)。clocktimer->setInterval(Interval)設(shè)定為定時(shí)時(shí)間,最小定時(shí)時(shí)間可設(shè)為1mS;最大是4字節(jié)整型數(shù)乘以1mS的整數(shù)倍,認(rèn)為是無(wú)窮大。Interval被設(shè)定為10,意味著顯示器每0.01秒刷新一次。

Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—InitSignalSlots()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—InitSignalSlots()InitSignalSlots()是槽函數(shù)初始化,包括7個(gè)connect()函數(shù)。對(duì)信號(hào)和槽關(guān)聯(lián)的處理是本實(shí)驗(yàn)一大特色,包括多個(gè)信號(hào)對(duì)應(yīng)一個(gè)槽函數(shù)以及信號(hào)傳送參數(shù)給槽函數(shù)等,將結(jié)合相關(guān)的程序代碼做詳細(xì)論述。MainWindow:~MainWindow(){deleteui;}本實(shí)驗(yàn)的析構(gòu)函數(shù),~MainWindow()執(zhí)行以后,釋放相關(guān)資源。實(shí)際上,析構(gòu)函數(shù)還可以用來(lái)執(zhí)行“用戶希望的最后一次使用對(duì)象之后所執(zhí)行的任何操作”。InitSignalSlots()不是槽函數(shù),是為槽函數(shù)服務(wù)的初始化函數(shù),包括7個(gè)connect函數(shù)。1~8的編號(hào)是為了敘述問(wèn)題的方便,實(shí)際的代碼不存在上述標(biāo)號(hào)。將1~3放在一組,三個(gè)信號(hào)關(guān)聯(lián)到同一個(gè)槽函數(shù)。原因是這三個(gè)信號(hào)都和電子鐘的時(shí)間(即“時(shí)”“分”“秒”)數(shù)據(jù)有關(guān)。便于顯示器QLabel數(shù)據(jù)處理。做成三個(gè)槽函數(shù)也不是不可以,但代碼的維護(hù)和可讀性不好。flashtimer信號(hào)觸發(fā)QLabel顯示器數(shù)據(jù)顯示,clocktimer是電子鐘時(shí)間計(jì)數(shù)器的計(jì)時(shí)基準(zhǔn)。ui->LineEditButton設(shè)置數(shù)據(jù)以及要接收信號(hào)的觸發(fā)動(dòng)作。這三個(gè)信號(hào)關(guān)聯(lián)同一個(gè)槽看似一個(gè)很好的解決方案。這里面還有一個(gè)問(wèn)題,觸發(fā)信號(hào)的參數(shù)應(yīng)該有統(tǒng)一的形式。不用說(shuō),前兩個(gè)信號(hào)無(wú)須傳遞參數(shù),不僅如此timeout()是Qt定義好的,就是沒(méi)有參數(shù)。但是,LineEditButton不傳遞參數(shù)就沒(méi)法交代了,因?yàn)樗菙?shù)據(jù)輸入控件,就是為了傳送數(shù)據(jù)的。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—InitSignalSlots()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—SettingHMS()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—SettingHMS()這是一個(gè)槽函數(shù),F(xiàn)un_Button單擊,該函數(shù)立即執(zhí)行。FunctionStatus是一個(gè)模4的循環(huán)計(jì)數(shù)器,控制電子鐘的模態(tài)。QLabel_status用于顯示電子鐘模態(tài),在模態(tài)切換中,啟、停相關(guān)的定時(shí)器。FunctionStatus是類MainWindow的私有變量,在MainWindow類內(nèi),F(xiàn)unctionStatus都可以被使用??v觀整個(gè)程序,其余的成員函數(shù)和槽函數(shù)都是在讀取這個(gè)變量,唯獨(dú)SettingHMS()槽函數(shù)在更改FunctionStatus的值。究其原因,該槽函數(shù)的唯一觸發(fā)信號(hào)Fun_Button功能鍵的clicked()是電子鐘模態(tài)改變的源,每單擊一次Fun_Button,電子鐘的模態(tài)改變一次。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—WriteTextToLabel()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—WriteTextToLabel()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—WriteTextToLabel()電子鐘設(shè)置時(shí)間寫(xiě)入槽函數(shù)。程序中用到了電子鐘模態(tài)變量,用以區(qū)分是對(duì)時(shí)、分、秒哪一個(gè)對(duì)象操作。LineEdit回車(chē)鍵發(fā)出的數(shù)據(jù)信號(hào),進(jìn)入Qlabel_response槽函數(shù)后發(fā)送getText(QString)信號(hào),觸發(fā)WriteTextToLabel(constQString&string)槽函數(shù)。函數(shù)參數(shù)是QString&string。string.toInt()函數(shù)是將QString類型的字符串轉(zhuǎn)換成整型數(shù),進(jìn)行限幅處理。函數(shù)負(fù)責(zé)對(duì)相關(guān)變量的修改和狀態(tài)顯示的更新。Qlabel_response()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()槽函數(shù)Qlabel_response()是電子鐘核心模塊,也是電子鐘最難的部分。槽函數(shù)首先要區(qū)分信號(hào)源從哪里來(lái)?使用QTimer*SignalSource=qobject_cast<QTimer*>sender()對(duì)發(fā)送信號(hào)進(jìn)行類型轉(zhuǎn)換,使用QTimer*指針指向它。判斷是不是QTimer類?若是再判斷是哪個(gè)定時(shí)器發(fā)出來(lái)的?確定了信號(hào)源后再做相應(yīng)的處理。如若不是定時(shí)器發(fā)出來(lái)的信號(hào),那就執(zhí)行QLineEdit*LineEdit=qobject_cast<QLineEdit*>sender(),將指針指向QLineEdit,判斷信號(hào)是由對(duì)象LineEditButton發(fā)出。槽函數(shù)解決了對(duì)相同類型的不同對(duì)象以及不同類型控制的甄別,在實(shí)際的項(xiàng)目使用中具有應(yīng)用價(jià)值。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()對(duì)10mS定時(shí)器的代碼分析如下。每進(jìn)一次槽函數(shù),執(zhí)行一次+1的操作,10mS是電子鐘定時(shí)計(jì)數(shù)器的最小計(jì)數(shù)單位?!皶r(shí)”“分”“秒”和“10mS”各自都有自己的權(quán),+1的操作是整型數(shù)的行為,顯示的數(shù)據(jù)是QSring數(shù)據(jù)類型。于是,在運(yùn)算環(huán)節(jié),運(yùn)算量統(tǒng)統(tǒng)轉(zhuǎn)換為整數(shù),時(shí)間的顯示和變量的保存再轉(zhuǎn)換到QString類型。函數(shù)QString:number(total_minute)和函數(shù)S_minuteSetting.toInt()完成整型數(shù)到字符串以及字符串到整型數(shù)數(shù)據(jù)類型的轉(zhuǎn)換。總之,相關(guān)代碼完成計(jì)時(shí)操作以及數(shù)據(jù)類型轉(zhuǎn)換。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—Qlabel_response()對(duì)500mS定時(shí)器的代碼分析如下。定時(shí)時(shí)間到切換閃爍flashFlag的標(biāo)志位。這是一個(gè)布爾量,取反即可。標(biāo)志位為1時(shí),顯示數(shù)據(jù)。標(biāo)志位為0時(shí),關(guān)顯示(也稱消隱),利用定時(shí)器周期性改變標(biāo)志位,就可見(jiàn)被修改數(shù)據(jù)在閃爍。變量FunctionStatus控制到底是時(shí)、分還是秒被修改,前文已述。用于顯示時(shí)、分、秒的幾個(gè)QLabel類對(duì)象分別是label_hour、label_second和label_minute。setText(…)括號(hào)內(nèi)的值,要么是雙引號(hào)內(nèi)的字符串,要么是QString變量。需要強(qiáng)調(diào)的是QString使用unicoder編碼,支持漢字輸入,譬如setText(“顯示秒”)。對(duì)于QLineEdit代碼分析如下。發(fā)射帶QString類型的參數(shù)的信號(hào),清零LineEditButton對(duì)話框內(nèi)的數(shù)值。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—KeysManagement()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—KeysManagement()Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—KeysManagement()這是一個(gè)槽函數(shù),關(guān)聯(lián)了三個(gè)QPushButton類的三個(gè)按鈕:?jiǎn)?dòng)(停止)、復(fù)位、暫停。槽函數(shù)用于響應(yīng)三個(gè)按鈕。設(shè)計(jì)這三個(gè)信號(hào)和同一個(gè)槽關(guān)聯(lián),原因是它們是相關(guān)聯(lián)操作,由這些操作決定在電子鐘運(yùn)行的模態(tài)下是運(yùn)行、停止、暫停,還是復(fù)位狀態(tài)。頭文件中定義了三個(gè)constint的常量STOP、RUN和PAUSE,一個(gè)int型的變量state用來(lái)表示電子鐘在非參數(shù)設(shè)定模態(tài)下的子狀態(tài)。啟動(dòng)按鈕是啟動(dòng)、停止操作,啟動(dòng)狀態(tài)時(shí)按啟動(dòng)執(zhí)行停止,停止?fàn)顟B(tài)時(shí)按啟動(dòng)執(zhí)行啟動(dòng)。啟動(dòng)態(tài)開(kāi)始計(jì)時(shí),停止態(tài)時(shí)間自動(dòng)清零。暫停鈕在停止態(tài)不起作用,在啟動(dòng)態(tài)使電子鐘暫停,暫停時(shí)保持?jǐn)?shù)據(jù)不變。在暫停態(tài)再按暫停按鍵,電子鐘繼續(xù)計(jì)數(shù)。不管在何種狀態(tài)復(fù)位按鍵使電子鐘進(jìn)入停止態(tài),同時(shí)電子鐘的計(jì)時(shí)時(shí)間清零。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—KeysManagement()文中出現(xiàn)了對(duì)定時(shí)器的啟動(dòng)、停止操作。GTimer是Qt的類,在控制類代碼中定時(shí)器是必不可少的控件。前文講過(guò),使用newQTimer創(chuàng)建定時(shí)器,本實(shí)驗(yàn)是兩個(gè)定時(shí)器。在構(gòu)造函數(shù)中使用諸如clocktimer->setInterval(Interval)設(shè)置定時(shí)器溢出時(shí)間,溢出時(shí)產(chǎn)生的信號(hào)是QTimer::timeout(),常常用connect函數(shù)將溢出信號(hào)關(guān)聯(lián)一個(gè)槽函數(shù),在槽函數(shù)里處理溢出時(shí)間。這是Qt的一大貢獻(xiàn),通過(guò)connect,關(guān)聯(lián)信號(hào)和槽函數(shù)。GTimer還有兩個(gè)重要的函數(shù):start()和stop(),作用是啟動(dòng)和關(guān)閉定時(shí)器。例如clocktimer->start()啟動(dòng)電子鐘定時(shí)器。GTimer類是電子鐘的心臟,是時(shí)鐘節(jié)拍,是不可或缺的控件。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—ResetDisplay()為了敘述項(xiàng)目的完整,展示上述代碼。這是一個(gè)成員函數(shù)。目的是復(fù)位QLabel顯示器,包括變量清零以及setText()函數(shù)的賦值。Qt程序電子鐘設(shè)計(jì)綜合實(shí)驗(yàn)—運(yùn)行結(jié)果展示至此,電子鐘工程的全部程序介紹完畢。電子鐘啟動(dòng)后運(yùn)行的效果如上圖所示。本實(shí)驗(yàn)看起來(lái)并不像一個(gè)成熟的現(xiàn)代GUI應(yīng)用程序,但它使用多種用于更復(fù)雜應(yīng)用程序的基本技術(shù),包括:GTimer類、信號(hào)和槽、QPushButton、QLabel和QLineEdit。對(duì)剛?cè)腴T(mén)的初學(xué)者和以后從事更為復(fù)雜的圖形用戶界面應(yīng)用程序開(kāi)發(fā)的程序員都有一定幫助。提綱Qt編程基礎(chǔ)圖形界面設(shè)計(jì)信號(hào)和槽機(jī)制Qt程序綜合實(shí)驗(yàn)—電子鐘設(shè)計(jì)Qt開(kāi)發(fā)環(huán)境的搭建Qt開(kāi)發(fā)環(huán)境的搭建隨著嵌入式技術(shù)的發(fā)展,Qt的使用越來(lái)越多。對(duì)Qt較為常見(jiàn)的描述是跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架。Qt可用于Windows桌面系統(tǒng),被嵌入在VisualStudio開(kāi)發(fā)環(huán)境里。Qt可用于臺(tái)式機(jī)的桌面Linux,也可以用于嵌入式的Linux。用于Linux開(kāi)發(fā)的環(huán)境常常使用QtCreator,這是一個(gè)輕量級(jí)的QtIDE。針對(duì)桌面Linux和嵌入式Linux,QtCreator使用編譯器和交叉編譯器分別對(duì)它們進(jìn)行編譯。本書(shū)桌面Linux是宿主機(jī),虛擬機(jī)的版本是VMwareWorkstationPro的15.x,虛擬機(jī)使用的Linux是Ubuntu18.04,安裝Qt版本是5.12.8,QtCreator的版本是4.11.2。嵌入式平臺(tái)實(shí)驗(yàn)箱(以后簡(jiǎn)稱平臺(tái))為博創(chuàng)智聯(lián)科技有限公司設(shè)計(jì)制造。平臺(tái)內(nèi)預(yù)裝的Qt版本是5.3.2,Qt被封裝在QtCreator內(nèi),QtCreator的版本是4.11.2??梢钥吹剑拗鳈C(jī)和平臺(tái)使用的QtCreator是同一軟件,這樣在調(diào)試的時(shí)候可以任意切換在宿主機(jī)上操作或是在平臺(tái)上操作。QtCreator的IDE是一個(gè)編程、配置、調(diào)試的集成桌面環(huán)境。整個(gè)開(kāi)發(fā)的流程大多在可視化界面下進(jìn)行,有一些命令行操作,但不是太多。設(shè)置交叉編譯環(huán)境打開(kāi)VMwareWorkstationPro,在開(kāi)啟虛擬機(jī)之前,在設(shè)備一欄,單擊網(wǎng)絡(luò)適配器。出現(xiàn)下圖界面選擇橋接模式(B):直接連接網(wǎng)絡(luò)網(wǎng)絡(luò)。

橋接和NAT模式選擇同時(shí),在復(fù)制物理網(wǎng)絡(luò)連接狀態(tài)前面的方框勾選。手動(dòng)輸入IP手動(dòng)選擇IP如圖11.10所示。開(kāi)啟此虛擬機(jī),虛擬機(jī)的右上角有幾個(gè)圖標(biāo)單擊那個(gè)三角符號(hào)→有線連接→有線設(shè)置→IPV4選手動(dòng),IP地址設(shè)為2,子網(wǎng)掩碼設(shè)為,網(wǎng)關(guān)為空,DNS為空,路由為空。在終端執(zhí)行ifconfig命令,查看虛擬機(jī)IP地址??梢?jiàn),IP地址為2。在電腦的開(kāi)始運(yùn)行部分輸入\\2,進(jìn)入Samba共享文件夾。將光盤(pán)資料SRC目錄下面的fsl-6dl-source.tar.bz2壓縮包復(fù)制到Samba共享目錄如下圖所示。

光盤(pán)拷入虛擬機(jī)的文件然后在ubun

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論