Qt 6.2C++程序設(shè)計與桌面應(yīng)用開發(fā) 思政教學(xué)課件 第11、12章 網(wǎng)絡(luò)編程、進(jìn)程與線程_第1頁
Qt 6.2C++程序設(shè)計與桌面應(yīng)用開發(fā) 思政教學(xué)課件 第11、12章 網(wǎng)絡(luò)編程、進(jìn)程與線程_第2頁
Qt 6.2C++程序設(shè)計與桌面應(yīng)用開發(fā) 思政教學(xué)課件 第11、12章 網(wǎng)絡(luò)編程、進(jìn)程與線程_第3頁
Qt 6.2C++程序設(shè)計與桌面應(yīng)用開發(fā) 思政教學(xué)課件 第11、12章 網(wǎng)絡(luò)編程、進(jìn)程與線程_第4頁
Qt 6.2C++程序設(shè)計與桌面應(yīng)用開發(fā) 思政教學(xué)課件 第11、12章 網(wǎng)絡(luò)編程、進(jìn)程與線程_第5頁
已閱讀5頁,還剩161頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

Qt6.2/C++程序設(shè)計與桌面應(yīng)用開發(fā)21世紀(jì)高等學(xué)校計算機(jī)類課程創(chuàng)新規(guī)劃教材–微課視頻版教材目錄第1章初識Qt框架第2章Qt開發(fā)基礎(chǔ)第3章界面設(shè)計組件第4章主框架窗口第5章對話框設(shè)計第6章事件系統(tǒng)第7章文件與數(shù)據(jù)庫第8章模型/視圖結(jié)構(gòu)第9章圖形繪制第10章多媒體編程第11章網(wǎng)絡(luò)編程第12章進(jìn)程與線程教材目錄第11章網(wǎng)絡(luò)編程11.1Qt網(wǎng)絡(luò)模塊11.2網(wǎng)絡(luò)信息查詢11.3HTTP編程11.4TCP編程11.5UDP編程11.1Qt網(wǎng)絡(luò)模塊Qt提供了多個與網(wǎng)絡(luò)相關(guān)的模塊,使用這些模塊不僅可以開發(fā)出基于各種網(wǎng)絡(luò)協(xié)議的應(yīng)用程序,還可以輕松地將Web內(nèi)容嵌入到Qt應(yīng)用程序中,開發(fā)出具有Internet功能的混合桌面應(yīng)用程序。11.1.1QtNetwork模塊Qt的Network模塊提供了用于編寫TCP/IP客戶端和服務(wù)器端程序的各種類,通過這些類可以實現(xiàn)特定的應(yīng)用層協(xié)議。QtNetwork模塊中的部分類及功能如表11.1所示。11.1.2QtWebSockets模塊WebSocket是一種在單個TCP連接上進(jìn)行全雙工通信的協(xié)議。WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動向客戶端推送數(shù)據(jù)。在WebSocketAPI中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。Qt的WebSockets模塊提供了WebSocket協(xié)議的實現(xiàn),使用該模塊中的類能夠開發(fā)出基于WebSocket協(xié)議的網(wǎng)絡(luò)應(yīng)用程序,包括客戶端和服務(wù)器。QtWebSockets模塊包含4個C++類,它們是:QMaskGenerator、QWebSocket、QWebSocketServerQWebSocketCorsAuthenticatorQMaskGenerator類是一個自定義32位掩碼生成器的抽象庫;QWebSocket類表示實現(xiàn)與WebSocket協(xié)議對話的TCP套接字;QWebSocketServer類表示基于WebSocket協(xié)議的服務(wù)器實現(xiàn);QWebSocketCorsAuthenticator類表示跨源請求(CrossOriginRequests,簡稱CORS)的身份驗證器對象。下面是一個QWebSocket

和QWebSocketServer類的簡單使用示例。11.1.3QtWebChannel模塊Qt的WebChannel模塊用于支持服務(wù)器(QML/C++應(yīng)用程序)和客戶端(HTML/JavaScript或QML應(yīng)用程序)之間的對等通信。該模塊提供了2個C++類,即QWebChannel和QWebChannelAbstractTransport類,以及一個名為qwebchannel.js的JavaScript庫。QWebChannel用于將服務(wù)器應(yīng)用程序的QObjects對象暴露給遠(yuǎn)程的HTML客戶端;QWebChannelAbstractTransport類用于表示一個C++QWebChannel服務(wù)器和一個HTML/JS客戶端之間的通信頻道;qwebchannel.js庫用于將C++和QML應(yīng)用程序與HTML/JavaScript和QML客戶端無縫集成。下面是一個簡單的示例程序。11.1.4QtWebEngine模塊Qt的WebEngine模塊提供了一個web瀏覽器引擎,可以輕松地將萬維網(wǎng)中的內(nèi)容嵌入到?jīng)]有本地web引擎的平臺上的Qt應(yīng)用程序中。該模塊為Qt提供了對廣泛的標(biāo)準(zhǔn)Web技術(shù)的支持,這些技術(shù)可以將用CSS樣式化并用JavaScript腳本化的HTML內(nèi)容嵌入到Qt應(yīng)用程序中。QtWebEngine模塊促進(jìn)了HTML網(wǎng)頁與傳統(tǒng)的基于QWidget的桌面應(yīng)用程序的集成。QtWebEngine提供了Qt應(yīng)用程序中動態(tài)web內(nèi)容區(qū)域的呈現(xiàn)功能,它由3個子模塊組成,分別為QtWebEngineWidgets、QtWebEngine和QtWebEngineCore。這些子模塊的作用及相關(guān)C++類的使用方法,請參見Qt的幫助文檔。下面是一個QtWebEngine模塊的簡單使用示例。11.1.5QtWebView模塊Qt的WebView模塊用于在QML應(yīng)用程序中顯示W(wǎng)eb內(nèi)容,常用于基于Android、IOS操作系統(tǒng)的移動平臺中。由于本教材沒有介紹QML編程,請大家自行運(yùn)行教材給出的示例代碼項目code_11_1_5,該項目來自于Qt實例minibrowser。圖11.4為項目運(yùn)行結(jié)果。11.2網(wǎng)絡(luò)信息查詢與網(wǎng)絡(luò)有關(guān)的信息有很多,其中主要的是網(wǎng)絡(luò)接口信息,也就是網(wǎng)絡(luò)中主機(jī)的相關(guān)信息。在QtNetwork模塊中,QHostInfo

