4

コード領域のように動作するテキスト オブジェクト タイプ ( QTextObjectInterfaceを継承) を作成することに興味があります。

  • 特徴的な背景
  • 国境
  • 等幅フォント
  • 編集可能なコンテンツ
  • インスタンス内のコンテンツを抽出できるように、インスタンスをコードで識別できるようにする必要があります (周囲のコンテンツからコードを分離する)。
  • 保存/読み込み (通常の html ファイルから)
  • 構文の強調表示はプラスになりますが、実際には必須ではありません

ドキュメントの他の領域は、通常の方法で動作する必要があります (編集可能なフォント プロパティ、編集可能な色など)。


Qt は、 QTextEditでカスタム テキスト オブジェクトを実装する例を提供します。新しいテキスト オブジェクトは QTextEdit / QTextDocument内の既存のインフラストラクチャを利用できないため、これは難しい方法のように見えます。

QTextObject

QTextDocumentのパーツをグループ化できるさまざまな種類のオブジェクトの基本クラス

それを継承することは選択肢かもしれませんが、Qt SDK パッケージのソース ファイルも Google 検索も有用な情報を明らかにしませんでした。

QTextFrameはQTextObjectを継承しているため、このパスに関するヒントが見つかれば、実行可能な基本クラスになる可能性があります。


単純な HTML ファイルでは、これらすべて (構文の強調表示を除く) は簡単です。QTextEditは html を入力として受け取り、html をエクスポートできますが、その過程で構造が失われます。

<code class="code-sample">
  int i = 0;
</code>

ちなみに、 QWebViewは読み取り専用です。次のように宣伝しています。

HTML ドキュメントの一部は、たとえば HTML 要素の contenteditable 属性を介して編集可能にすることができます。


これがすぐに利用できるプラットフォームは他にもあるかもしれませんが、テキスト エディターはプラグインとして Qt Creator 内で使用する必要があるため、Qt フレームワークを使用することは理にかなっています。

結論: QTextEditウィジェットにコード領域を実装するにはどうすればよいでしょうか?


その後の編集:

  • トランクから Qt sdk を使用 (自身を 4.8.4 として識別)
  • トランクからの Qt Creator (Qt Creator 2.6.81)
4

1 に答える 1

5

QTextEdit / QTextDocument を使用してこれを実装できることがわかりました。私が考えることができる最も単純な実装は、将来のシーカーの参考のためにこの回答に示されています。

通常の .toHtml() では必要な情報が保持されないため、保存/読み込みをカスタマイズする必要があることに注意してください。

コード ブロックの挿入は簡単です。

QTextFrame * frame;

frame = cursor.insertFrame( code_block_format_ );
connect( frame, SIGNAL( destroyed() ),
  this, SLOT( codeBlockDeleted() ) );
code_blocks_.append( frame );

クラスに保存できる 2 つの変数に注意してください。

QTextFrameFormat code_block_format_;
QList<const QTextFrame*> code_blocks_;

フレームのフォーマットは、一貫性があり特徴的である必要があります。コンストラクターで次のように初期化する必要があります。

code_block_format_.setBackground( QBrush( Qt::yellow ) );
code_block_format_.setBorder( 1 );
code_block_format_.setBorderStyle( QTextFrameFormat::BorderStyle_Inset);
code_block_format_.setMargin( 10 );
code_block_format_.setPadding( 4 );

特定のフレームがコード ボックスであるかどうかを判断するには、リストが必要です。QTextObject を継承するすべてのオブジェクトは QTextDocument::createObject() で作成する必要があるため、単純に QTextFrame をサブクラス化することはできません (実際にはできると思いますが、まだわかりません)。

コード コンテンツを残りの部分から分離することは、通常の方法で行うことができます。

for ( it = frame->begin(); !(it.atEnd()); ++it ) {
  child_frame = it.currentFrame();
  child_block = it.currentBlock();
  if ( child_frame != NULL )
  {
    if ( code_blocks_.contains( frame ) )
    {
      /* ... */
    }
  }
} /* for ( it = frame->begin(); !(it.atEnd()); ++it ) */

ただし、これは簡潔にするために単純化しすぎていることに注意してください。ネストされたフレームを考慮する必要があります。

完全な実装に興味がある場合は、git リポジトリをチェックしてください(進行中、2012 年 11 月)。

于 2012-11-23T20:00:04.083 に答える