導航:首頁 > 數據分析 > qt如何讀取地址數據

qt如何讀取地址數據

發布時間:2024-10-15 06:39:04

⑴ 如何在QT中讀取串口數據

一、文件下載

文件下載地址:

也可以下載我上傳到網盤上的:

二、文件內容介紹

1.下載到的文件為qextserialport-1.2win-alpha ,解壓並打開後其內容如下。

(點擊圖片可以查看清晰大圖)

下面分別介紹:

(1)doc文件夾中的文件內容是QextSerialPort類和QextBaseType的簡單的說明,我們可以使用記事本程序將它們打開。

(2)examples文件夾中是幾個例子程序,可以看一下它的源碼,不過想運行它們好像會出很多問題啊。

(3)html文件夾中是QextSerialPort類的使用文檔。

(4)然後就是剩下的幾個文件了。其中qextserialenumerator.cpp及qextserialenumerator.h文件中定
義的QextSerialEnumerator類是用來獲取平台上可用的串口信息的。不過,這個類好像並不怎麼好用,而且它不是我們關注的重點,所以下面
就不再介紹它了。

(5)qextserialbase.cpp和qextserialbase.h文件定義了一個QextSerialBase
類,win_qextserialport.cpp和win_qextserialport.h文件定義了一個Win_QextSerialPort
類,posix_qextserialport.cpp和posix_qextserialport.h文件定義了一個
Posix_QextSerialPort類,qextserialport.cpp和qextserialport.h文件定義了一個
QextSerialPort類。這個QextSerialPort類就是我們上面所說的那個,它是所有這些類的子類,是最高的抽象,它屏蔽了平台特徵,
使得在任何平台上都可以使用它。

2.幾個類的簡單介紹。

下面是這幾個類的關系圖。

可以看到它們都繼承自QIODevice類,所以該類的一些函數我們也可以直接來使用。圖中還有一個QextBaseType類,其實它只是一個標
識,沒有具體的內容,它用來表示Win_QextSerialPort或Posix_QextSerialPort
中的一個類,因為在QextSerialPort類中使用了條件編譯,所以QextSerialPort類既可以繼承自
Win_QextSerialPort類,也可以繼承自Posix_QextSerialPort類,所以使用了QextBaseType來表示。這一點
我們可以在qextserialport.h文件中看到。再說QextSerialPort類,其實它只是為了方便程序的跨平台編譯,使用它可以在不同的
平台上,根據不同的條件編譯繼承不同的類。所以它只是一個抽象,提供了幾個構造函數而已,並沒有具體的內容。在qextserialport.h文件中的
條件編譯內容如下:

#ifdef_TTY_POSIX_

#include「posix_qextserialport.h」

#define QextBaseTypePosix_QextSerialPort

#else

#include「win_qextserialport.h」

#define QextBaseTypeWin_QextSerialPort

#endif

所以,其實我們沒有必要使用這個類,直接使用Win_QextSerialPort或Posix_QextSerialPort就可以了。當然如果
你想使用這個類,實現同樣的源程序可以直接在Windows和Linux下編譯運行,那麼一定要注意在Linux下這里需要添加
#define _TTY_POSIX_ 。而我們這里為了使得程序更明了,所以沒有使用該類,下面也就不再介紹它了。

QextSerialBase類繼承自QIODevice類,它提供了操作串口所必需的一些變數和函數等,而
Win_QextSerialPort和Posix_QextSerialPort均繼承自QextSerialBase
類,Win_QextSerialPort類添加了Windows平台下操作串口的一些功能,Posix_QextSerialPort類添加了
Linux平台下操作串口的一些功能。所以說,在Windows下我們使用Win_QextSerialPort類,在Linux下我們使用
Posix_QextSerialPort類。

3.在QextSerialBase類中還涉及到了一個枚舉變數QueryMode。

它有兩個值Polling和EventDriven
。QueryMode指的是讀取串口的方式,下面我們稱為查詢模式,我們將Polling稱為查詢方式Polling,將EventDriven稱為事件驅動方式。

事件驅動方式EventDriven就是使用事件處理串口的讀取,一旦有數據到來,就會發出readyRead()信號,我們可以關聯該信號來讀取串口的數據。在事件驅動的方式下,串口的讀寫是非同步的,調用讀寫函數會立即返回,它們不會凍結調用線程。

而查詢方式Polling則不同,讀寫函數是同步執行的,信號不能工作在這種模式下,而且有些功能也無法實現。但是這種模式下的開銷較小。我們需要自己建立定時器來讀取串口的數據。