和QNetworkInterface類用于獲取網(wǎng)絡(luò)接口信息。11.2.1使用QHostInfo類QHostInfo類用于查找與主機(jī)名關(guān)聯(lián)的IP地址,或與IP地址關(guān)聯(lián)的主機(jī)名。其部分成員函數(shù)名稱及功能如表11.2所示?!纠?1.1】編寫一個Qt應(yīng)用程序,使用QHostInfo類來查詢主機(jī)信息。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_1的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類為QMainWindow。(2)雙擊mainwindow.ui界面文件打開QtDesigner界面設(shè)計工具,在應(yīng)用程序主窗口中放置一個QPlainTextEdit文本編輯器部件和一個QPushButton按鈕部件,對象名稱分別為plainTextEdit和pushButton。布局效果如圖11.5所示。(3)選擇主窗口中的pushButton按鈕,為其添加一個與clicked()信號關(guān)聯(lián)的槽函數(shù),函數(shù)名稱為on_pushButton_clicked();另外,再添加一個測試用槽函數(shù)lookedUp()。兩個槽函數(shù)的聲明代碼如下所示:(4)在槽函數(shù)on_pushButton_clicked()中添加代碼,獲取本地主機(jī)信息。代碼如下所示。(5)在槽函數(shù)lookedUp()中添加代碼,獲取遠(yuǎn)程主機(jī)信息。代碼如下所示。(6)連接網(wǎng)絡(luò),構(gòu)建并運(yùn)行程序。11.2.2使用QNetworkInterface類QNetworkInterface類提供一個主機(jī)IP地址和網(wǎng)絡(luò)接口列表,可以通過該列表來獲取相關(guān)網(wǎng)絡(luò)信息。其部分成員函數(shù)及功能如表11.3所示。【例11.2】編寫一個Qt應(yīng)用程序,使用QNetworkInterface類來查詢主機(jī)信息。(1)復(fù)制例11.1中的應(yīng)用程序examp11_1,將項目名稱修改為examp11_2。刪除程序中的lookedUp()槽函數(shù),以及on_pushButton_clicked()函數(shù)中的代碼。(2)修改應(yīng)用程序主窗口標(biāo)題以及主窗口中按鈕的標(biāo)題,如圖11.6所示。(3)在on_pushButton_clicked()函數(shù)中添加如下代碼。(4)構(gòu)建并運(yùn)行程序。11.3HTTP編程網(wǎng)絡(luò)應(yīng)用程序的開發(fā)分為低級和高級兩個層次;低層次開發(fā)基于網(wǎng)絡(luò)的傳輸層協(xié)議,例如TCP和UDP協(xié)議,實現(xiàn)的是低層的網(wǎng)絡(luò)進(jìn)程通信(Socket通信)的功能;高層次開發(fā)基于應(yīng)用層的網(wǎng)絡(luò)協(xié)議,例如HTTP、FTP和SMTP等,它們運(yùn)行在TCP/UDP傳輸協(xié)議之上,在低層Socket通信的基礎(chǔ)上進(jìn)一步實現(xiàn)應(yīng)用型的協(xié)議功能。11.3.1相關(guān)Qt類基于HTTP協(xié)議的網(wǎng)絡(luò)應(yīng)用程序的開發(fā),需要使用QtNetwork模塊提供的一些實現(xiàn)高層網(wǎng)絡(luò)操作的類;如QNetworkRequest、QNetworkAccessManager和QNetworkRely等。1、QNetworkRequest類在Qt中,使用QNetworkRequest類來表示一個網(wǎng)絡(luò)訪問請求,同時保存該網(wǎng)絡(luò)請求的相關(guān)信息。作為與請求有關(guān)的信息的統(tǒng)一容器,在創(chuàng)建請求對象時指定的URL決定了請求使用的協(xié)議,目前支持HTTP、HTTPS、FTP和本地文件URLs的下載或上傳。QNetworkRequest類的部分成員函數(shù)及功能,如表11.4所示。2、QNetworkAccessManager類該類用于協(xié)調(diào)網(wǎng)絡(luò)操作。在QNetworkRequest類發(fā)起一個網(wǎng)絡(luò)訪問請求后,QNetworkAccessManager類負(fù)責(zé)發(fā)送該請求、創(chuàng)建網(wǎng)絡(luò)響應(yīng),并發(fā)送信號來報告網(wǎng)絡(luò)通信的進(jìn)度。QNetworkAccessManager類的部分成員函數(shù)及功能如表11.5所示。3、QNetworkReply類Qt用QNetworkReply類來表示網(wǎng)絡(luò)請求的響應(yīng),它由QNetworkAccessManager類在完成請求調(diào)度后創(chuàng)建QNetworkReply類提供了像finished()、readyRead()和downloadProgress()等信號,使用這些信號,可以實現(xiàn)對網(wǎng)絡(luò)響應(yīng)執(zhí)行情況的監(jiān)測,并執(zhí)行相應(yīng)操作。QNetworkReply類的部分成員函數(shù)如表11.6所示。11.3.2HTTP訪問HTTP(HyperTextTransferProtocol,超文本傳輸協(xié)議)是一個客戶端和服務(wù)器端請求和應(yīng)答的標(biāo)準(zhǔn)??梢允褂肣NetworkRequest、QNetworkAccessManager

