Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Japanese
  4. 外字について
QtWS25 Last Chance

外字について

Scheduled Pinned Locked Moved Japanese
8 Posts 2 Posters 12.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    t-ozaki
    wrote on last edited by
    #1

    皆様はじめまして。
    尾崎@名古屋です。
    Qt名古屋勉強会 #4でも質問させていただいた内容なのですが
    未だ解決できないためご協力をお願いいたします。

    問題点
    Qt上で外字が文字化けして表示できません。
    QtCreatorも例外ではないです。
    Windows環境で確認しています。

    再現方法
    1.外字を作ります。
    外字エディタを起動します。
    Xpなら
    [プログラム]-[アクセサリ]-[ユーザー補助]-外字エディタ
    Vista以降は
    [プログラム]-[アクセサリ]-[システムツール]-外字エディタ
    開いたらコード「F040」を選択(デフォルトだと思います)してOKクリック
    他の文字と区別が付くように適当にお絵かきをしていただいて
    編集メニューから同じコードで保存(Ctrl+s)

    2.正しく登録されたどうか確認します。
    フォント等が変更できるアプリケーション(例えばWord)を起動します。
    カーソルを入力したい場所に入れた状態でIMEパッドから文字一覧を表示します。
    文字カテゴリでシフトJISを選択して0xF40を選択すると外字文字の入力が出来たと思います。
    あとはフォントサイズや種類を変更して変化することを確認してください。
    この文字を上記手順やコピペすればChromeやEclipseでも表示されるはずです。

    3.Qtで確認します。
    QtCreatorを起動して外字を貼り付けます。
    「・」か「□」のような文字に文字化けしたと思います。

    試したこと
    1.文字コードのマッピング?
    QTextCodec::setCodecForCStrings
    QTextCodec::setCodecForTr
    putenv("UNICODEMAP_JP=XXX")
    辺りをいろいろ組み合わせましたが解決に至りませんでした。
    試しに外字を含んだテキストを読み込んでからアウトプットしてみたところ
    文字コードが正しく保持されているため文字コード自体が
    壊れているわけではないことが判りました。

    2.QFontにの設定?
    QFontにSystemかFixedSysを設定すると文字化けしなくなることが判りました。
    QtCreatorでもオプションメニューからテキストエディタ-フォント&色タブのフォントを
    SystemかFixedSysに変更すればエディタでは文字化けしなくなります。(UI周りは変わりません)
    ただ、Systemフォントでは制約が非常に大きいため解決とは言えませんでした。

    3.フォントの上書き
    以下のサンプルコードを使って検証します。
    15行目のボタンテキストに外字を入力してみます。
    @#include <QtGui>

    int main(int argc, char *argv[])
    {
    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
    QTextCodec::setCodecForTr(QTextCodec::codecForLocale());

     QApplication app(argc, argv);
     QApplication::setFont(QFont("System"));
    
     QWidget window;
     window.resize(320, 240);
     window.show();
     QPushButton *button = new QPushButton(
         QApplication::translate("childwidget", "日本語←0xF40"), &window);
     button->move(100, 100);
    
     int fontsize = 11;
     //int fontsize = 9;
     //int fontsize = 16;
     //int fontsize = 24;
     button->setFont(QFont("MS UI Gothic", fontsize));
     button->show();
     return app.exec();
    

    }@

    一旦Systemフォントに設定すればフォントを上書きしても文字化けしないことは確認できました。
    ただし、外字だけはSystemフォントのまま表示されてしまいます。
    私も詳しくは知らないのですが、Systemフォントは特定のフォントサイズにしか対応しておらず
    最小が11ptとなっているようです。
    fontsizeを設定している部分を変更してみて頂ければ確認できます。

    なんとか外字の文字化けは回避できたと思いますが、
    可能であればフォント指定が有効になるようにしたいと考えております。
    何かお気づきの点があれば教えて頂けると助かります。

    よろしくお願いいたします。

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Atsushi4
      wrote on last edited by
      #2

      うーん,分からない。。。
      日本語全体がsystemフォント固定になってるみたいですね。

      一応自分の確認コード
      (コンパイルエラーが出たらqmakeして下さい)

      @
      #include <QtGui>

      class MainWindow : public QDialog
      {
      Q_OBJECT
      public:
      MainWindow()
      {
      qApp->setFont(QFont("System"));
      QFontComboBox *f = new QFontComboBox;
      QSpinBox *s = new QSpinBox;
      setLayout(new QVBoxLayout);
      layout()->addWidget(new QLineEdit("\ue000 <- 外字"));
      layout()->addWidget(f);
      layout()->addWidget(s);
      s->setValue(11);

          connect(f, SIGNAL(currentFontChanged(QFont)), SLOT(fontSelected(QFont)));
          connect(s, SIGNAL(valueChanged(int)), SLOT(sizeSelected(int)));
      }
      

      public slots:
      void fontSelected(const QFont &f)
      {
      QFont ff(f);
      ff.setPointSize(font().pointSize());
      setFont(ff);
      }
      void sizeSelected(int size)
      {
      QFont f = font();
      f.setPointSize(size);
      setFont(f);
      }
      };

      int main(int argc, char *argv[])
      {
      QApplication a(argc, argv);
      QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
      MainWindow w;
      w.show();
      return a.exec();
      }

      #include "main.moc"

      @

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Atsushi4
        wrote on last edited by
        #3

        違う。。。

        選択したフォントで文字が見つからなければ
        qAppのフォント(System)で表示してるんですかね。。。

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Atsushi4
          wrote on last edited by
          #4

          選択したフォントで文字が見つからないと
          parentを辿って表示できるフォントが有れば使用する,というロジックらしい。

          根本的な解決になりませんが
          "System" の代わりに "Terminal" を使うと
          "System" よりは細かくサイズ指定できそうです。

          1 Reply Last reply
          0
          • T Offline
            T Offline
            t-ozaki
            wrote on last edited by
            #5

            ご回答ありがとうございます。

            確かにSystemよりもサイズ指定できることを確認できました!
            Systemが11,24...
            Terminalは6,11,17...

            残念なことに6ptだとかなり小さくなりますね。
            Terminalだと横長のフォントになってしまうのも痛いです。

            parentを辿って表示できるフォントが有れば使用する,というロジックらしい。
            具体的にソースコードの場所を教えて頂けると大変助かります。
            よろしくお願いします。

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Atsushi4
              wrote on last edited by
              #6

              ごめんなさい,ソースコードを追ったわけではなくて
              実際の動作とドキュメントからです(;´∀`)

              QApplicationに"System",
              MainWindowに"MS UI Gothic",
              QLineEditに日本語非対応フォント
              みたいな事をしてみました。

              QFont::NoFontMerging のドキュメントに
              ちょっと説明らしきものが有りました。

              1 Reply Last reply
              0
              • T Offline
                T Offline
                t-ozaki
                wrote on last edited by
                #7

                情報ありがとうございます。

                昨日の頂いた情報で、何処かの判定が間違っていて
                Systemに戻されてしまうのであれば強制的にフラグを書き替えたら
                直るのではないかと妄想しておりました。
                まさにQFont::NoFontMergingがそのスイッチにあたりますね。

                ドキュメントを読ませていただき
                QFont::NoFontMerging指定をしてみましたが
                指定したフォントで正しく文字化けに戻るだけですね(当たり前ですが)

                ギギギ…

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  t-ozaki
                  wrote on last edited by
                  #8

                  新たな問題が発覚しました。
                  SystemやFixedSys、-Terminal-フォントに指定すると
                  全角の数字「1」が文字化けし始めます。

                  上記の私が書いたサンプルソースで
                  15行目のテキストを"全角1"とし
                  22行目のsetFontをコメントすると文字化けすることが確認できます。

                  Qtのソースも見てみたのですがお手上げです
                  恐らくこのあたりだと思うのですが…
                  /src/gui/text/qfontengine_win.cpp
                  /src/gui/text/qfontdatabase_win.cpp

                  2012/04/24 20:17 追記です

                  これで文字化けするのはXp端末で、
                  Vistaや7では文字化けしませんでした。

                  2012/04/25 18:39 追記です

                  記載に誤りがありました。
                  Terminalでは化けませんでした。

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved