① qt多線程調用函數問題
主界面有兩個按鈕,點擊「開始」按鈕,觸發一個信號,然後子線程列印一條信息,點擊「結束」按鈕,關閉線程
② QT 自定義多線程
.h
.cpp
使用:
③ 在Qt的多線程網路通信中一個TCPSocket怎麼實現讀和寫
你好 ,能開源你的代碼不?感覺沒看夠啊。正好需要用到你上面的一些功能和技術,主要是多線程的socket。
④ QT中udp多線程怎麼處理
Qt上要求界面處理一般需要在主線程中完成。
所以最好把次線程中的數據緩沖區放到主線程中:
1、一種方式可以進行數據拷貝,但肯定效率低了。
2、另一種方式是直接將數據緩沖區放到主線程中,然後在主線程中處理讀取數據槽。但這樣可能主線程壓力大,機器配置不能太低。
3、直接在主線程中訪問次線程的數據並刷新界面,不過這處理起來復雜(需要手工同步),容易出錯。
4、將TableWidget指針傳入次線程中,直接在次線程中對其進行操作並發送刷新信號。這種方式未經驗證,感覺可能性不大:一方面指針容易走空,另一方面就是前面說的限制在主線程中對接面進行處理。不過所說的「處理」可能並不包括刷新數據吧。
期待樓主進行驗證,並展示結果。
⑤ qt中如何實現多線程
QT線程是獨立的類:
在QT中添加C++類,頭文件引用#include <QThread>;類公開,這樣寫:
class XXXX:public QThread,類裡面申明Q_OBJECT,直接寫在裡面。signals: XXX();這是你的訂閱事件名。private:void run();這是run函數;public: int cona=3;這是變數,一定要public。
cpp文件里引用頭文件,run函數裡面寫方法:
void XXXX::run()
{
do
{
msleep(cona);
emit connec();
}while(true);
}
上面就是線程類了。現在我們在窗體中應用,先在頭文件申明
頭文件private: XXXX *thread1;XXXX *thread2;
構造函數中初始化他們
thread1=new XXXX();
thread1->cona=3;
QObject::connect(thread1,SIGNAL(connec()),this,SLOT(XXX信號1()));
thread2=new XXXX();
thread2->cona=4;
QObject::connect(thread2,SIGNAL(connec()),this,SLOT(XXX信號2()));
XXX信號1()是讀A數據,XXX信號2()讀B數據。
按鈕1的信號槽里寫方法同時進行每3秒讀A、沒4秒讀B
thread1->start();
thread2->start();
要結束誰就用 xxxx->terminate();
看明白沒?QT可不同與C++,你不熟悉編程環境,是很難理解的。
⑥ Qt網路編程
Qt網路模塊為我們提供了編寫TCP / IP客戶端和伺服器的類。 它提供了較低級別的類,例如代表低級網路概念的QTcpSocket,QTcpServer和QUdpSocket,以及諸如QNetworkRequest,QNetworkReply和QNetworkAccessManager之類的高級類來執行使用通用協議的網路操作。 它還提供了諸如QNetworkConfiguration,QNetworkConfigurationManager和QNetworkSession等類,實現承載管理。
要使用Qt網路類需要:
#include <QtNetwork>
要鏈接到Qt網路模塊需要:
QT += network
名稱空間
網路類
網路訪問API是用於執行常見網路操作的類的集合.API在所使用的特定操作和協議(例如,通過HTTP獲取和發布數據)上提供了一個抽象層,並且僅暴露了一般或高級概念的類,函數和信號。
⑦ qthread如何啟動多個線程
1. 引言
多線程對於需要處理耗時任務的應用很有用,一方面響應用戶操作、更新界面顯示,另一方面在「後台」進行耗時操作,比如大量運算、復制大文件、網路傳輸等。
使用Qt框架開發應用程序時,使用QThread類可以方便快捷地創建管理多線程。而多線程之間的通信也可使用Qt特有的「信號-槽」機制實現。
下面的說明以文件復制為例。主線程負責提供交互界面,顯示復制進度等;子線程負責復制文件。最後附有可以執行的代碼。
2. QThread使用方法1——重寫run()函數
第一種使用方法是自己寫一個類繼承QThread,並重寫其run()函數。
大家知道,C/C++程序都是從main()函數開始執行的。main()函數其實就是主進程的入口,main()函數退出了,則主進程退出,整個進程也就結束了。
而對於使用Qthread創建的進程而言,run()函數則是新線程的入口,run()函數退出,意味著線程的終止。復制文件的功能,就是在run()函數中執行的。
下面舉個文件復制的例子。自定義一個類,繼承自Qthread
CopyFileThread: public QThread
{
Q_OBJECTpublic:
CopyFileThread(QObject * parent = 0);protected: void run(); // 新線程入口// 省略掉一些內容}
在對應的cpp文件中,定義run()
void CopyFileThread::run(){ // 新線程入口
// 初始化和操作放在這里}
將這個類寫好之後,在主線程的代碼中生成一個CopyFileThread的實例,例如在mainwindow.cpp中寫:
// mainwindow.h中CopyFileThread * m_cpyThread;// mainwindow.cpp中m_cpyThread = new CopyFileThread;
在要開始復制的時候,比如按下「復制」按鈕後,讓這個線程開始執行:
m_cpyThread->start();
注意,使用start()函數來啟動子線程,而不是run()。start()會自動調用run()。
線程開始執行後,就進入run()函數,執行復制文件的操作。而此時,主線程的顯示和操作都不受影響。
如果需要進行對復制過程中可能發生的事件進行處理,例如界面顯示復制進度、出錯返回等等,應該從CopyFileThread中發出信號(signal),並事先連接到mainwindow的槽,由這些槽函數來處理事件。
3. QThread使用方法2——moveToThread()
如果不想每執行一種任務就自定義一個新線程,那麼可以自定義用於完成任務的類,並讓它們繼承自QObject。例如,自定義一個FileCopier類,用於復制文件。
class FileCopier : public QObject
{
Q_OBJECTpublic: explicit FileCopier(QObject *parent = 0);public slots: void startCopying(); void cancelCopying();
}
注意這里我們定義了兩個槽函數,分別用於復制的開始和取消。
這個類本身的實例化是在主線程中進行的,例如:
// mainwindow.h中private:
FileCopier* m_copier;// mainwindow.cpp中,初始化時
m_copier = new FileCopier;
此時m_copier還是屬於主線程的。要將其移動到子線程處理,需要首先聲明並實例化一個QThread:
// mainwindow.h中signals: void startCopyRsquested();private:
QThread * m_childThread; // m_copier將被移動到此線程執行// mainwindow.cpp中,初始化時
m_childThread = new QThread; // 子線程,本身不負責復制
然後使用moveToThread()將m_copier移動到新線程。注意moveToThread()是QObject的公有函數,因此用於復制文件的類FileCopier必須繼承自QObject。移動之後啟動子線程。此時復制還沒有開始。
m_copier->moveToThread(m_childThread); // 將實例移動到新的線程,實現多線程運行
m_childThread->start(); // 啟動子線程
注意一定要記得啟動子線程,否則線程沒有運行,m_copier的功能也無法執行。
要開始復制,需要使用信號-槽機制,觸發FileCopier的槽函數實現。因此要事先定義信號並連接:
// mainwindow.h中signals: void startCopyRsquested();// mainwindow.cpp中,初始化時// 使用信號-槽機制,發出開始指令
connect(this, SIGNAL(startCopyRsquested()), m_copier, SLOT(startCopying()));
當按下「復制」按鈕後,發出信號。
emit startCopyRsquested(); // 發送信號
m_copier在另一個線程接收到信號後,觸發槽函數,開始復制文件。
4.常見問題
4.1. 子線程中能不能進行UI操作?
Qt中的UI操作,比如QMainWindow、QWidget之類的創建、操作,只能位於主線程!
這個限制意味著你不能在新的線程中使用QDialog、QMessageBox等。比如在新線程中復制文件出錯,想彈出對話框警告?可以,但是必須將錯誤信息傳到主線程,由主線程實現對話框警告。
因此一般思路是,主線程負責提供界面,子線程負責無UI的單一任務,通過「信號-槽」與主線程交互。
4.2. QThread中的哪些代碼屬於子線程?
QThread,以及繼承QThread的類(以下統稱QThread),他們的實例都屬於新線程嗎?答案是:不。
需要注意的是,QThread本身的實例是屬於創建該實例的線程的。比如在主線程中創建一個QThread,那麼這個QThread實例本身屬於主線程。當然,QThread會開辟一個新線程(入口是run()),但是QThread本身並不屬於這個新線程。也就是說,QThread本身的成員都不屬於新線程,而且在QThread構造函數里通過new得到的實例,也不屬於新線程。這一特性意味著,如果要實現多線程操作,那麼你希望屬於新線程的實例、變數等,應該在run()中進行初始化、實例化等操作。本文給出的例子就是這樣操作的。
如果你的多線程程序運行起來,會出現關於thread的報警,思考一下,各種變數、實例是不是放對了位置,是不是真的位於新的線程里。
4.3. 怎麼查看是不是真的實現了多線程?
可以列印出當前線程。對於所有繼承自QObject的類,例如QMainwindow、QThread,以及自定義的各種類,可以調用QObject::thread()查看當前線程,這個函數返回的是一個QThread的指針。例如用qDebug()列印:
在mainwindow.cpp的某個函數里、QThread的run()函數里、自定義類的某個函數里,寫上:
qDebug() << "Current thread:" << thread();
對比不同位置列印的指針,就可以知道它們是不是位於同一個線程了。
5.範例
範例實現了多線程復制文本文件。
提供的範例文件可用QtCreator編譯運行。界面如下(不同的操作系統略有不同):
範例中實現了本文介紹的兩種方法,同時也給出了單線程復制對比。打鉤選擇不同的復制方法。可以發現,在使用多線程的時候,界面不會假死,第二根進度條的動畫是持續的;而使用單線程復制的時候,「取消」按鈕按不動,界面假死,而且第二根進度條的動畫也停止了。
由於範例處理的文件很小,為了讓復制過程持續較長時間以便使得現象明顯,復制文件的時候,每復制一行加入了等待。
範例代碼:
https://github.com/Xia-Weiwen/CopyFile
⑧ Qt多線程編程中子線程如何調用主線程中的成員變數
我提供兩種比較簡單的解決方案
創建一個Receiver的QObject, 該對象必須生存在你繼承的線程中
要麼給該對象構造對應的信號, 然後與你主線程窗體進行Connect, 一般來說是Queue的Connection
然後在子線程只要Emit你所實現的信號即可
或者用postEvent來解決, 自定義一種Event, 然後持有主線程窗體對象, 然後PostEvent給主線程窗體對象
⑨ Qt Socket網路編程 伺服器端提示QIODevice::read (QTcpSocket): device not open,但是與客戶端連接成功
這是因為文件路徑不對造成的,解決方法如下:
1、首先pro文件配置:Qt網路功能需要在pro文件增加網路庫。
⑩ qt多個線程調用同一個類怎麼處理
如果文件不大,應該以位元組流的形式載入文件到內存,然後多線程同時讀取,相當於批量上傳前,單線程載入弄個進度條。
多線程讀取文件的時候你可以給文件加鎖,如果有鎖sleep1沒有鎖就執行業務代碼然後釋放鎖。
qt應用程序開發框架,一個1991年由QtCompany開發的跨平台C加加圖形用戶界面應用程序開發框架。它既可以開發GUI程序,也可用於開發非GUI程序,比如控制台工具和伺服器。Qt是面向對象的框架,使用特殊的代碼生成擴展以及一些宏,Qt很容易擴展,並且允許真正地組件編程。