QtのQTextCodec乱談


どこから始まるの?
Qtプログラムにlatin 1文字セット以外の文字が現れると,ほとんど例外なくQTextCodecが用いられる.
多くのネットユーザーは、中国語を使うと、次の3つの命令を同時に使用します(textcはgb 18030またはutf 8とし、systemも使用します).
QTextCodec::setCodecForCStrings(textc);
QTextCodec::setCodecForTr(textc);
QTextCodec::setCodecForLocale(textc);

しかし、この3つのものは何の役に立つのでしょうか.QTextCodecは何に使いますか?
文字列、バイトストリーム
CとC++では、私たちは一般的に「hello world!」これを文字列と呼ぶ(狭い文字列、C伝統文字列、char*文字列...)
しかし、現在、文字列を提案する場合、一般的にUnicode文字列であり、1つのunicode文字から構成されている.バイトストリームを抽出すると、1つ1つのバイトを指します.
もしかすると、ANSI C、C++のカットオフは現在バイトストリームのみであり、文字列のサポートが不足していると言えるかもしれません.
Qtはバイトストリームと文字列にそれぞれQByteArrayとQStringの2つのクラス(QLatin 1 Stringなどの他のクラスもありますが、この2つが最も主要です).IOに触れると、例えばファイルの読み書き、ネットワークの読み書き、コンソール(端末)の入出力、読み書きシリアルポート...操作はすべてバイトストリームであり、このとき必要な操作の内容が文字列であれば、両者の間の相互変換が必要です.
QTextCodecは何をしますか?
Java、C#、pythonなどの言語にunicode文字列が内蔵されている場合、C、C++はunicodeに対して直接的なサポートを提供していません(いわゆるワイド文字wchar_tがありますが、問題は解決できません).次世代標準(C++0 x,C 1 x)でもunicodeは一部のサポートを提供しているだけで、本当に...
標準はunicodeに対してサポートが不足しており、各コンパイラの符号化に対するサポートは大きく異なり、unicode文字列が必要でプラットフォームを誇張するC++のライブラリQtにとって、本当に挑戦である.Qtはこの問題を解決するためにQTextCodecを提供した.
QTextCodecは、文字列とバイトストリームとの間の相互変換(すなわち、文字の符号化)を提供する.
QTextCodecが何をしたのかを知るために、まず自分のcodecを定義してみましょう.
カスタムQTextCodec
  • latin 1のような1バイトの文字セットを定義する
  • 共0~255この256個の符号ビット
  • latin 1と比較すると、a-zとA-Zが逆の順序
  • にすぎない.
  • 例えば、バイトストリーム"x 68x 65x 6 cx 6 cx 6 fx 20x 77x 6 fx 72x 6 cx 64x 21"
  • latin 1で復号するとu「hello world!」
  • は私たちのカスタムコードに従って、意味のないu“svool dliow!”

  • class DbzhangCodec:public QTextCodec
    {
    public:
        DbzhangCodec(){}
        ~DbzhangCodec(){}
    
        QString convertToUnicode(const char *chars, int len, ConverterState *) const
        {
            if (len <= 0 || chars == 0)
                return QString();
            QString r(len);
            for (int i=0; i<len; ++i) {
                if (chars[i] > 'a' && chars[i] < 'z')
                    r[i] = 'a' + 'z' - chars[i];
                else if (chars[i] > 'A' && chars[i] < 'Z')
                    r[i] = 'A' + 'Z' - chars[i];
                else
                    r[i] = QLatin1Char(chars[i]);
            }
            return r;
        }
        QByteArray convertFromUnicode(const QChar *in, int len, ConverterState *) const
        {
            QByteArray r(len, '?');
            for (int i=0; i<len; ++i) {
                int u = in[i].unicode();
                if (u > 255)
                    r[i] = '?';
                else if (u > 'a' && u < 'z')
                    r[i] = 'z' - u + 'a';
                else if (u > 'A' && u < 'Z')
                    r[i] = 'Z' - u + 'A';
                else
                    r[i] = u;
            }
            return r;
        }
    
        QByteArray name() const {return "dbzhang800";}
        QList<QByteArray> aliases() const{return QList<QByteArray>()<<"dbzhang-800";}
        int mibEnum() const{return 2011;}
    };

    このクラスは主に2つの関数を実現し、1つはバイトストリームからunicodeへの変換であり、1つはunicodeからバイトストリームへの変換である.
    使用例
    カスタムcodecを定義しましたが、どのように使用しますか?
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QTextCodec * codec = new DbzhangCodec;
        QTextCodec::setCodecForCStrings(codec);
        qDebug()<<QString("hello world!");
        return 0;
    }

    注意:ここではnewを使用しますが、対応するdeleteはありません.これは、QtがTextCodecを作成するたびにQListに格納されるため、メモリが漏れることはありません.これにより、プログラムが終了すると、codecが破棄されていない場合、クリーンアップされます.
    この例では、2つの文字列とバイトストリームの変換について説明します.
  • "hello world!"バイトストリームです.「x 68x 65x 6 cx 6 cx 6 cx 6 fx 20x 77x 6 fx 72x 6 cx 64x 21」
  • に相当します.
  • QStringとバイトストリームのデフォルト変換符号化をカスタマイズしたcodec
  • に設定
  • すると、前のバイトストリームはu「svool dliow!」に復号される.このようなunicode文字列
  • qDebugこの文字列を出力する場合、バイトストリームに符号化する必要がありますか?どのようにコードしますか?QTextCodec::setCodecForLocaleによって制御され、デフォルト符号化はsystem
  • である.
  • は「svool dliow!」と符号化された.このようなバイトストリーム出力.

  • プラグイン
    前にcodecをカスタマイズしましたが、使っても大丈夫ですが、あまり正規ではないようですね.普通はプラグインを出して、実行可能なプログラムがあるディレクトリの下のcodecsサブディレクトリの下に置いて、プログラムに自動的に識別させるのではないでしょうか.
    はい、少し多くの仕事をして、前にcodecを定義したファイルにクラスを追加します.
    #include <QTextCodecPlugin>
    #include <QTextCodec>
    
    class DbzhangCodecPlugin : public QTextCodecPlugin
    {
    public:
        DbzhangCodecPlugin() {}
    
        QList<QByteArray> names() const {return QList<QByteArray>()<<"dbzhang800";}
        QList<QByteArray> aliases() const {return QList<QByteArray>()<<"dbzhang-800";}
        QList<int> mibEnums() const {return QList<int>()<<2011;}
    
        QTextCodec *createForMib(int mib)
        {
            return mib == 2011 ? new DbzhangCodec : 0;
        }
    
        QTextCodec *createForName(const QByteArray & name)
        {
            if (name == "dbzhang800" || name == "dbzhang-800")
                return new DbzhangCodec;
            else
                return 0;
        }
    };
    
    Q_EXPORT_PLUGIN2(dbzhangcodec, DbzhangCodecPlugin)

    一つ組み合わせるProファイル
    TARGET = dbzhangcodec
    TEMPLATE  = lib
    CONFIG    += plugin
    SOURCES += codecplugin.cpp

    次に、生成されたダイナミックライブラリを実行可能プログラムディレクトリのcodecsサブディレクトリの下に配置します.
    この場合、プログラムで直接使用できます.
        QTextCodec * codec = QTextCodec::codecForName("dbzhang800");

    setCodecFor****
    この3つのものはいったい何をしているのでしょうか.
    QTextCodec::setCodecForCStrings(textc);
    QTextCodec::setCodecForTr(textc);
    QTextCodec::setCodecForLocale(textc);

    3つの簡単なもの.バイトストリーム<==>文字列
    setCodecForCStrings
    void QTextCodec::setCodecForCStrings ( QTextCodec * codec ) [static]
    
    Sets the codec used by QString to convert to and from const char * and QByteArrays. If the codec is 0 (the default), QString assumes Latin-1.

    QStringと中国語の問題で私たちはこれを紹介したことがあります.QStringに影響します
  • QString ( const char * str )
  • QString ( const QByteArray & ba )
  • QString & append ( const QByteArray & ba )
  • QString & append ( const char * str )
  • bool operator!= ( const QByteArray & other ) const
  • bool operator!= ( const char * other ) const
  • QString & operator= ( const QByteArray & ba )
  • QString & operator= ( const char * str )
  • QString fromAscii ( const char * str, int size = -1 )
  • QString fromAscii ( const char * str, int size = -1 )
  • ...

  • などはバイトストリーム(QByteArrayまたはchar*)に関連するがfromUtf 8などのように明確に符号化されたメンバー関数を指定しているかどうか.
    QByteArrayクラスでunicode文字列に関連するメンバー関数
  • QByteArray & append ( const QString & str )
  • int indexOf ( const QString & str, int from = 0 ) const
  • bool operator< ( const QString & str ) const
  • ...

  • setCodecForTr
    void QTextCodec::setCodecForTr ( QTextCodec * c ) [static]
    
    Sets the codec used by QObject::tr() on its argument to c. If c is 0 (the default), tr() assumes Latin-1.

    Qtではtranslate,tr関係と中国語の問題について述べた.
    私たちが
    QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 ) [static]

    この関数の場合、sourceTextというバイトストリームをQString文字列に変換する必要があります.
    翻訳ファイルをロードした場合、Qtはバイトストリームをkeyとして対応する翻訳された文字列を検索します.
    翻訳ファイルをロードしなかったら?Qtは、あるcodecがバイトストリームをunicode文字列に復号する必要がある.
    setCodecForLocale
    void QTextCodec::setCodecForLocale ( QTextCodec * c ) [static]
    
    Set the codec to c; this will be returned by codecForLocale(). If c is a null pointer, the codec is reset to the default.
    
    This might be needed for some applications that want to use their own mechanism for setting the locale.

    これは何も言うことはありませんが、ほとんどの場合、コードではこの関数を使用できないはずです(デフォルトのシステムは私たちが設定できるより良いはずです).
  • プログラムのコマンドラインからパラメータを読み込むとint main(int argc,char*argv[])
  • コンソールからコンテンツを出力するとqDebug()<
  • 使用QString::fromLocal 8 Bit()とQString::toLocal 8 Bit()
  • ...