www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 充電吧
[導(dǎo)讀]該文章原創(chuàng)于Qter開源社區(qū)(www.qter.org),作者yafeilinux,轉(zhuǎn)載請(qǐng)注明出處! 導(dǎo)語 在前面的幾節(jié)內(nèi)容中講解了Qt網(wǎng)絡(luò)編程的一些基本內(nèi)容,這一節(jié)來看一下在Qt中進(jìn)程和

該文章原創(chuàng)于Qter開源社區(qū)(www.qter.org),作者yafeilinux,轉(zhuǎn)載請(qǐng)注明出處!

導(dǎo)語
在前面的幾節(jié)內(nèi)容中講解了Qt網(wǎng)絡(luò)編程的一些基本內(nèi)容,這一節(jié)來看一下在Qt中進(jìn)程和線程的基本應(yīng)用。
環(huán)境:Windows Xp + Qt 4.8.5+Qt Creator2.8.0


目錄
一、進(jìn)程 二、線程


正文

一、進(jìn)程 ? ??在設(shè)計(jì)一個(gè)應(yīng)用程序時(shí),有時(shí)不希望將一個(gè)不太相關(guān)的功能集成到程序中,或者是因?yàn)樵摴δ芘c當(dāng)前設(shè)計(jì)的應(yīng)用程序聯(lián)系不大,或者是因?yàn)樵摴δ芤呀?jīng)可以使用現(xiàn)成的程序很好的實(shí)現(xiàn)了,這時(shí)就可以在當(dāng)前的應(yīng)用程序中調(diào)用外部的程序來實(shí)現(xiàn)該功能,這就會(huì)使用到進(jìn)程。Qt應(yīng)用程序可以很容易的啟動(dòng)一個(gè)外部應(yīng)用程序,而且Qt也提供了在多種進(jìn)程間通信的方法。 ? ? Qt的QProcess類用來啟動(dòng)一個(gè)外部程序并與其進(jìn)行通信。下面我們來看一下怎么在Qt代碼中啟動(dòng)一個(gè)進(jìn)程。
1.首先創(chuàng)建QtGui應(yīng)用。 工程名稱為“myProcess”,其他選項(xiàng)保持默認(rèn)即可。
2.然后設(shè)計(jì)界面。 在設(shè)計(jì)模式往界面上拖入一個(gè)Push Button部件,修改其顯示文本為“啟動(dòng)一個(gè)進(jìn)程”。
3.修改槽。 在按鈕上點(diǎn)擊鼠標(biāo)右鍵,轉(zhuǎn)到其clicked()信號(hào)對(duì)應(yīng)的槽,更改如下: void?MainWindow::on_pushButton_clicked() { ? ???myProcess.start("notepad.exe"); }
4.進(jìn)入mainwindow.h文件添加代碼。 先添加頭文件包含:#include ,然后添加私有對(duì)象定義:QProcess myProcess;
5.運(yùn)行程序。 當(dāng)單擊界面上的按鈕時(shí)就會(huì)彈出一個(gè)記事本程序。
這里我們使用QProcess對(duì)象運(yùn)行了Windows系統(tǒng)下的記事本程序(即notepad.exe程序),因?yàn)樵摮绦蛟谙到y(tǒng)目錄中,所以這里不需要指定其路徑。大家也可以運(yùn)行其他任何的程序,只需要指定其具體路徑即可。我們看到,可以使用start()來啟動(dòng)一個(gè)程序,有時(shí)啟動(dòng)一個(gè)程序時(shí)需要指定啟動(dòng)參數(shù),這種情況在命令行啟動(dòng)程序時(shí)是很常見的,下面來看一個(gè)例子,還在前面的例子的基礎(chǔ)上進(jìn)行更改。
1.在mainwindow.h文件中添加代碼。 添加私有槽: private?slots: ? ??void?showResult();
2.在mainwindow.cpp文件中添加代碼。
(1)先添加頭文件包含:#include ,然后在構(gòu)造函數(shù)中添加如下代碼: connect(&myProcess,SIGNAL(readyRead()), this, SLOT(showResult()));
(2)然后添加showResult()槽的定義: void?MainWindow::showResult() { ? ??qDebug() << "showResult: " << endl ? ?? ?? ?? ?< (3)最后將前面按鈕的單擊信號(hào)對(duì)應(yīng)的槽更改為: void?MainWindow::on_pushButton_clicked() { ? ??QString?program?=?"cmd.exe"; ? ??QStringList?arguments; ? ??arguments?< 3.?為了確??梢燥@示輸出的中文字符,在main.cpp文件中添加代碼。 先添加頭文件包含#include ,然后在main()函數(shù)第一行代碼下面,添加如下一行代碼: QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
4.運(yùn)行程序。 按下界面上的按鈕,會(huì)在Qt Creator中的應(yīng)用程序輸出欄中輸出命令的執(zhí)行結(jié)果。 ? ??對(duì)于Qt中進(jìn)程進(jìn)一步的使用可以參考QProcess類的幫助文檔。在Qt中還提供了多種進(jìn)程間通信的方法,大家可以在Qt幫助中查看Inter-ProcessCommunication in Qt關(guān)鍵字對(duì)應(yīng)的文檔。

二、線程 ? ? Qt提供了對(duì)線程的支持,這包括一組與平臺(tái)無關(guān)的線程類,一個(gè)線程安全的發(fā)送事件的方式,以及跨線程的信號(hào)-槽的關(guān)聯(lián)。這些使得可以很容易的開發(fā)可移植的多線程Qt應(yīng)用程序,可以充分利用多處理器的機(jī)器。多線程編程也可以有效的解決在不凍結(jié)一個(gè)應(yīng)用程序的用戶界面的情況下執(zhí)行一個(gè)耗時(shí)的操作的問題。關(guān)于線程的內(nèi)容,大家可以在Qt幫助中參考Thread Support in Qt關(guān)鍵字。
(一)啟動(dòng)一個(gè)線程 ? ? Qt中的QThread類提供了平臺(tái)無關(guān)的線程。一個(gè)QThread代表了一個(gè)在應(yīng)用程序中可以獨(dú)立控制的線程,它與進(jìn)程中的其他線程分享數(shù)據(jù),但是是獨(dú)立執(zhí)行的。相對(duì)于一般的程序都是從main()函數(shù)開始執(zhí)行,QThread從run()函數(shù)開始執(zhí)行。默認(rèn)的,run()通過調(diào)用exec()來開啟事件循環(huán)。要?jiǎng)?chuàng)建一個(gè)線程,需要子類化QThread并且重新實(shí)現(xiàn)run()函數(shù)。 ? ??每一個(gè)線程可以有自己的事件循環(huán),可以通過調(diào)用exec()函數(shù)來啟動(dòng)事件循環(huán),可以通過調(diào)用exit()或者quit()來停止事件循環(huán)。在一個(gè)線程中擁有一個(gè)事件循環(huán),可以使它能夠關(guān)聯(lián)其他線程中的信號(hào)到本線程的槽上,這使用了隊(duì)列關(guān)聯(lián)機(jī)制,就是在使用connect()函數(shù)進(jìn)行信號(hào)和槽的關(guān)聯(lián)時(shí),將Qt::ConnectionType類型的參數(shù)指定為Qt::QueuedConnection。擁有事件循環(huán)還可以使該線程能過使用需要事件循環(huán)的類,比如QTimer和QTcpSocket類等。注意,在線程中是無法使用任何的部件類的。 ? ??下面來看一個(gè)在圖形界面程序中啟動(dòng)一個(gè)線程的例子,在界面上有兩個(gè)按鈕,一個(gè)用于開啟一個(gè)線程,一個(gè)用于關(guān)閉該線程。
1.創(chuàng)建項(xiàng)目。 ? ? 新建Qt Gui應(yīng)用,名稱為“myThread”,類名為“Dialog”,基類選擇QDialog。
2.設(shè)計(jì)界面。 ? ??完成項(xiàng)目創(chuàng)建后進(jìn)入設(shè)計(jì)模式,向界面中放入兩個(gè)Push Button按鈕,將第一個(gè)按鈕的顯示文本更改為“啟動(dòng)線程”,將其objectName屬性更改為startButton;將第二個(gè)按鈕的顯示文本更改為“終止線程”,將其objectName屬性更改為stopButton,將其enabled屬性取消選中。
3.添加自定義線程類。 ? ??向項(xiàng)目中添加新的C++類,類名設(shè)置為“MyThread”,基類設(shè)置為“QThread”,類型信息選擇“繼承自QObject”。完成后進(jìn)入mythread.h文件,先添加一個(gè)公有函數(shù)聲明: void stop(); 然后再添加一個(gè)函數(shù)聲明和一個(gè)變量的定義: protected: ? ? void?run(); private: ? ? volatile bool stopped; ? ??這里stopped變量使用了volatile關(guān)鍵字,這樣可以使它在任何時(shí)候都保持最新的值,從而可以避免在多個(gè)線程中訪問它時(shí)出錯(cuò)。然后進(jìn)入mythread.cpp文件中,先添加頭文件#include ,然后在構(gòu)造函數(shù)中添加如下代碼: stopped = false; ? ? 這里將stopped變量初始化為false。下面添加run()函數(shù)的定義: void MyThread::run() { ? ? qreal i = 0; ? ? while (!stopped) ? ?? ???qDebug() << QString("in MyThread: %1").arg(i++); ? ? stopped = false; } ? ??這里一直判斷stopped變量的值,只要它為false,那么就一直打印字符串。下面添加stop()函數(shù)的定義: void MyThread::stop() { ? ? stopped = true; } ? ??在stop()函數(shù)中將stopped變量設(shè)置為了true,這樣便可以結(jié)束run()函數(shù)中的循環(huán),從而從run()函數(shù)中退出,這樣整個(gè)線程也就結(jié)束了。這里使用了stopped變量來實(shí)現(xiàn)了進(jìn)程的終止,并沒有使用危險(xiǎn)的terminate()函數(shù)。
4.在Dialog類中使用自定義的線程。 先到dialog.h文件中,添加頭文件包含: #include "mythread.h" ? ??然后添加私有對(duì)象的定義: MyThread thread; ? ? 下面到設(shè)計(jì)模式,分別進(jìn)入兩個(gè)按鈕的單擊信號(hào)對(duì)應(yīng)的槽,更改如下:
// 啟動(dòng)線程按鈕 void Dialog::on_startButton_clicked() { ? ? thread.start(); ? ? ui->startButton->setEnabled(false); ? ? ui->stopButton->setEnabled(true); }
// 終止線程按鈕 void Dialog::on_stopButton_clicked() { ? ? if (thread.isRunning()) { ? ?? ???thread.stop(); ? ?? ???ui->startButton->setEnabled(true); ? ?? ???ui->stopButton->setEnabled(false); ? ? } } ? ??在啟動(dòng)線程時(shí)調(diào)用了start()函數(shù),然后設(shè)置了兩個(gè)按鈕的狀態(tài)。在終止線程時(shí),先使用isRunning()來判斷線程是否在運(yùn)行,如果是,則調(diào)用stop()函數(shù)來終止線程,并且更改兩個(gè)按鈕的狀態(tài)。現(xiàn)在運(yùn)行程序,按下“啟動(dòng)線程”按鈕,查看應(yīng)用程序輸出欄的輸出,然后再按下“終止線程”按鈕,可以看到已經(jīng)停止輸出了。 ? ??下面我們接著來優(yōu)化這個(gè)程序,通過信號(hào)和槽來將子線程中的字符串顯示到主界面上。
1.在mythread.h文件中添加信號(hào)的定義: signals: void stringChanged(const QString &);
2.然后到mythread.cpp文件中更改run()函數(shù)的定義: void?MyThread::run() { ? ??long?int?i?=?0; ? ??while?(!stopped)?{ ? ?? ??QString?str?=?QString("in?MyThread:?%1").arg(i); ? ?? ??emit?stringChanged(str); ? ?? ??msleep(1000); ? ?? ??i++; ? ??} ? ??stopped?=?false; } 這里每隔1秒就發(fā)射一次信號(hào),里面包含了生成的字符串。
3.到dialog.h文件中添加槽聲明: private?slots: ? ??void?changeString(const?QString?&);
4.打開dialog.ui,然后向主界面上拖入一個(gè)Label標(biāo)簽部件。
5.到dialog.cpp文件中,在構(gòu)造函數(shù)里面添加信號(hào)和槽的關(guān)聯(lián): //?關(guān)聯(lián)線程中的信號(hào)和本類中的槽 connect(&thread,?SIGNAL(stringChanged(QString)), this, SLOT(changeString(QString)));
6.然后添加槽的定義: void?Dialog::changeString(const?QString?&str) { ? ??ui->label->setText(str); } ? ??這里就是將子線程發(fā)送過來的字符串顯示到主界面上?,F(xiàn)在可以運(yùn)行程序,查看效果了。

(二)線程同步 ? ? Qt中的QMutex、QReadWriteLock、QSemaphore和QWaitCondition類提供了同步線程的方法。雖然使用線程的思想是多個(gè)線程可以盡可能的并發(fā)執(zhí)行,但是總有一些時(shí)刻,一些線程必須停止來等待其他線程。例如,如果兩個(gè)線程嘗試同時(shí)訪問相同的全局變量,結(jié)果通常是不確定的。QMutex提供了一個(gè)互斥鎖(mutex);QReadWriteLock即讀-寫鎖;QSemaphore即信號(hào)量;QWaitCondition即條件變量。
(三)可重入與線程安全 在查看Qt的幫助文檔時(shí),在很多類的開始都寫著“All functions in this class are reentrant”,或者“All functions in this class are thread-safe”。在Qt文檔中,術(shù)語“可重入(reentrant)”和“線程安全(thread-safe)”用來標(biāo)記類和函數(shù),來表明怎樣在多線程應(yīng)用程序中使用它們: 一個(gè)線程安全的函數(shù)可以同時(shí)被多個(gè)線程調(diào)用,即便是這些調(diào)用使用了共享數(shù)據(jù)。因?yàn)樵摴蚕頂?shù)據(jù)的所有實(shí)例都被序列化了。 一個(gè)可重入的函數(shù)也可以同時(shí)被多個(gè)線程調(diào)用,但是只能是在每個(gè)調(diào)用使用自己的數(shù)據(jù)時(shí)。

結(jié)語

最后要注意的是,使用線程是很容易出現(xiàn)問題的,比如無法在主線程以外的線程中使用GUI類的問題(可以簡(jiǎn)單的通過這樣的方式來解決:將一些非常耗時(shí)的操作放在一個(gè)單獨(dú)的工作線程中來進(jìn)行,等該工作線程完成后將結(jié)果返回給主線程,最后由主線程將結(jié)果顯示到屏幕上)。大家應(yīng)該謹(jǐn)慎的使用線程。
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