在Windows下支持以上兩種模式,而在Linux下只支持Polling模式。

三、小結。

這里講了這么多,最後要說的只是,我們在Qt中使用這個類編寫串口程序,根據平台的不同只需要分別使用四個文件。

在Windows下是:

qextserialbase.cpp和qextserialbase.h
以及win_qextserialport.cpp和win_qextserialport.h

在Linux下是:

qextserialbase.cpp和qextserialbase.h
以及posix_qextserialport.cpp和posix_qextserialport.h

而在Windows下我們可以使用事件驅動EventDriven方式,也可以使用查詢Polling方式,但是在Linux下我們只能使用查詢Polling方式。

第二部分 在Windows下編寫串口通信程序

我們的環境是Windowsxp,Qt4.6.3及Qt Creator2.0。

第一,下面我們首先使用事件驅動來實現串口通信。

1.新建工程。

我們在QtCreator中新建Qt Gui工程,命名為myCom,Base Class選擇QWidget。

2.添加文件。

我們將那四個文件添加到工程文件夾中。如下圖。

然後我們將這四個文件添加到工程中,在Qt
Creator的工程列表中的工程文件夾上點擊滑鼠右鍵,在彈出的菜單中選擇「AddExisting Files」菜單。如下圖。

我們在彈出的對話框中選中四個文件,按下「打開」按鈕即可,如下圖。

最終工程文件列表如下圖。

3.更改界面。

我們將界面設計如下。

其中的TextBrowser 部件用來顯示接收到的數據,Line Edit部件用來輸入要發送的數據,Push
Button按鈕用來發送數據。我們保持各部件的屬性為默認值即可。

4. 我們在widget.h文件中進行對象及函數聲明。

添加頭文件包含:#include「win_qextserialport.h」

然後在private中聲明對象:Win_QextSerialPort *myCom;

聲明私有槽函數:

private slots:

voidon_pushButton_clicked(); //」發送數據」按鈕槽函數

void readMyCom(); //讀取串口

5.在widget.cpp文件中進行更改。

在構造函數中添加代碼,完成後,構造函數內容如下:

Widget::Widget(QWidget*parent) :

QWidget(parent),

ui(newUi::Widget)

{

ui->setupUi(this);

myCom=
new Win_QextSerialPort(「COM1″,QextSerialBase::EventDriven);

//定義串口對象,指定串口名和查詢模式,這里使用事件驅動EventDriven

myCom->open(QIODevice::ReadWrite);

//以讀寫方式打開串口

myCom->setBaudRate(BAUD9600);

//波特率設置,我們設置為9600

myCom->setDataBits(DATA_8);

//數據位設置,我們設置為8位數據位

myCom->setParity(PAR_NONE);

//奇偶校驗設置,我們設置為無校驗

myCom->setStopBits(STOP_1);

//停止位設置,我們設置為1位停止位

myCom->setFlowControl(FLOW_OFF);

//數據流控制設置,我們設置為無數據流控制

myCom->setTimeout(500);

//延時設置,我們設置為延時500ms,這個在Windows下好像不起作用

connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));

//信號和槽函數關聯,當串口緩沖區有數據時,進行讀串口操作

}

實現槽函數:

void Widget::readMyCom()//讀取串口數據並顯示出來

{

QByteArray
temp = myCom->readAll();

//讀取串口緩沖區的所有數據給臨時變數temp

ui->textBrowser->insertPlainText(temp);

//將串口的數據顯示在窗口的文本瀏覽器中

}

voidWidget::on_pushButton_clicked() //發送數據

{

myCom->write(ui->lineEdit->text().toAscii());

//以ASCII碼形式將數據寫入串口

}

6.此時,我們運行程序,效果如下。

可以看到,已經成功完成通信了。

(註:我們這里下位機使用的是單片機,它使用串口與計算機的COM1相連。單片機上運行的程序的功能是,接收到一個字元便向上位機發送一個字元串然後發送接收到的字元。)

兩個重要問題的講解:

一、關於數據接收。

我們想在程序中對接收的數據進行控制,但是readyRead()信號是一旦有數據到來就發射的,不過我們可以使用bytesAvailable()函數來檢查已經獲得的位元組數,從而對數據接收進行控制。

(1)我們在widget.cpp中添加頭文件包含:#include

然後在讀串口函數中添加一行代碼,如下:

void Widget::readMyCom() //讀取串口數據並顯示出來

{

qDebug()
<< 「read:
「<<myCom->bytesAvailable()<<」bytes」;

//我們輸出每次獲得的位元組數

QByteArray
temp = myCom->readAll();

ui->textBrowser->insertPlainText(temp);

}