和QNetworkReply類

來實現(xiàn)Qt應(yīng)用程序的HTTP訪問功能。【例11.3】編寫一個Qt應(yīng)用程序,實現(xiàn)簡單Web瀏覽器功能。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_3的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類為QMainWindow。(2)雙擊mainwindow.ui界面文件打開QtDesigner界面設(shè)計工具,刪除應(yīng)用程序主窗口中的菜單欄與狀態(tài)欄。在應(yīng)用程序主窗口中放置一個QLabel標(biāo)簽、一個QLineEdit單行文本輸入框、一個名為“訪問”的QPushButton按鈕和一個QPlainTextEdit文本編輯器部件,對象名稱分別為label、lineEdit、pushButton和plainTextEdit。布局效果如圖11.7所示。(3)為主窗口中的“訪問”按鈕添加clicked()信號槽函數(shù),函數(shù)名為on_pushButton_clicked();另外,再添加一個名為replyFinished()的槽函數(shù)。這兩個槽函數(shù)的聲明代碼如下:privateslots:voidreplyFinished(QNetworkReply*reply);voidon_pushButton_clicked();(4)為MainWindow類添加2個私有成員變量,如下所示。private:…QNetworkAccessManager*manager;QNetworkRequestrequest;(5)在MainWindow類的構(gòu)造函數(shù)中添加如下代碼。manager=newQNetworkAccessManager(this);connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)));這里,finished(QNetworkReply*)是QNetworkAccessManager的信號,該信號在響應(yīng)完成后自動發(fā)送。(6)編寫on_pushButton_clicked()槽函數(shù)代碼,如下所示。(7)編寫replyFinished()槽函數(shù)代碼,如下所示。(8)構(gòu)建并運(yùn)行程序。11.3.3HTTP下載基于HTTP協(xié)議的網(wǎng)絡(luò)文件下載與上述HTTP訪問相似,只要將請求后獲取到的響應(yīng)內(nèi)容存儲在指定的文件中即可?!纠?1.4】編寫一個Qt應(yīng)用程序,實現(xiàn)簡單的Web文件下載功能。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_4的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類為QMainWindow。(2)雙擊mainwindow.ui界面文件打開QtDesigner界面設(shè)計工具,刪除主窗口中的菜單欄與狀態(tài)欄。在應(yīng)用程序主窗口中放置3個QLabel標(biāo)簽、2個QLineEdit單行文本編輯框、2個QPushButton按鈕、1個QCheckBox按鈕和1個QPrecess進(jìn)度條部件。布局效果如圖11.9所示。(3)在MainWindow類中添加成員變量及槽函數(shù),如下所示。(4)在MainWindow類的實現(xiàn)文件中添加代碼,實現(xiàn)程序功能。如下所示。(5)構(gòu)建并運(yùn)行程序。11.4TCP編程TCP(TransmissionControlProtocol,傳輸控制協(xié)議)是一個用于數(shù)據(jù)傳輸?shù)牡蛯泳W(wǎng)絡(luò)協(xié)議,多個互聯(lián)網(wǎng)協(xié)議(如HTTP、FTP等)都是基于該協(xié)議的。TCP是一個面向數(shù)據(jù)流和連接的可靠傳輸協(xié)議,特別適合用于連續(xù)數(shù)據(jù)的傳輸。TCP編程一般分為客戶端和服務(wù)器端,即使用C/S(Client/Server)模型。11.4.1相關(guān)Qt類在QtNetwork模塊類中,有2個與TCP直接相關(guān)的類QTcpSocket

和QTcpServer。QTcpSocket

用于建立TCP連接后使用套接字(Socket)進(jìn)行通信;QTcpServer用于服務(wù)器端建立網(wǎng)絡(luò)監(jiān)聽,創(chuàng)建網(wǎng)絡(luò)Socket連接。1、QTcpSocket類QTcpSocket類為TCP提供一個接口,用于建立TCP連接并傳輸數(shù)據(jù)流。其繼承關(guān)系如圖11.10所示。2、QTcpServer類QTcpServer類提供基于TCP的服務(wù)器。該類繼承自QObject,并被QScptServer類繼承。其部分成員函數(shù)及功能如表11.8所示。11.4.2服務(wù)器端編程服務(wù)器端程序首先需要用QTcpServer::listen()開始服務(wù)器端監(jiān)聽,可以指定監(jiān)聽的IP地址和端口,一般一個服務(wù)程序只監(jiān)聽某個端口的網(wǎng)絡(luò)連接。當(dāng)有新的客戶端接入時,QTcpServer內(nèi)部的incomingConnection()函數(shù)會創(chuàng)建一個與客戶端連接的QTcpSocket對象,然后發(fā)射信號newConnection()。在newConnection()信號的槽函數(shù)中,可以用nextPendingConnection()接受客戶端的連接,然后使用QTcpSocket與客戶端進(jìn)行通信?!纠?1.5】編寫一個Qt應(yīng)用程序,演示基于TCP協(xié)議的服務(wù)器端程序設(shè)計方法。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_5的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類為QWidget。(2)雙擊widget.ui界面文件打開QtDesigner界面設(shè)計工具,在應(yīng)用程序主窗口中放置一個QListWidget列表框、一個QLabel標(biāo)簽、一個QLineEdit單行文本編輯框和一個QPushButton按鈕部件,其對象名稱分別為listWidget、label、lineEdit和pushButton。布局效果如圖11.11所示。(3)在項目中添加一個名為Server的C++類,其頭文件server.h和實現(xiàn)文件server.cpp如下所示。(4)在項目中添加一個名為Client的C++類,其頭文件client.h和實現(xiàn)文件client.cpp如下所示。(5)在Widget類中添加私有成員變量server,以及私有槽函數(shù)on_pushButton_clicked()和updateServer()。其聲明代碼如下所示。(6)在Widget類的構(gòu)造函數(shù)中添加代碼,并實現(xiàn)上述(5)中的2個槽函數(shù)功能。如下所示。(7)構(gòu)建并運(yùn)行程序,單擊“啟動服務(wù)器”按鈕啟動服務(wù)器。(8)為了對服務(wù)器端程序進(jìn)行測試,需要運(yùn)行客戶端應(yīng)用程序。運(yùn)行教材源碼中的examp11_6應(yīng)用程序(例11.6中的客戶端應(yīng)用程序),如圖11.12所示。11.4.3客戶端編程客戶端應(yīng)用程序的編程非常簡單,只需要使用一個QTcpSocket對象,即可和服務(wù)器端程序進(jìn)行通信。【例11.6】編寫一個Qt應(yīng)用程序,演示基于TCP協(xié)議的客戶端程序設(shè)計方法。程序運(yùn)行結(jié)果如圖11.13和圖11.14所示。這里啟動了2個客戶端應(yīng)用程序。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_6的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類為QWidget。(2)雙擊widget.ui界面文件打開QtDesigner界面設(shè)計工具,在應(yīng)用程序主窗口中放置部件并使用布局管理器進(jìn)行布局。主窗口中部件類型及對象名稱如如圖11.15所示。(3)在Widget類中添加私有成員變量和槽函數(shù),其聲明代碼如下所示。(4)在Widget類的構(gòu)造函數(shù)中添加代碼,并實現(xiàn)上述(3)中的5個槽函數(shù)功能。如下所示。(5)構(gòu)建并運(yùn)行程序。11.5UDP編程UDP(UserDatagramProtocol,用戶數(shù)據(jù)報協(xié)議)是輕量的、不可靠的、面向數(shù)據(jù)報(datagram)、無連接的協(xié)議,它可以用于對可靠性要求不高的場合。與TCP通信不同,兩個程序之間進(jìn)行UDP通信無需預(yù)先建立持久的socket連接,UDP每次發(fā)送數(shù)據(jù)報都需要指定目標(biāo)地址和端口。Qt中的UDP通信通過QUdpSocket類來實現(xiàn)。11.5.1QUdpSocket類與QTcpSocket一樣,QUdpSocket也是從QAbstractSocket類派生出來的,其繼承關(guān)系如圖11.10所示。除了繼承下來的函數(shù)之外,QUdpSocket還定義了一些特有的成員函數(shù),如表11.9所示。11.5.2UDP單播UDP消息傳送有單播、廣播、組播三種模式,其示意圖如圖11.16所示。【例11.7】編寫一個Qt應(yīng)用程序,演示基于UDP協(xié)議的網(wǎng)絡(luò)通信功能的實現(xiàn)方法。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_7的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類QWidget。(2)雙擊widget.ui界面文件打開QtDesigner界面設(shè)計工具,在應(yīng)用程序主窗口中放置部件并使用布局管理器進(jìn)行布局。主窗口中部件對象類型及名稱如圖11.19所示。(3)打開examp11_7.pro項目文件,添加QtNetwork模塊支持。如下所示。QT+=network(4)在Widget類中添加私有成員變量、成員函數(shù)和槽函數(shù),其聲明代碼如下所示。(5)在Widget類的構(gòu)造函數(shù)中添加代碼,并實現(xiàn)上述(4)中的5個函數(shù)功能。如下所示。(5)構(gòu)建并運(yùn)行程序。11.5.3UDP組播UDP組播是主機(jī)之間“一對一組”的通信模式。組播報文的目的地址使用D類IP地址,D類地址不能出現(xiàn)在IP報文的源IP地址字段。用同一個IP多播地址接收多播數(shù)據(jù)報的所有主機(jī)構(gòu)成了一個組,稱為多播組或組播組。所有的信息接收者都加入到一個組內(nèi),并且一旦加入之后,流向組地址的數(shù)據(jù)報立即開始向接收者傳輸,組中的所有成員都能接收到數(shù)據(jù)報。組中的成員是動態(tài)的,主機(jī)可以在任何時候加入和離開組播組?!纠?1.8】編寫一個Qt應(yīng)用程序,演示基于UDP協(xié)議的網(wǎng)絡(luò)組播通信功能的實現(xiàn)方法。(1)啟動QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個名為examp11_8的Qt應(yīng)用程序,設(shè)置應(yīng)用程序主窗口基類QWidget。(2)雙擊widget.ui界面文件打開QtDesigner界面設(shè)計工具,在應(yīng)用程序主窗口中放置部件并使用布局管理器進(jìn)行布局。主窗口中部件對象類型及名稱如圖11.22所示。(3)打開examp11_8.pro項目文件,添加QtNetwork模塊支持。如下所示。QT+=network(4)在Widget類中添加私有成員變量、成員函數(shù)和槽函數(shù),其聲明代碼如下所示。(5)在Widget類的構(gòu)造函數(shù)中添加代碼,并實現(xiàn)上述(4)中的函數(shù)功能。如下所示。(5)構(gòu)建并運(yùn)行程序。課后作業(yè)思政本章結(jié)束Qt6.2/C++程序設(shè)計與桌面應(yīng)用開發(fā)21世紀(jì)高等學(xué)校計算機(jī)類課程創(chuàng)新規(guī)劃教材–微課視頻版教材目錄第1章初識Qt框架第2章Qt開發(fā)基礎(chǔ)第3章界面設(shè)計組件第4章主框架窗口第5章對話框設(shè)計第6章事件系統(tǒng)第7章文件與數(shù)據(jù)庫第8章模型/視圖結(jié)構(gòu)第9章圖形繪制第10章多媒體編程第11章網(wǎng)絡(luò)編程第12章進(jìn)程與線程教材目錄第12章進(jìn)程與線程12.1相關(guān)Qt類12.2進(jìn)程12.3線程12.4線程控制12.1相關(guān)Qt類Qt對進(jìn)程和線程的支持是通過一系列的類協(xié)同實現(xiàn)的,其中主要的有QProcess類和QThread類。QProcess類用來啟動一個進(jìn)程并與其進(jìn)行通信;QThread類提供不依賴于平臺的管理線程常用方法。12.1.1QProcess類QProcess類屬于Qt的core模塊中,它是QIODevice類的直接子類,屬于Qt的順序訪問I/O設(shè)備;同時,QProcess類也是QObject的子類,因而具有Qt的信號/槽功能。其繼承關(guān)系如圖12.1所示。QProcess類提供了大量的函數(shù)實現(xiàn)進(jìn)程的啟動、控制、查詢、設(shè)置及通信等功能。其部分成員函數(shù)及功能如表12.1所示。下面是一段使用QProcess啟動cmd.exe控制臺程序并執(zhí)行dir命令的示例代碼。12.1.2QThread類QThread類直接繼承自QObject類,每個QThread對象代表了一個在應(yīng)用程序中可以獨立控制的線程,這個線程與進(jìn)程中的其他線程分享數(shù)據(jù)。表12.2給出了QThread類的部分非繼承成員函數(shù)及功能。下面是一段使用QThread類實現(xiàn)多線程的示例代碼。12.2進(jìn)程進(jìn)程(Process)是計算機(jī)中的程序關(guān)于數(shù)據(jù)集合上的一次運(yùn)行活動,是正在運(yùn)行的程序的實例。從理論角度來看,進(jìn)程是對正在運(yùn)行的程序過程的抽象;從實現(xiàn)角度來看,進(jìn)程就是一種數(shù)據(jù)結(jié)構(gòu)。進(jìn)程清晰地刻畫了動態(tài)系統(tǒng)的內(nèi)在規(guī)律,并有效地管理和調(diào)度進(jìn)入計算機(jī)系統(tǒng)主存儲器運(yùn)行的程序。12.2.1進(jìn)程的啟動進(jìn)程是一個“執(zhí)行中的程序”,所以,啟動進(jìn)程就是開始運(yùn)行一個程序??梢允褂肣Process類的start()、startDetached()和execute()函數(shù)來啟動一個進(jìn)程。下面是一個在Qt應(yīng)用程序中打開/關(guān)閉Windows系統(tǒng)計算器的簡單實例?!纠?2.1】編寫一個Qt應(yīng)用程序,在程序中運(yùn)行Windows計算器。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個基于QWidget類的Qt應(yīng)用程序。項目名稱為examp12_1。(2)雙擊項目視圖中的widget.ui界面文件,打開QtDesigner設(shè)計工具,對程序主窗口界面進(jìn)行設(shè)計。在主窗口中添加1個QPlainTextEdit類型的多文本編輯器,和2個QPushButton類型的按鈕。3個對象的名稱分別為plainTextEdit、startButton和closeButton。(3)為2個QPushButton按鈕添加clicked()信號的槽函數(shù),函數(shù)名稱分別為on_startButton_clicked()和on_closeButton_clicked()。(4)打開widget.h頭文件,為Widget類添加一個名為isActive()的私有成員函數(shù),用于判斷計算器是否已經(jīng)啟動;添加一個名為showError()的槽函數(shù),用于顯示啟動進(jìn)程時可能會出現(xiàn)的錯誤信息;添加3個名稱為myProcess、program和arguments的私有成員變量,分別表示進(jìn)程、外部程序以及命令行參數(shù)。代碼如下所示。(5)打開widget.cpp文件,編寫構(gòu)造函數(shù)、自定義函數(shù),以及槽函數(shù)代碼,以實現(xiàn)程序功能。如下所示。(6)構(gòu)建并運(yùn)行程序。12.2.2進(jìn)程間通信Qt提供了多種方法在Qt應(yīng)用程序中實現(xiàn)進(jìn)程間通信(IPC,Inter-ProcessCommunication)。主要有:1、TCP/IP方法2、LocalServer/Socket方法3、SharedMemory方法4、D-Bus協(xié)議方法5、QProcess方法6、SessionManagement方法1、TCP/IP方法跨平臺的QtNetwork模塊提供了眾多的類來實現(xiàn)網(wǎng)絡(luò)編程。它不僅提供了使用特定應(yīng)用程序級協(xié)議進(jìn)行通信的高級類(如QNetworkAccessManager),也提供了用于實現(xiàn)相關(guān)協(xié)議的低級類(如QTcpSocket、QTcpServer、QSslSocket)。本教材的第11章網(wǎng)絡(luò)編程中詳細(xì)介紹了此種方法。2、LocalServer/Socket方法跨平臺的QtNetwork模塊提供了使本地網(wǎng)絡(luò)編程可移植且容易的類。它提供了QLocalServer

和QLocalSocket類,允許在本地設(shè)置中進(jìn)行類似網(wǎng)絡(luò)的通信?!纠?2.2】編寫一個Qt應(yīng)用程序,通過LocalServer/Socket方法來實現(xiàn)進(jìn)程之間的通信。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建2個基于QDialog類的Qt應(yīng)用程序。項目名稱分別為examp12_1_server和examp12_1_client。前者表示服務(wù)器端程序,后者表示客戶端程序。(2)編寫服務(wù)器端程序代碼。下面只給出部分關(guān)鍵代碼,其他請參見教材源碼。(3)編寫客戶端程序代碼。下面只給出部分關(guān)鍵代碼,其他請參見教材源碼。(4)構(gòu)建并運(yùn)行程序。3、SharedMemory方法QtNetwork模塊中的跨平臺的QSharedMemory

共享內(nèi)存類,提供對操作系統(tǒng)的共享內(nèi)存的實現(xiàn),它允許多個線程和進(jìn)程安全訪問共享內(nèi)存段。QSystemSemaphore也可以用來控制訪問由系統(tǒng)共享的資源以及進(jìn)程之間的通信?!纠?2.3】編寫一個Qt應(yīng)用程序,使用共享內(nèi)存來實現(xiàn)進(jìn)程之間的通信。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個基于QWidget類的Qt應(yīng)用程序。項目名稱為examp12_3。(2)雙擊項目視圖中的widget.ui界面文件,打開QtDesigner設(shè)計工具,對程序主窗口界面進(jìn)行設(shè)計。在主窗口中添加1個QLabel標(biāo)簽控件,和2個QPushButton類型的按鈕。3個對象的名稱分別為label、loadFromFileButton和loadFromSharedMemoryButton。(3)為2個QPushButton按鈕添加clicked()信號的槽函數(shù),函數(shù)名稱分別為on_loadFromFileButton_clicked()和on_loadFromSharedMemoryButton_clicked()。(4)打開widget.h頭文件,為Widget類添加一個名為detach()的私有成員函數(shù),用于將進(jìn)程與共享內(nèi)存段分離;添加一個名為sharedMemory的QSharedMemory私有成員對象,用于表示共享內(nèi)存段。代碼如下。private:voiddetach();private:…QSharedMemorysharedMemory;(5)打開widget.cpp文件,編寫構(gòu)造函數(shù)、自定義函數(shù),以及槽函數(shù)代碼,以實現(xiàn)程序功能。如下所示。(4)構(gòu)建并運(yùn)行程序。4、D-Bus協(xié)議方法Qt的D-Bus模塊是一種可用于使用D-Bus協(xié)議實現(xiàn)IPC的唯一Unix庫。它將Qt的信號和槽機(jī)制延伸到IPC級別,允許由一個進(jìn)程發(fā)出的信號被連接到另一個進(jìn)程的槽。該方法的實現(xiàn),請參見Qt的示例程序D-BusChatExample和D-BusRemoteControlledCarExample5、QProcess方法跨平臺類QProcess能夠用于啟動外部程序作為子進(jìn)程,并與它們進(jìn)行通訊。它提供了用于監(jiān)測和控制該子進(jìn)程狀態(tài)的API。另外,QProcess為從QIODevice繼承的子進(jìn)程提供了輸入/輸出通道。該方法的實現(xiàn),請參見上面12.1.1小節(jié)中的code_12_1_1示例項目。6、SessionManagement方法在Linux/X11平臺上,Qt提供了會話管理的支持。會話容許事件傳播到進(jìn)程,例如,當(dāng)檢測到關(guān)機(jī)時,進(jìn)程和應(yīng)用程序能夠執(zhí)行任何必須的操作,如保存打開的文檔等。12.3線程Qt對線程的支持是通過三個方面來實現(xiàn)的:一是提供了一組與平臺無關(guān)的線程類,二是提供了一個線程安全的事件發(fā)送方式,三是提供了跨線程的信號與槽的關(guān)聯(lián)。Qt對多線程操作的全面支持,使得開發(fā)可移植的Qt多線程應(yīng)用程序變得非常容易,同時還可以充分發(fā)揮多處理器中各個內(nèi)核的效用。12.3.1線程的運(yùn)行在Qt的多線程應(yīng)用程序中,通常使用QThread類提供的方法來對線程進(jìn)行管理。一個QThread類的對象管理一個線程,默認(rèn)情況下,線程是在QThread::run()函數(shù)中開始運(yùn)行的,run()函數(shù)通過調(diào)用exec()啟動并運(yùn)行Qt的事件循環(huán)。1、線程的創(chuàng)建在多線程編程中,將應(yīng)用程序的線程稱為主線程,額外創(chuàng)建的線程稱為工作線程。工作線程可以通過兩種方法來創(chuàng)建:一種方法是自定義QThread類的子類,并重載run()函數(shù);另一種方法是先創(chuàng)建工作對象,然后使用QObject::moveToThread()函數(shù)將工作對象嵌入到線程中。(1)使用QThread子類對象通過子類化QThread來創(chuàng)建工作線程,是Qt多線程編程中的常用方法。下面是一段示例代碼。(2)使用QObject::moveToThread()函數(shù)通過這種方法創(chuàng)建工作線程,首先需要創(chuàng)建一個工作者對象,將線程任務(wù)集中到這個對象中,然后使用QObject::moveToThread()函數(shù)完成工作線程的創(chuàng)建。示例如下。2、線程的啟動工作線程創(chuàng)建完成后,可以在外部創(chuàng)建該線程的實例,然后調(diào)用start()函數(shù)來開始執(zhí)行該線程,start()默認(rèn)會調(diào)用run()函數(shù)。下面來看一個簡單的實例?!纠?2.4】編寫一個Qt應(yīng)用程序,統(tǒng)計n個自然數(shù)中質(zhì)數(shù)的個數(shù)。要求統(tǒng)計計算在單獨的線程中完成,主線程接收用戶輸入并顯示統(tǒng)計結(jié)果。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個基于QWidget類的Qt應(yīng)用程序。項目名稱為examp12_4。(2)雙擊項目視圖中的widget.ui界面文件,打開QtDesigner設(shè)計工具,對程序主窗口界面進(jìn)行設(shè)計。在主窗口中添加2個QLabel標(biāo)簽、1個QPushButton按鈕、1個QLineEdit單行文本輸入框和1個QPlainTextEdit多行文本編輯器。其中,單行文本輸入框、按鈕和多行文本編輯器控件對象的名稱分別為lineEdit、pushButton和plainTextEdit。(3)右擊主窗口中的lineEdit控件,選擇快捷菜單中的“Gotoslots…”菜單命令,為單行文本控件添加editingFinished信號關(guān)聯(lián)槽函數(shù)on_lineEdit_editingFinished();使用同樣的方法,為“計算”按鈕控件添加clicked信號關(guān)聯(lián)槽函數(shù)on_pushButton_clicked()。(4)在項目中添加一個QThread類的派生類MyThread,并重載run()虛函數(shù)。為類MyThread添加私有成員變量endNum,用于存儲需要統(tǒng)計的自然數(shù)的個數(shù);為endNum成員變量添加公有的設(shè)置函數(shù)setEndNum()。代碼如下所示。接著,編寫mythread.cpp文件中的代碼,完成成員變量的初始化、成員變量的設(shè)置和線程任務(wù)等工作。代碼如下所示。(5)打開widget.h文件,在類Widget中添加一個MyThread類型的對象myThread,并為上述第(3)步中創(chuàng)建的2個槽函數(shù)添加代碼,實現(xiàn)相應(yīng)的功能。如下所示。(6)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,輸入不同的n值,并單擊“計算”按鈕進(jìn)行測試,結(jié)果如圖12.10所示。該程序子線程中的計算結(jié)果是直接在控制臺輸出的,如果要將計算結(jié)果傳遞到主線程中,就需要了解線程間通信的基本方法。12.3.2線程間通信線程間的通信一般通過兩種方法來實現(xiàn),即成員變量方法和自定義信號方法。成員變量方法就是通過線程對象的成員變量來返回線程數(shù)據(jù);自定義信號方法通過在線程類中定義信號,利用信號參數(shù)來傳遞線程數(shù)據(jù)。1、成員變量方法由于線程任務(wù)是在run()函數(shù)中完成的,而run()函數(shù)又屬于線程類的成員函數(shù),所以可以通過線程類的成員變量來存儲run()函數(shù)中的相關(guān)數(shù)據(jù)?!纠?2.5】編寫一個Qt應(yīng)用程序,使用成員變量來實現(xiàn)線程之間的通信。(1)復(fù)制例12.4中的項目examp12_4,并將名稱修改為examp12_5。(2)打開項目中的mythread.h文件,在MyThread線程類中添加一個類型為long的私有成員變量result,并為其添加公有的getResult()函數(shù)。getResult()函數(shù)實現(xiàn)代碼如下:longMyThread::getResult(){returnresult;}(3)修改run()函數(shù)中的代碼,將計算結(jié)果賦值給成員變量result。如下所示。voidMyThread::run(){…//qDebug()<<"在1~"<<endNum<<"的n個自然數(shù)中,質(zhì)數(shù)的個數(shù)為:"<<n;result=n;}(4)打開項目中的widget.h文件,在類Widget中添加槽函數(shù)returnResult()。其實現(xiàn)代碼如下所示:voidWidget::returnResult(){longr=myThread.getResult();QStringstr;str.setNum(r);ui->plainTextEdit->insertPlainText(str);}(5)在Widget類的構(gòu)造函數(shù)中編寫代碼,將槽函數(shù)returnResult()和QThread::finished信號關(guān)聯(lián)。代碼如下:connect(&myThread,&QThread::finished,this,&Widget::returnResult);子線程運(yùn)行結(jié)束后,即刻調(diào)用主窗口中的returnResult()槽函數(shù),將計算結(jié)果顯示在多行文本編輯器光標(biāo)所在的位置。(6)構(gòu)建并運(yùn)行程序。程序運(yùn)行后,在文本輸入框中輸入n并回車,然后單擊“計算”按鈕開始統(tǒng)計計算。程序計算時,可以在主窗口中進(jìn)行其他操作,主線程沒有被阻塞。如圖12.12所示。2、自定義信號方法在Qt的信號與槽通訊機(jī)制中,對象在發(fā)射信號的時候是可以附帶傳送一些參數(shù)的。所以,可以通過在線程類中定義信號,利用信號參數(shù)來傳遞線程數(shù)據(jù)。【例12.6】編寫一個Qt應(yīng)用程序,使用自定義信號方法實現(xiàn)線程之間的通信。(1)復(fù)制例12.4中的項目examp12_4,并將名稱修改為examp12_6。(2)打開項目中的mythread.h頭文件,為線程類MyThread添加一個信號函數(shù)。代碼如下:signals:voidreturnResult(longresult);(3)打開項目中的mythread.cpp文件,修改線程類MyThread的run()函數(shù)中的代碼,如下所示。voidMyThread::run(){…//qDebug()<<"在1~"<<endNum<<"的n個自然數(shù)中,質(zhì)數(shù)的個數(shù)為:"<<n;emitreturnResult(n);}(4)打開項目文件widget.h,在類Widget中添加槽函數(shù)getResult(),并編寫其實現(xiàn)代碼。如下所示。voidWidget::getResult(longresult){longr=result;QStringstr;str.setNum(r);ui->plainTextEdit->insertPlainText(str);}(5)在Widget類的構(gòu)造函數(shù)中編寫代碼,將槽函數(shù)getResult()和MyThread::returnResult信號關(guān)聯(lián)。代碼如下:connect(&myThread,&MyThread::returnResult,this,&Widget::getResult);(6)構(gòu)建并運(yùn)行程序。12.4線程控制線程之間存在著互相制約的關(guān)系,具體可以分為互斥和同步這兩種關(guān)系。在Qt中,線程的互斥與同步控制,可以使用QMutex、QMutexLocker、QReadWriteLock、QReadLocker、QWriteLocker、Qsemaphore和QWaitCondition

等類來實現(xiàn)。12.4.1基于互斥量互斥量可以通過Qmutex

或QMutexLocker類實現(xiàn)。Qmutex和QMutexLocker

又稱為互斥鎖,用于保護(hù)共享資源(如對象、數(shù)據(jù)結(jié)構(gòu)和代碼段等),它們能夠保證多線程程序中在同一時刻只有一個線程訪問共享資源。【例12.7】編寫一個Qt應(yīng)用程序,示例使用互斥量保護(hù)共享資源。(1)打開QtCreator集成開發(fā)環(huán)境,創(chuàng)建一個基于QWidget類的Qt應(yīng)用程序,項目名稱為examp12_7。(2)在項目中添加一個名為TestData的C++類,并在該類中定義2個靜態(tài)成員sharedNumber和sharedNumMutex,前者表示共享整型數(shù)據(jù);后者表示互斥鎖。代碼如下。(3)在項目中添加2個QThread的子線程類,類名分別為WorkThread1和WorkThread2。在這兩個類中實現(xiàn)QThread::run()虛函數(shù),代碼如下。(4)在項目主窗口中添加一個QPushButton類型的按鈕,并在其clicked()信號對應(yīng)的槽函數(shù)中編寫代碼,如下所示。voidWidget::on_pushButton_clicked(){m_workThread2.start();//先啟動線程2m_workThread1.start();}(5)構(gòu)建并運(yùn)行程序。為了對比運(yùn)行結(jié)果,程序運(yùn)行測試分兩次來進(jìn)行。先注釋掉上述(3)步代碼中的語句1、語句5和語句9,測試不使用互斥鎖的情形,結(jié)果如圖12.14所示。從輸出結(jié)果可以看出,在線程1中輸出的結(jié)果為17(0+2+20-5),這個結(jié)果是執(zhí)行了語句6、語句2和語句3后得到的。也就是說,在線程2還沒有對共享數(shù)據(jù)TestData::sharedNumber修改(語句7還沒有執(zhí)行)完成的時候,線程1便對該共享數(shù)據(jù)進(jìn)行了修改。很顯然這個計算結(jié)果是不符合程序設(shè)計者的初衷的。接著,測試使用互斥鎖后程序的運(yùn)行情況。取消語句1、語句5和語句9的注釋,重新構(gòu)建并運(yùn)行程序,結(jié)果如圖12.15所示。從結(jié)果可以看到,使用互斥鎖以后,線程1就不能在線程2訪問共享數(shù)據(jù)的時候?qū)ζ溥M(jìn)行操作了。這樣有效保護(hù)了程序

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論