見出し画像

QTextListというクラスについて語る

 はい。このページは需要がない中でもさらに需要がありません。自信があります。
Noteをやっていてダッシュボードからわかる人数を見てみますと、QtあるいはPySideについて閲覧者は、せいぜい100人程度。
 どれだけ駄目な文章でもちょっとだけ見てみようかな・・・という人が中に含まれていると思いますから、せいぜい100人程度です。ありがとうございます!この方達には感謝いたします!
 日本全国のQtユーザーが皆noteを知っているとは限らないので、大きくサバ読んで200人程度しか日本にQtユーザーはいないのでは!?Qtについてネットで調べると、私の投稿がおそらくヒットすることもあるんじゃないかな。Noteに直接こなくても!そういう人たちを呼び込めるようになるといいですね。Stack Over Flow日本版のサイトをたまに見るのですが、多分アクティブな人は5人もいない。
 Teratailの方にも少しいるくらい。
 で、QTextListのクラスについてのトピックなんて書くのは私が恐らく初めてですよ!
 おそらく、知りたいと思っている少数の人の、知識需要は濃い一方、母集団が少ないので知識を書いても苦労の割に報われない・・・これはQt開発者が少なくなる可能性もありますね。良いライブラリなのになぜこんなに数が少ないんだQt.

 こうなれば・・・世界挑戦だ。(口だけ。)

 変な前置きですが、QTextListについてです。

QTextListはQTextObjectというクラスを継承しています。QTextDocument内でリスト型の構造を導入できるものです。
ちょうど、Noteでいえば、

  • こういう感じですね。

 スタイルにもいくつかあり、● ○ ■ □ ちょっと大きさは違うのですが、こういうマーク。後は番号、アルファベット、そしてローマ数字です。

 これを最初に導入したときは、なんて扱いにくいクラスなんだと思いました。

リストフォーマットとブロックフォーマットは全く別物

 リストフォーマットにインデントをセットすることと、ブロックフォーマットにインデントをセットするのは全く違います。見た目は同じですが。
 これは割と簡単に気づきました。たしかにクラスが違う以上別の扱いであるのは仕方がないか。ただ、見た目全く一緒なので、別にどっちでもいい感じはしましたね。

素直に消えてくれない。

 バックスペースをしても、素直に消えてくれません。そのため、Backspaceのキーイベントをオーバーライドして、処理を書く必要があります。一旦setIndent(0)にしてから消さなければ、インデントはそのまま残ります。Qtのバージョンがアップしたからか、昔よりは素直に消えてくれるようになりました。昔は、消えないままずっと残ってしまうもので、下記のブロックリストの仕組みを知らなかったので、大変苦労しました。リストから外す必要があったのですね。

番号リストの場合は、自動で番号が切り替わってくれない。

 今でこそ解決してくれましたが、例えば、
 1.
 2.
 3.
とリストが並んでいたとして、
 1.
    1.
 2.
となったとします。
この1.をまた元に戻したい時、
 1.
 1.
 2.
になります。
 こういうときだけじゃありません。いろんなところで発生します。
たとえば、
 1.
    1.
    2.
としたくても、
 1.
    1.
    1.
になりますから。

とりあえず、どうして番号が切り替わらないのかという原因は、QTextListがQTextBlockGroupというクラスを継承しており、その中にあるブロックコンテナの中に、該当するブロックが含まれているか、含まれていないかによって、処理がわかれるからです。

 どういうことかといいますと、一番上の1のブロックと、その下の1のブロックは、別々のブロックコンテナに属しています。おそらく内部的に、ブロックコンテナを取り出し、シーケンス処理を行って、順番に番号をdrawしているのでしょう。
 ですから、タブやアンタブで場所を移動するたび、どのブロックコンテナにブロックを加えるか?ということの計算をしてあげなくてはなりません。
 これは少し苦労しました。

アンインデントの時は、引っ越しが大変。

例えば、
1.
  1.
  2.
とあるとき、この子としての1.をアンインデントしたいとします。
すると、普通なら
1.
1.
  2.
