目次
1.QMainWindowウィンドウとUIデザインを作成します
1.QT独自のwindeployqt.exeを使用してパッケージ化します
2.より深いパッケージングには、HM NISEditエディターとNSISコンパイラーを使用します
I.はじめに
これはAmwayによって書かれた小さなシリアルデバッグアシスタントソフトウェアです。QT5.5で書かれています。Windowsでは通常使用できます。Linux環境ではテストされていません。Windows環境での文字エンコーディングがANSIであるため、文字が文字化けする場合があります。中国のシステムのANSIはGBKエンコーディング)であり、Linux環境の文字エンコーディングはUTF-8であり、デバッグアシスタントで送受信されるデータもGBKエンコーディングに従って変換されます。といった:
キャラクター |
GBKエンコーディング |
Unicodeエンコーディング |
UTF-8 |
「123ラーニング」 |
31 32 33 D1 A7 CF B0 |
31 32 33 5B 66 4E 60 |
31 32 33 E5 AD A6 E4 B9 A0 |
1.文字セットエンコーディングに関する拡張読み取り
5. QTシリアルポートの中国語表示の問題、UnicodeからGBK
2.文字エンコーディングに関する要約
1.文字はテキスト記号の集まりです。各国には独自の言語と文字があります。これらの文字はどのようにコンピューターに保存されますか?コンピュータはすべて01バイナリで保存されるため、これらの文字を対応する一意のバイナリコードに変換するだけです。英語のASCII、中国語のGDBエンコード、日本語のShift-JISエンコードなど、さまざまなエンコードもあります。
2. ASCIIコード:1960年代に、米国は英語の文字とバイナリビットの関係を一律に規制する文字コードのセットを策定しました。これはASCIIコードと呼ばれます。ASCIIコードは合計128文字を指定します。エンコーディング。バイトの最後の7ビットのみが占有され、最初の1ビットは一律に0として定義されます。
3. GBKコード:128シンボルの英語エンコーディングで十分ですが、他の言語では128シンボルでは不十分であるため、中国語の文字を表すために2バイトが使用されるため、理論的には最大256x256 = 65536を表すことができます。シンボル
4. Unicode:世界には多くのエンコード方法があります。同じバイナリ番号は異なるシンボルとして解釈できます。テキストファイルを開く場合は、そのエンコード方法を知っている必要があります。そうでない場合、間違ったエンコード方法で解釈されます。文字化けした文字が表示されます。不整合の問題を解決するために、国際的な組織が出てきて、世界中のすべての言語文字を含むエンコーディング、つまりUnicodeエンコーディングを策定しました。Unicodeは通常、文字を表すために2バイトを使用します。元の英語のエンコーディングはシングルバイトからダブルバイトに変更されます。すべての上位バイトを0で埋めるだけで済みます。ただし、Unicodeは単なるシンボルセットであり、シンボルのバイナリコードを指定するだけで、バイナリコードの保存方法は指定しません。1バイトのASCIIの利点を表すためにUnicodeを使用すると、メモリが浪費され、Unicodeのさまざまな保存方法もあります。
5. UTF-8エンコーディング:UTF-8は、インターネット上で最も広く使用されているユニコード実装です。他の実装には、UTF-16およびUTF-32が含まれます。UTF-8の最大の特徴の1つは、可変長のエンコード方式であるということです。1〜6バイトを使用してシンボルを表すことができ、バイト長はシンボルごとに異なります。
2.機能と効果
1.効果
ナンセンスな話をしないで、最初に効果を見てください
2.機能
1.シリアルポートの構成情報を記録して保存し、次回開いたときに最後の構成を直接使用できるようにします。
2.データをシリアルポート受信エリアに保存します(シリアルポートで受信することも、シリアルポートで送信することもできます)。
3.受信ウィンドウと送信ウィンドウのデータをクリアするための1つのキー
4.受信時に、16進表示または文字表示を選択でき、現在の時刻と送信データを表示することを選択できます
5.送信するときは、定期的に送信するか、新しい行を送信するか、ファイルデータを送信するかを選択できます。なお、16進数の送信を選択するかしないかは、送信エリアの文字表示を切り替えるだけです。送信されるデータはすべてANSIエンコードのバイトデータです。16進数を選択すると、文字はANSIエンコードに変換されます(ここではGBKコード)表示、16進数をチェックせずに文字を表示する、または16進数のデータをANSIコードに従って文字に変換する
6.現在のシリアルポートのステータス、送信されたバイト数、受信されたバイト数、および現在の時刻を表示できます。
三、実現プロセス
1.QMainWindowウィンドウとUIデザインを作成します
作成後、.proプロジェクト管理ファイルにQT + = serialportを追加して、シリアルポートを使用できるようにします。
2.コードの実装
ソース接続:https://github.com/denghengli/qt_study/tree/master/17_SerialPort
焦点を合わせる:
1.信号とスロットを関連付ける方法
方法1:
0)カスタム信号の場合は、.hで宣言する必要があります
1).hでスロット機能を宣言します
2).cppにスロット機能を実装する
3)connectを使用して、信号とスロット機能を接続します。
QObject::connect(ui->pushbutton,SIGNAL( clicked() ),this,SLOT( on_pushBuuton_clicked() );
方法2:
.uiファイルで、ボタンを右クリックし、[スロットに移動]オプションを選択し、「クリックされた」信号を選択して、スタンドアロンの[OK]ボタンを選択します。システムはスロット関数の宣言と定義を自動的に生成し、内部マッピングを確立します。スロット関数本体にスロット関数の関数を記述し、メソッド1のステップ2としてステートメントを追加するだけです。
方法3:
.uiインターフェイスで、[信号/スロットの変更]オプションを選択し、[+]をクリックして新しいスロット機能を追加し、確認してスロット機能の追加を完了し、最後に方法1の手順1と2を繰り返して、スロット機能の宣言と定義を完了します。
2.ファイルの送信とファイルの保存
QFileDialogクラスによって提供されるファイルダイアログボックスを介して、送信するファイルと新しく保存されたファイルを選択します
openfile_path = QFileDialog::getOpenFileName(this, "打开文件", "", "Text File(*.txt)");
savefile_path = QFileDialog::getSaveFileName(this,"另存为", savefile_path, "Text File(*.txt)");
3.構成情報を保存します
シリアルポート、ボーレート、ストップビットなどを設定した後、シリアルポートを開くたびに、QSettingsクラスを介して、設定情報をキー値の形式で所定のファイルに保存します。ソフトウェアを開くたびに読んでください。この構成ファイルのデータを取得し、シリアルポートを設定します
//创建ini配置文件
void SerialPort::configiniInit()
{
iniPath = new QDir;
iniFilename = iniPath->currentPath() + "/SerialPort.ini";
//构造一个QSettings对象,用于访问存储在名为iniFilename的文件中的设置。如果文件不存在,就创建它
configini = new QSettings(iniFilename, QSettings::IniFormat);
}
//读取ini配置文件,设置下拉框的项目
void SerialPort::configiniRead()
{
configini->beginGroup("SETUP");
int i_port = configini->value("COM").toInt();
int i_baudrate = configini->value("baudrate").toInt();
int i_databit = configini->value("databit").toInt();
int i_checkbit = configini->value("checkbit").toInt();
int i_stopbit = configini->value("stopbit").toInt();
configini->endGroup();
ui->CB_port->setCurrentIndex(i_port);
ui->CB_baudrate->setCurrentIndex(i_baudrate);
ui->CB_databit->setCurrentIndex(i_databit);
ui->CB_checkbit->setCurrentIndex(i_checkbit);
ui->CB_stopbit->setCurrentIndex(i_stopbit);
}
//写ini配置文件,将下拉框的项目索引写入ini文件
void SerialPort::configiniWrite()
{
configini->beginGroup("SETUP");
configini->setValue("COM", ui->CB_port->currentIndex());
configini->setValue("baudrate", ui->CB_baudrate->currentIndex());
configini->setValue("databit", ui->CB_databit->currentIndex());
configini->setValue("checkbit", ui->CB_checkbit->currentIndex());
configini->setValue("stopbit", ui->CB_stopbit->currentIndex());
configini->endGroup();
}
4.文字と16進コード文字間の変換
混同しないでください。これは、文字とANSI(ここではGBK)の16進コード文字の間の変換です。
例: "123 Learning" <----> "31 32 33 D1 A7 CF B0"
その理由は、textEditコントロールがQString文字を表示し、表示時に文字と16進数を切り替える必要があるためです。
"123学習" ----> "31 32 33 D1 A7 CF B0"ステップ:
//1、获取发送数据 QString = "123学习"
QString sendstr = ui->textEdit_tx->toPlainText();
//2、"123学习" --> GBK编码:31 32 33 D1 A7 CF B0
QByteArray sendarray = sendstr.toLocal8Bit();//"123学习"在QT中是UTF8编码的,所以这里需要使用toLocal8Bit转成Winds中的GBK编码
//3、GBK编码:31 32 33 D1 A7 CF B0 --> GBK编码字符:"31 32 33 D1 A7 CF B0"
QDataStream out(&sendarray,QIODevice::ReadWrite); //将字节数组读入
while(!out.atEnd())
{
qint8 outChar = 0;
out>>outChar; //每字节填充一次,直到结束
QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
str = str.toUpper();
ui->textEdit_tx->insertPlainText(str + " ");//在当前光标处插入文本
//返回表示当前可见游标的QTextCursor副本。对返回游标的更改不会影响QTextEdit的游标;使用setTextCursor()更新可见的游标
QTextCursor cursor = ui->textEdit_tx->textCursor();
cursor.movePosition(QTextCursor::End);//将光标移动到文档的最后
ui->textEdit_tx->setTextCursor(cursor);//更新光标
}
"31 32 33 D1 A7 CF B0" ----> "123学習"ステップ:
//1、获取发送数据 QString = "31 32 33 D1 A7 CF B0"
QString sendstr = ui->textEdit_tx->toPlainText();
QByteArray sendarray;
//2、GBK编码字符:"31 32 33 D1 A7 CF B0" --> GBK编码:31 32 33 D1 A7 CF B0
QStringtoHex(sendarray, sendstr);
//3、GBK编码:31 32 33 D1 A7 CF B0 --> Unicode编码 --> "123学习"
QString str1 = QString::fromLocal8Bit(sendarray);//实现了从本地字符集GBK到Unicode的转换,解决中文显示乱码问题
ui->textEdit_tx->setText(str1);
QStringtoHex(QByteArray&sendData、QString str)関数の方が重要であることがわかりますが、実装も比較的簡単です。
char SerialPort::ConvertHexChar(char c)
{
if(c>='a'&&c<='f'){
return c-'a'+10;
}
else if(c>='A'&&c<='F'){
return c-'A'+10;
}
else if(c>='0'&&c<='9'){
return c-'0';
}
else{
return -1;
}
}
//"31 32 33 D1 A7 CF B0" --> 31 32 33 D1 A7 CF B0
void SerialPort::QStringtoHex(QByteArray& sendData,QString str)
{
char hstr,lstr,hdata,ldata;
int len = str.length();
int sendnum = 0;
QByteArray temp;
temp.resize(len/2);//设置大小,len/2会大于实际16进制字符
for(int i=0;i<len;)
{
//QString转QByteArray的方法,Latin1代表ASCII。'3' --> 3
hstr = str[i].toLatin1();
if(hstr == ' '){
++i; continue;
}
if(++i >= len) break;
lstr = str[i].toLatin1();
hdata = ConvertHexChar(hstr);
ldata = ConvertHexChar(lstr);
if(-1 == hdata || -1 == ldata)
break;
++i;
temp[sendnum] = hdata<<4|ldata;
sendnum++;
}
sendData.reserve(sendnum);//重新调整大小
sendData = temp.left(sendnum);//返回一个 字节数组,其中包含这个字节数组最左边的len字节。去掉多余字符
}
3.プロジェクトパッケージのリリース
1.QT独自のwindeployqt.exeを使用してパッケージ化します
1.リリースを選択してプロジェクトをビルドします
2. .exeファイルを任意のパスにコピーしてパッケージ化し、QT環境がインストールされていない任意のコンピューターで実行できるようにします。パッケージ化する前に、まずQTインストールディレクトリにwindeployqt.exeがあることを確認してください。
3.ターミナルを開いて.exeディレクトリに入り(ショートカット:フォルダ内の空白部分をクリックし、Shiftキーを押しながら右クリックして[ここでウィンドウを開く]を選択します)、windeployqt.exeファイルを入力します。
4.生成が成功すると、現在のディレクトリにいくつかのファイルが生成されます。このフォルダをQT環境のない任意のコンピュータにコピーして実行します。
2.より深いパッケージングには、HM NISEditエディターとNSISコンパイラーを使用します
1.最初にQT独自のwindeployqt.exeを使用してパッケージ化し、実行可能ファイルと必要な動的ライブラリを生成します
2.ダウンロードしてインストール2つのソフトウェアNSISとNISの編集
3. NIS Editインストールウィザードを使用する手順に従って、windeployqt.exeのパッケージファイルをパッケージ化してSetup.exeインストールウィザードファイルを生成します。NISEDITを使用してインストールする場合、アプリケーションファイルを選択する際に注意が必要な点があります。いつ、パッケージ化する必要があるフォルダを選択します
完了後、このSetup.exeを介してシリアルデバッグアシスタントをインストールして使用できます。Setup.exeをインストールするときは、プロンプトに従ってください。次の手順で問題ありません。これはそれを良くしますか?
4、機能テスト
1.仮想シリアルポートツールをダウンロードします。VSDPをダウンロードしました。もちろん、他のツールも問題ありません。次の図に示すように、シリアルポートをローカルで仮想化できる限り、COM1とCOM2を相互接続できます。「ペアの追加」は新しい仮想シリアルポートを追加します。
2.シリアルポートでCOM2を開き、シリアルデバッグアシスタント(ここではXCOM)を使用してCOM1を開きます。相互にデータを送信することをテストしても問題ありません。