運行程序,效果如下:

可以看到,我們獲取的數據並不是一次獲得的。

(2)利用上面的結論,我們可以讓串口緩沖區擁有了一定的數據後再讀取。

void Widget::readMyCom()

{

if(myCom->bytesAvailable()>=8 )

//如果可用數據大於或等於8位元組再讀取

{

qDebug()
<< 「read:
「<<myCom->bytesAvailable()<<」bytes」;

QByteArray
temp = myCom->readAll();

ui->textBrowser->insertPlainText(temp);

}

}

運行程序,效果如下:

我們發送了兩次數據,可以看到,這樣實現了每8個位元組讀取一次,而最後剩餘的不夠8個位元組的數據將會和後面的數據一起讀出。

然後我們將8改為3,發送一次數據,效果如下:

改為7,發送兩次數據,效果如下:

改為11,發送兩次數據,效果如下:

改為17,發送三次數據,效果如下:

重要結論:我們發送一次數據,應該獲得37位元組的數據,然後我們對比上面的結果,發現了什麼?是的,其實串口每次讀取8位元組的數據放到緩沖區,只有
數據總數小於8位元組時,才會讀取小於8位元組的數據。為了再次驗證我們的結論,我們可以將上面程序中的「>=」改為「==」,那麼只有8的倍數才能讀
取數據(當然這里37也可以),你可以測試一下。

關於接收數據方面,可以根據你自己的需要再去進行研究和改進,這里只是拋磚引玉。

二、關於發送數據。

我們也可以使用函數獲取要發送的數據的大小,這里有個bytesToWrite()可以獲取要發送的位元組數。例如將發送數據更改如下:

voidWidget::on_pushButton_clicked() //發送數據

{

myCom->write(ui->lineEdit->text().toAscii());

qDebug()
<< 「write:
「<<myCom->bytesToWrite()<<」bytes」;

//輸出要發送的位元組數

}

運行後效果如下:

當然,對於要發送的數據的大小我們不是很關心,而且它還有很多方法可以實現,這個還有個bytesWritten()信號函數來獲取已經發送的數據的大小,不過好像它不是很好用。這里將它們提出來,只是供大家參考而已。

第二,使用查詢方式Polling來實現串口通信。

這里再次說明,Polling方式是不能使用readyRead()信號的,所以我們需要自己設置定時器,來不斷地讀取緩沖區的數據。

1.我們在widget.h中聲明一個定時器對象。

添加頭文件包含:#include

添加private變數:QTimer *readTimer;

2.我們在widget.cpp文件中的構造函數中更改。

(1)將串口定義更改為:

myCom =
newWin_QextSerialPort(「COM1″,QextSerialBase::Polling);

//定義串口對象,指定串口名和查詢模式,這里使用Polling

(2)定義定時器,並將以前的關聯更改為定時器的關聯。

readTimer = newQTimer(this);

readTimer->start(100);

//設置延時為100ms

connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));

//信號和槽函數關聯,延時一段時間,進行讀串口操作

3.此時運行程序,便可以正常收發數據了。

重點:關於延時問題。

上面的程序中可以進行數據的接收了,但是好像中間的延時有點長,要等一會兒才能收到數據,而且即便我們將定時器改為10ms
也不行。問題在哪裡呢?其實真正控制串口讀寫時間的不是我們的定時器,而是延時timeout。我們在構造函數中設置了延時:

myCom->setTimeout(500);

//延時設置,我們設置為延時500ms

我們前面說延時並不起作用,那是因為是在事件驅動的情況下,一旦有數據到來就會觸發readyRead()信號,所以延時不起作用。但是現在,真正
控制串口讀寫數據間隔的就是這個函數。這里值得注意,我們現在所說的串口讀寫是指底層的串口讀寫,從上面的程序中我們也可以看到,我們每隔100ms去讀
串口,確切地說,應該是去讀串口緩沖區。而timeout才是正真的讀取串口數據,將讀到的數據放入串口緩沖區。所以如果timeout時間很長,即便我
們的定時器時間再短,也是讀不到數據的。所以我們這里需要將timeout設置為較小的值,比如10。我們更改代碼:

myCom->setTimeout(10);

這樣再運行程序,我們就可以很快地獲得數據了。

關於數據接收:事件驅動那裡的結論依然有用,不過這里更多的是靠讀取的時間間隔來控制。

關於發送數據:這時bytesToWrite()函數就不再那麼好用了。

第三部分 在Linux下編寫串口通信程序