になっちゃうんですよね。これのどこが問題なのかというと、1.の下の2.は元々さらに上の1.の子だったわけです。ですから、その下の1.が単に左にずれるだけだと、2.はいつの間にか、別の親の子になってしまうわけです。つまり、
1.
  2.
1.
 となるようになってくれなければ、正確とは言えないわけですね。
 これだけではなくて、例えば、
1.
  1.
    1.
      1.
    2.
  2.
なんていう形で、1.にたくさんの子が付いている場合に、アンインデントを行ったとき、

1.
  2.
1.
  1.
    1.
  2.
となるようにしなくてはなりません。

もちろんこの時も、番号が自動で切り替わってくれることはありませんでした。○や□という無個性のノードであれば、何もしなくていいのですが・・・。
 よりやっかいなのが、イメージオブジェクトなどが間に存在している場合ですね。これについてもキャッチして、適切にお引越ししなければなりません。引っ越しはプログラミングの世界でも大変ですね。

すくない!

 多分日本で1~2人いればいいほうじゃないでしょうか。こういう情報を求めている人は。
ここまで人が少ないと、noteの書き方とかはもう無関係のレベルになっているように思います。やけのやんぱちひやけのなすびです。


 If we were more ambitious, we could provide the means for users to create lists and tables, and to insert hyperlinks and images. In fact, providing basic support for bulleted lists is extremely easy: we just call QTextEdit::setAutoFormatting(QTextEdit::AutoBulletList), and the user can start a bulleted list by inserting an "*"(asterisk) in the left margin. However, it takes more work to provide means of indenting and unindenting(to achieve nested lists), and for inserting and editing tables, and so on. All of these things are left as an exercise for those who want to dig more deeply into Qt's rich text engine.

Advanced Qt Programming [Creating Great Software with C++ and Qt 4] Mark Summerfield P358-2段落目

 「志があるのであれば、ユーザーにリストやテーブルを作る手段を与えることもできますし、ハイパーリンクやイメージを挿入する手段を与えることができます。事実、ノード付きリストの挿入は極めて簡単です。QTextEdit::setAutoFormatting(QTextEdit::AutoBulletList)を呼ぶだけです。ユーザーは左余白で*を挿入することによってノード付きリストからスタートすることができます。しかしながら、インデントとアンインデント(ネスト化されたリストを達成するには)、テーブルを挿入し、編集するには、より多くの作業がいります。これらの物事は全て、Qtのリッチテキストエンジンをより深く掘り下げたい人達のための試練として残されています。」

 試練一つクリアしちゃいましたね。この著者の方はQt創世記から関わっている方なのですが、何でもご存じだと思うのですが、そうではないみたい?
 この時からずいぶん時間がたっていますが、この時点の知識では私の方が詳しくなってしまっているようです。

 で、ここで新知識を発見。そうか。QTextEdit::setAutoFormatting(QTextEdit::AutoBulletList)を使っても何も起きないな…と思っていましたが、*を打つとリスト化されるのですね。でも、まだ●しか使えないご様子。リファレンスには将来もっと増やそうと思ってますって書いてありますね。

 で、もっと深く掘り下げていくと、このQTextListは、使わなくてよかったという悲しい結末になりました。別の手段で、もっと楽にリスト型を実装できるのです。答えはQGraphicsItem等の組み合わせですね。もちろんQGraphicsObjectでもいいですよ。2Dグラフィックスを利用したほうが、ノードとインタラクティブな作業ができますから、もっと柔軟なアプリになりますね。
 私の別記事でフローウィアプリケーションをご紹介していますが、あれがそうです。

 こうなれば私がQtの伝導師になってやる。活動費に寄付をお願いしますw 人がいない。寄付をしてくれるひともいない。どうやって活動費稼ごうかな。ええ。0円よりは1円。1円よりは5円です。10円で大喜びです。私はQtの神になる!(実力不問)お賽銭のために。








この記事が気に入ったらサポートをしてみませんか?