1

Qt5 を使用して単純なテキスト エディター プログラムに取り組んでいます。私のエディタ コンポーネントは のサブクラスであり、基本的な機能の一部については、この Qt デモ プログラムQPlainTextEditからいくつかのコードを盗用しました。互いに干渉しているように見える 2 つの機能は、エディターの現在の行を強調表示するコードです (デモが示すように、テキスト編集の信号に接続されています)。cursorPositionChanged()

QList<QTextEdit::ExtraSelection> es;
QTextEdit::ExtraSelection selection;

selection.format.setBackground(currentLineHighlight);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);

selection.cursor = textCursor();
selection.cursor.clearSelection();

es.append(selection);
setExtraSelections(es);

そして、非常に一般的な「複数の行を選択しているときにタブを押すと、すべての行をインデントする」ことを行うために私が書いたコード:

QTextCursor curs = textCursor();

if(!curs.hasSelection())
    return;

// Get the first and count of lines to indent.

int spos = curs.anchor(), epos = curs.position();

if(spos > epos)
{
    int hold = spos;
    spos = epos;
    epos = hold;
}

curs.setPosition(spos, QTextCursor::MoveAnchor);
int sblock = curs.block().blockNumber();

curs.setPosition(epos, QTextCursor::MoveAnchor);
int eblock = curs.block().blockNumber();

// Do the indent.

curs.setPosition(spos, QTextCursor::MoveAnchor);

curs.beginEditBlock();

for(int i = 0; i <= (eblock - sblock); ++i)
{
    curs.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);

    curs.insertText("\t");

    curs.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor);
}

curs.endEditBlock();

// Set our cursor's selection to span all of the involved lines.

curs.setPosition(spos, QTextCursor::MoveAnchor);
curs.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);

while(curs.block().blockNumber() < eblock)
{
    curs.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
}

curs.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);

setTextCursor(curs);

これらの機能はどちらもうまく機能します - 少なくともほとんどの場合。次のことを行うと、これら2つに関連する奇妙なバグがあるようです:

  1. 数行を選択してタブを押すと、期待どおりにすべてがインデントされます。
  2. その操作を元に戻します。

この時点で、インデントされた一連の行の最後の行で、行の強調表示は、通常のようにエディター全体に広がるのではなく、行の終わりまでしか広がりません。カーソルをその行の末尾に移動してから「Enter」を押すと、問題が解決します。

この問題を診断するために、ハイライト関数を呼び出すだけでなく、カーソルやアンカーを移動しようとしたり、エディターのドキュメントを構成する s をclearSelection()調べたり反復したりするなど、いくつかのことを試しました。QTextBlockいくつかの矛盾を見つけるために、しかし、この時点で私は途方に暮れています。このコードを期待どおりに動作させることはできません。

現在正しくレンダリングされていない行を「修正」できることを発見しましたが、その行に文字を追加するか、ウィンドウのサイズを変更します。

setTextCursorまた、インデント関数の最後の呼び出しを削除すると、このバグは引き続き発生します。

これら 2 つのことから、このバグはテキスト カーソルやドキュメントの内容とは何の関係もないと私は信じています。

誰かが私が間違っているところを見ていますか?

4

1 に答える 1

1

これは実際には Qt のバグであり、OP のコードの問題ではありません。QTBUG-30051 - QTextCursor と beginEditBlock がレイアウトを壊す を参照してください。

于 2014-01-21T16:44:06.417 に答える