我這里的環境是Ubuntu10.04,Qt 4.6.3和Qt Creator2.0
。上面已經提到,在Linux下只能使用Polling的方式讀取串口數據,所以我們將上面Windows下的應用Polling的程序在Linux下重
新編譯。我們使用Qt Creator打開該工程,然後進行下面的操作。

1.文件替換。

將工程中的win_qextserialport.cpp和win_qextserialport.h文件替換成posix_qextserialport.cpp和posix_qextserialport.h文件。

(1)我們先刪除工程中的win_qextserialport.cpp和win_qextserialport.h文件。

在工程列表中用滑鼠右擊win_qextserialport.h,然後選擇「Remove File」選項。如下圖。

在彈出的對話框中我們選中「Deletefile permanently」選項,確保刪除了工程文件夾中的文件。如下圖。

然後我們使用同樣的方法刪除win_qextserialport.cpp文件。

(2)我們按照Windows下添加文件的方法,向工程中添加posix_qextserialport.cpp和posix_qextserialport.h文件。最終工程文件列表如下。

2.設置編碼。

(這是因為兩個系統使用的默認編碼不同造成的,如果你那裡沒有該問題,可以跳過這一步)

現在我們打開widget.cpp文件,發現中文出現亂碼,而且無法編輯。在編輯器最上面有一個黃色提示條和一個「Select
Encoding」按鈕,我們點擊該按鈕。如下圖。

在彈出的對話框中我們選擇「GB2312」。按下「Reload with Encoding」按鈕,中文就可以正常顯示了。

3.更改程序。

在widget.h文件中:

將以前的#include「win_qextserialport.h」更改為#include「posix_qextserialport.h」

將以前的Win_QextSerialPort*myCom;更改為Posix_QextSerialPort*myCom;

在widget.cpp文件中:

將以前的myCom= new
Win_QextSerialPort(「COM1″,QextSerialBase::Polling);

更改為:myCom= new
Posix_QextSerialPort(「/dev/ttyS0″,QextSerialBase::Polling);

(這里一定要注意串口名稱的寫法。)

4.下面我們運行程序。

這時可能會出現以下提示。

錯誤是說一個函數的調用出現了問題。我們點擊該錯誤,定位到出錯的位置,然後將那個函數中的第一個參數刪除即可。如下圖。

5.再次運行程序,這時已經可以正常運行了。

6.小結

可以看到將Windows下的串口程序在Linux下重新編譯是很簡單的,我們只需要替換那兩個文件,然後更改一下頭文件包含,對象定義和串口名即可。

⑵ Qt如何讀取數據文件

#include <QFile>

#include <QString>
#include <QIODevice>
#include <QDebug>
#include <QTextStream>

void Read(QString Filename)//名字自己定,需要帶路徑
{

QFile mFile(Filename);

if(!mFile.open(QFile::ReadOnly|QFile::Text))

{

qDebug()<<"could not open file for read!";

return;

}

QTextStream in(&mFile);

QString mtext = in.readAll();

// mtext = mtext.trimmed();

qDebug()<<mtext;

if(mtext == "")

qDebug()<<" read over!";

mFile.flush();

mFile.close();
}

⑶ Qt中關於QTextEdit的問題,如何獲取選中其中某個位置數據呢

要實現選中指定字元串可以看看 QTextCursor 類的相關方法,如果還需要選中高亮可以看看 QTextCharFormat 類的相關方法

閱讀全文

與qt如何讀取地址數據相關的資料

熱點內容
網路貸款一直不起訴怎麼辦 瀏覽:707
畢設程序寫不出來 瀏覽:621
廣州檔案文件袋設計多少錢 瀏覽:903
qq生死狙擊好號和密碼大全 瀏覽:33
g83編程有哪些例子 瀏覽:342
58app到底幾個 瀏覽:731
hdfs本地文件系統 瀏覽:33
蘋果手機上的app為什麼都要更新 瀏覽:247
用手機如何連接電腦的網路 瀏覽:940
dnf國慶版本2017活動 瀏覽:157
UG中編程完畢後處理選擇哪個 瀏覽:534
bat排除文件夾 瀏覽:81
金屬銻是什麼意思網路用語 瀏覽:887
解密壓縮文件軟體 瀏覽:167
qq空間電影視頻播放器 瀏覽:567
數據預測有哪些演算法 瀏覽:176
qt如何讀取地址數據 瀏覽:383
工業控制網路大體分為哪些層面 瀏覽:688
linuxmake日誌 瀏覽:705
文件覆蓋了怎麼找回 瀏覽:567

友情鏈接