MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtの基礎 - 文字コードのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtの基礎 - 文字コード
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Qtでは、標準の文字コードはUTF-16である。<br> <br> 例えば、Visual StudioとQtを連携する場合、ソースコードのファイルの文字コードはUTF-8であるため、文字コードの変換が必要となる。<br> (変換しない場合は文字化けする)<br> <br><br> == QStringの内部表現 == QStringの内部表現は、プラットフォームに関係なく常にUTF-16で文字列を保持する。<br> <br> * 内部表現 *: <syntaxhighlight lang="c++"> QString str = "こんにちは"; // 内部的にはUTF-16として保存される </syntaxhighlight> * 確認方法 *: <syntaxhighlight lang="c++"> QString str = "こんにちは"; QByteArray utf16 = str.toUtf16(); // 内部表現のUTF-16を直接取得 QByteArray utf8 = str.toUtf8(); // UTF-8に変換 qDebug() << "UTF-16 size:" << utf16.size(); // UTF-16のバイト数 qDebug() << "UTF-8 size:" << utf8.size(); // UTF-8のバイト数 </syntaxhighlight> <br> * データの流れ *: <syntaxhighlight lang="c++"> // 入力 (UTF-8) -> QString (UTF-16) -> 出力 (任意の文字エンコーディング) QByteArray utf8_input = "こんにちは"; // UTF-8データ QString str = QString::fromUtf8(utf8_input); // 内部でUTF-16に変換 QByteArray output = str.toUtf8(); // 必要に応じてUTF-8に変換して出力 <br> QStringは常にUTF-16で保持する仕様であるため、UTF-8として保持する場合はQByteArrayを使用する必要がある。<br> <br> <u>※注意</u><br> <u>QByteArrayは、文字単位の操作が難しい。</u><br> <u>また、Unicode正規化等の操作ができない。</u><br> <br> <u>QByteArrayは、文字列長の取得が正確でない可能性がある。</u><br> <br> QFile::writeメソッドは、QByteArrayまたはconst char*を期待するため、QStringを直接指定する場合はエラーになる。<br> QStringからの暗黙の型変換は許可されていない。<br> <br> QTextStreamを使用する場合は、エンコーディングを明示的に制御できる。<br> バイナリモードで書き込む場合は、エンコーディングの制御が完全に開発者の責任になる。<br> <syntaxhighlight lang="c++"> QFile file("test.txt"); QString str = "こんにちは"; if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { // 方法 1 : QTextStreamを使用 (推奨) QTextStream out(&file); out.setEncoding(QStringConverter::Utf8); // UTF-8を指定 out << str; // 方法 2 : 直接バイト列として書き込む // file.write(str.toUtf8()); file.close(); } </syntaxhighlight> <br> 選択の基準<br> * QStringを使用する場合 *: テキスト処理や文字列操作が必要な場合 *: Unicode関連の操作が必要な場合 *: クロスプラットフォームの互換性が必要な場合 *: アプリケーション内部の処理では、QString (UTF-16) を使用する。 *: <br> * QByteArrayを使用する場合 *: バイナリデータとして扱う場合 *: エンコーディングを維持したまま保存、あるいは、送信する場合 *: メモリ使用量を最小限にする場合 *: 外部とのやり取り (ファイルI/O、ネットワーク通信等) では、必要に応じてQByteArray (UTF-8) を使用する。 <br><br> == QTextCodecクラスについて == ==== Qt 5 / Qt 6の違い ==== Qt 6では、<code>QTextCodec</code>クラスの使用方法が変更された。<br> <u>Qt 6では<code>QTextCodec</code>クラスのインクルードはサポートされておらず、代わりに文字エンコーディングの処理が<code>QStringConverter</code>クラスに移行された。</u><br> これにより、より柔軟で効率的な文字列変換が可能になった。<br> <br> * Qt 6の場合 <syntaxhighlight lang="c++"> #include <QStringConverter> </syntaxhighlight> <br> 例えば、Qt 5において、以下に示すようなコードがあるとする。<br> <syntaxhighlight lang="c++"> // 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); </syntaxhighlight> <br> Qt 6では、以下に示すように書き換えることができる。<br> <syntaxhighlight lang="c++"> // 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); </syntaxhighlight> <br> この変更は、QtのコアAPIをより現代的で効率的なものにするための一環である。<br> 新しいAPIは、以前のものと比較してより柔軟性が高く、パフォーマンスも向上している。<br> <br> ==== Qt 6でQTextCodecクラスを使用する場合 ==== Qt 6において、以前の<code>QTextCodec</code>クラスを使用することもできる。<br> <br> * CMakeを使用する場合 <syntaxhighlight lang="cmake"> find_package(Qt6 REQUIRED COMPONENTS Core5Compat) target_link_libraries(mytarget PRIVATE Qt6::Core5Compat) </syntaxhighlight> <br> * QMakeを使用する場合 <syntaxhighlight lang="make"> QT += core5compat </syntaxhighlight> <br> ソースコードファイルにおいて、<code>QTextCodec</code>クラスをインクルードする。<br> <syntaxhighlight lang="c++"> #include <QTextCodec> QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QString str = codec->toUnicode(byteArray); </syntaxhighlight> <br><br> == UTF-8から他の文字コードへの変換 == ==== QString::fromLocal8Bit() ==== Visual StudioとQtを連携する場合、文字列リテラルはソースコードのファイルの文字コードに関わらず、<br> ロケールの文字コード(WindowsならShift-JIS)に変換してコンパイルされるため、<br> 現在のロケールに合わせた文字コードで変換するQString::fromLocal8Bit()を使用する。<br> <syntaxhighlight lang="c++"> QString strU8 = QString::fromLocal8Bit("テスト"); ui->label->setText(strU8); </syntaxhighlight> <br> ==== QString::fromUtf8() ==== Visual Studio 2015以降とQtを連携する場合、Unicode文字列リテラルに対応しているため、<br> 接頭辞u8を付加することで、UTF-8のまま(ロケールの文字コードに変換されることなく)コンパイルすることができる。<br> <syntaxhighlight lang="c++"> QString strU8 = QString::fromUtf8(u8"テスト"); ui->label->setText(strU8); </syntaxhighlight> <br> ==== pragmaの指定 ==== Visual Studio 2013以前とQtを連携する場合、pragmaを指定することで、文字列リテラルをUTF-8に変換することができる。<br> <syntaxhighlight lang="c++"> #pragma execution_character_set("utf-8") </syntaxhighlight> <br> ==== その他の方法 ==== 以下のように、クラスに静的メソッドを定義して使用する方法でもよい。<br> <syntaxhighlight lang="c++"> std::string MainWindow::UTF16_to_UTF8(const QString &src) { return src.toUtf8().toStdString(); } </syntaxhighlight> <br><br> == UTF-16から他の文字コードへの変換 == ==== 現在のロケールへの変換 ==== UTF-16から現在のロケール(Windowsの場合はShift-JIS)へ変換する。<br> <syntaxhighlight lang="c++"> std::string MainWindow::UTF16_to_Locale(const QString &src) { return src.toLocal8Bit().toStdString(); } </syntaxhighlight> <br> ==== Shift-JISへの変換 ==== UTF-16からShift-JISへ変換する。<br> <syntaxhighlight lang="c++"> std::string MainWindow::UTF16_to_SJIS(const QString &src) { QTextCodec *codec = QTextCodec::codecForName("Shift-JIS"); QByteArray encoded = codec->fromUnicode(src); return encoded.toStdString(); } </syntaxhighlight> <br> ==== EUC-JPへの変換 ==== UTF-16からEUC-JPへ変換する。<br> <syntaxhighlight lang="c++"> std::string MainWindow::UTF16_to_EUC(const QString &src) { QTextCodec *codec = QTextCodec::codecForName("EUC-JP"); QByteArray encoded = codec->fromUnicode(src); return encoded.toStdString(); } </syntaxhighlight> <br><br> == Shift-JISからUTF-16への変換 == Shift-JISからUTF-16へ変換する。<br> <syntaxhighlight lang="c++"> QString MainWindow::SJIS_to_UTF16(const std::string &src) { QTextCodec *codec = QTextCodec::codecForName("Shift-JIS"); return codec->toUnicode(src.c_str()); } </syntaxhighlight> <br><br> == EUC-JPからUTF-16への変換 == EUC-JPからUTF-16へ変換する。<br> <syntaxhighlight lang="c++"> QString MainWindow::EUC_to_UTF16(const std::string &src) { QTextCodec *codec = QTextCodec::codecForName("EUC-JP"); return codec->toUnicode(src.c_str()); } </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
Qtの基礎 - 文字コード
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse