Qtの基礎 - 文字コード

提供:MochiuWiki : SUSE, EC, PCB
2024年9月23日 (月) 09:30時点におけるWiki (トーク | 投稿記録)による版 (→‎Qt 5 / Qt 6の違い)
ナビゲーションに移動 検索に移動

概要

Qtでは、標準の文字コードはUTF-16である。

例えば、Visual StudioとQtを連携する場合、ソースコードのファイルの文字コードはUTF-8であるため、文字コードの変換が必要となる。
(変換しない場合は文字化けする)


QTextCodecクラスについて

Qt 5 / Qt 6の違い

Qt 6では、QTextCodecクラスの使用方法が変更された。
Qt 6ではQTextCodecクラスのインクルードはサポートされておらず、代わりに文字エンコーディングの処理がQStringConverterクラスに移行された。
これにより、より柔軟で効率的な文字列変換が可能になった。

  • Qt 6の場合
 #include <QStringConverter>


例えば、Qt 5において、以下に示すようなコードがあるとする。

 // Qt 5の場合
 
 #include <QTextCodec>
 
 // Shift-JISからUTF-8へデコードする場合
 QByteArray SJISdata = "あいうえお";
 QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
 QString str       = codec->toUnicode(SJISdata);
 
 // UTF-8からShift-JISへエンコードする場合
 QString    str  = "あいうえお";
 QByteArray data = str.toUtf8();  // 文字列をバイト列へ変換
 
 QTextCodec *codec;  // エンコードオブジェクト
 codec           = QTextCodec::codecForName("Shift-JIS");
 encodedPostData = codec->fromUnicode(data);


Qt 6では、以下に示すように書き換えることができる。

 // Qt 6の場合
 
 #include <QStringConverter>
 
 // Shift-JISからUTF-8へデコードする場合
 QByteArray SJISdata = "あいうえお";
 QStringDecoder decoder("Shift-JIS");
 QString str         = decoder(SJISdata);
 
 // UTF-8からShift-JISへエンコードする場合
 QString    str  = "あいうえお";
 QByteArray data = str.toUtf8();  // 文字列をバイト列へ変換
 
 QStringEncoder encoder("Shift-JIS");
 QString encodeStr = encoder(data);


この変更は、QtのコアAPIをより現代的で効率的なものにするための一環である。
新しいAPIは、以前のものと比較してより柔軟性が高く、パフォーマンスも向上している。

Qt 6でQTextCodecクラスを使用する場合

Qt 6において、以前のQTextCodecクラスを使用することもできる。

  • CMakeを使用する場合
 find_package(Qt6 REQUIRED COMPONENTS Core5Compat)
 
 target_link_libraries(mytarget PRIVATE Qt6::Core5Compat)


  • QMakeを使用する場合
 QT += core5compat


ソースコードファイルにおいて、QTextCodecクラスをインクルードする。

 #include <QTextCodec>
 
 QTextCodec *codec = QTextCodec::codecForName("UTF-8");
 QString str = codec->toUnicode(byteArray);



UTF-8から他の文字コードへの変換

QString::fromLocal8Bit()

Visual StudioとQtを連携する場合、文字列リテラルはソースコードのファイルの文字コードに関わらず、
ロケールの文字コード(WindowsならShift-JIS)に変換してコンパイルされるため、
現在のロケールに合わせた文字コードで変換するQString::fromLocal8Bit()を使用する。

 QString strU8 = QString::fromLocal8Bit("テスト");
 ui->label->setText(strU8);


QString::fromUtf8()

Visual Studio 2015以降とQtを連携する場合、Unicode文字列リテラルに対応しているため、
接頭辞u8を付加することで、UTF-8のまま(ロケールの文字コードに変換されることなく)コンパイルすることができる。

 QString strU8 = QString::fromUtf8(u8"テスト");
 ui->label->setText(strU8);


pragmaの指定

Visual Studio 2013以前とQtを連携する場合、pragmaを指定することで、文字列リテラルをUTF-8に変換することができる。

 #pragma execution_character_set("utf-8")


その他の方法

以下のように、クラスに静的メソッドを定義して使用する方法でもよい。

 std::string MainWindow::UTF16_to_UTF8(const QString &src)
 {
    return src.toUtf8().toStdString();
 }



UTF-16から他の文字コードへの変換

現在のロケールへの変換

UTF-16から現在のロケール(Windowsの場合はShift-JIS)へ変換する。

 std::string MainWindow::UTF16_to_Locale(const QString &src)
 {
    return src.toLocal8Bit().toStdString();
 }


Shift-JISへの変換

UTF-16からShift-JISへ変換する。

 std::string MainWindow::UTF16_to_SJIS(const QString &src)
 {
    QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
    QByteArray encoded = codec->fromUnicode(src);
 
    return encoded.toStdString();
 }


EUC-JPへの変換

UTF-16からEUC-JPへ変換する。

 std::string MainWindow::UTF16_to_EUC(const QString &src)
 {
    QTextCodec *codec = QTextCodec::codecForName("EUC-JP");
    QByteArray encoded = codec->fromUnicode(src);
 
    return encoded.toStdString();
 }



Shift-JISからUTF-16への変換

Shift-JISからUTF-16へ変換する。

 QString MainWindow::SJIS_to_UTF16(const std::string &src)
 {
    QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");
 
    return codec->toUnicode(src.c_str());
 }



EUC-JPからUTF-16への変換

EUC-JPからUTF-16へ変換する。

 QString MainWindow::EUC_to_UTF16(const std::string &src)
 {
    QTextCodec *codec = QTextCodec::codecForName("EUC-JP");
 
    return codec->toUnicode(src.c_str());
 }