Qt程序的字符編碼方式


本節會創建一個圖形界面 Qt 程序,並故意對源文件使用不恰當的字符編碼方式,導致其文本顯示控件的漢字亂碼。我們會介紹兩種糾正方法:

  • 第一種是不修改源代碼文件編碼格式,通過 QString::fromLocal8Bit() 函數在程序運行時轉碼;
  • 第二種是直接將源代碼文件整體轉換成 UTF-8 編碼,就不需要修改具體的代碼行了。


第二種是最為推薦的方式,一勞永逸地解決亂碼問題,UTF-8 是 Qt5 默認的編碼方式。

亂碼的示例程序

首先「猛擊這里」下載 qtmess 示例程序,得到的是一個壓縮包,解壓到比如 D:\QtDemo\qtmess 文件夾里,然后用 QtCreator 打開該項目文件 qtmess.pro,看到項目配置提示界面:

 

 
一般選中 Select all kits ,然后點擊 Configure Project ,讓集成開發環境 QtCreator 自動配置好。

為了讓例子盡可能簡單,項目里面只有一個源文件 qtmess.cpp ,在項目視圖打開該源代碼文件,右邊編輯器出現以下提示:

 

 編輯器默認是認識 UTF-8 編碼的源文件,這個 qtmess.cpp 是在簡體中文 Windows 里用記事本編輯的,其漢字編碼格式是 GBK,所以上圖中文出現亂碼。右上角也提示出現解碼錯誤,不能用默認的 UTF-8 格式解碼。點擊“Select Encoding”按鈕,打開源文件編碼選擇對話框:

 

 對於簡體中文,選擇 GBK 打頭的條目或 GB18030 打頭的都可以,windows-936 和其他 CP936(CodePage)、MS936(Microsoft)是一個意思,大字符集 GB18030 也有其他稱呼,如 ibm-1392,windows 代碼頁編號 54936。這里選擇 GBK 的條目(GBK 條目有重復的,任選一個),然后點擊“按編碼重新載入”按鈕,文件里的漢字就正常了:

 

 注意 UTF-8 和 GBK 其實對英文和數字都是一樣的 ASCII 單字節編碼,所以源文件用英文和數字是肯定不亂碼,主要是漢字之類的本地語言文字編碼顯示容易出錯。

Windows 系統里一般的記事本、編輯器、VC++ 開發環境等都是默認用 GBK 漢字編碼,而 Linux 和 Qt 都是默認用 UTF-8 國際文字編碼,所以文本顯示亂碼一般都是這個原因,從編輯器里選擇正確的編碼就可以正常顯示本地語言文字了。

查看源文件的編碼格式

選擇源文件編碼之后,GBK 編碼文件和 UTF-8 編碼文件都能正確顯示,但怎么從 QtCreator 看到當前文件編碼格式呢?這個是可以配置的,讓 QtCreator 自動顯示。點擊菜單“工具”--> “選項”,在選項對話框左邊選擇“文本編輯器”,右邊選擇“顯示”,看到下圖:

 

 
選中“Display file encoding”,然后點擊“OK”按鈕,就可以在編輯器右上角看到當前文件的編碼格式:

 

 現在右上角可以看到源文件編碼“GBK”了,這其實是一個快捷按鈕,打開可以彈出剛才的文件編碼對話框的。

關於代碼的說明

關於編輯器的編碼顯示介紹到這,下面解釋一下源文件里的內容:

//qtmess.cpp
#include <QApplication>
#include <QTextBrowser>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString strText = QObject::tr("1234打印漢字");
    QTextBrowser tb;
    tb.setText(strText);
    tb.setGeometry(40, 40, 400, 300);
    tb.show();
   
    return a.exec();
}

代碼中包含了 QApplication、QTextBrowser、QDebug 三個頭文件,QTextBrowser 是一個只讀的文本顯示框,一般用於大段文字的顯示,並可以選擇(Ctrl+A)並復制(Ctrl+C)里面的文本;而之前用的 QLabel 一般用於短文本顯示,沒有復制文本的功能,QLabel 經常配合其他控件使用,顯示相關信息。

在 main() 函數內部:

  • 第一句定義了 Qt 應用程序入口;
  • 第二句定義了一個 strText 字符串對象,里面有數字和漢字;
  • 第三句定義了 QTextBrowser 對象 tb,就是本程序的圖形窗口;
  • 第四句設置文本框的文本內容為 strText ;
  • 第五句設置文本框的位置(屏幕左上角坐標 40,40)和尺寸(400*300);
  • 第六句是顯示本程序的窗口;
  • 最后一句是進入應用程序的事件循環,直到退出。


代碼比較簡單,接下來我們點擊 QtCreator 左下角的綠色三角形運行按鈕,編譯運行程序,看看效果:

 

 不出意外地,數字顯示是正常的,漢字是亂碼的,因為 Qt5 默認都是將源文件里的字符串當作 UTF-8 編碼處理,GBK 多字節編碼的漢字就會亂碼。對於糾正亂碼,正確的做法是將源文件的編碼格式修改成 UTF-8,不推薦的做法是使用 QString::​fromLocal8Bit() 函數實現轉碼。我們先來看看不推薦的做法。

【不推薦】QString::​fromLocal8Bit() 函數實現轉碼

我們先采用不改變源文件編碼的做法,而是通過修改具體的代碼行,使用 QString::​fromLocal8Bit() 函數代替 tr() 函數來實現轉碼。修改 qtmess.cpp 源文件內容如下:

//qtmess.cpp
#include <QApplication>
#include <QTextBrowser>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString strText = QString::fromLocal8Bit("1234打印漢字");
    QTextBrowser tb;
    tb.setText(strText);
    tb.setGeometry(40, 40, 400, 300);
    tb.show();
   
    return a.exec();
}

面將原來的 QObject::tr() 函數替換成了 QString::fromLocal8Bit() 函數,因為只有一個字符串所以替換了一次,如果字符串特別多,那就非常麻煩了。而且變成 QString::fromLocal8Bit() 函數之后,就不能通過檢測 tr() 函數進行國際化翻譯了,所以這種做法是不推薦的。

點擊 QtCreator 左下角運行按鈕,看看運行效果:

 

 現在漢字是正常顯示的,但代價是修改了代碼行,如果字符串很多,那就麻煩了。

【推薦】將源文件改成 UTF-8 編碼

將 qtmess.cpp 文件內容改回成原來的,還是使用原先的 QObject::tr() 封裝字符串。在 QtCreator 編輯器右上角,點擊文件編碼的“GBK”字樣:

 

 

 在編碼列表里找到“UTF-8”,選中該條目,然后點擊右下角的“按編碼保存”,QtCreator 會自動將文件內容轉換成 UTF-8 格式存儲,這樣就不需要修改具體的代碼行了:

 

 現在點擊左下角運行按鈕,同樣可以看到正常的漢字顯示。

本教程以后的全部文件格式都是按照 UTF-8 的編碼,這也是 Qt5 默認的源文件編碼格式,字符串也應該用 tr 函數封裝,方便做國際化翻譯。如果項目有面向國際化的要求,程序源代碼里應該全部用英文和數字等 ASCII 碼字符,盡量少用漢字,應當將漢字作為一個語言的翻譯文件程序。本教程大多數例子都是不符合國際化標准的,因為方便大家看,作者自己也省事。讀者實際的國際化項目開發中應該按照全英文的來寫代碼,然后將英文界面翻譯成多種語言文字的。

轉載:http://c.biancheng.net/view/5501.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM