Qt GUI テキスト編集:痒いところに手が届く!QTextCursor::selectionStart() の活用術


QTextCursor::selectionStart() は、Qt GUI におけるテキスト編集において、選択範囲の開始位置を取得するための重要なメソッドです。このメソッドは、選択されたテキストの操作や分析、あるいはテキスト編集機能の拡張などに役立ちます。

メソッド解説

QTextCursor::selectionStart() は、現在のテキストカーソルが保持する選択範囲の開始位置を整数値として返します。選択範囲が存在しない場合は、無効な値が返されます。

コード例

QTextCursor cursor = textEdit->textCursor();
int start = cursor.selectionStart();

if (start != -1) {
  // 選択範囲が存在する
  // start を利用して処理を行う
} else {
  // 選択範囲が存在しない
}
  • 選択範囲を操作するには、QTextCursor::setSelection() メソッドを用います。
  • QTextCursor::hasSelection() メソッドを用いることで、選択範囲が存在するかどうかを確認できます。
  • QTextCursor::selectionEnd() メソッドを用いることで、選択範囲の終了位置を取得できます。
  • 選択されたテキストを検索する
  • 選択されたテキストを別の場所にコピーする
  • 選択されたテキストを削除する
  • 選択されたテキストを太字にする


void makeSelectionBold() {
  QTextCursor cursor = textEdit->textCursor();
  int start = cursor.selectionStart();
  int end = cursor.selectionEnd();

  if (start != -1 && end != -1) {
    QTextCharFormat format = cursor.charFormat();
    format.setFontWeight(QFont::Bold);
    cursor.mergeCharFormat(format);
  }
}

サンプル 2: 選択されたテキストを削除する

void deleteSelection() {
  QTextCursor cursor = textEdit->textCursor();
  int start = cursor.selectionStart();
  int end = cursor.selectionEnd();

  if (start != -1 && end != -1) {
    cursor.movePosition(QTextCursor::StartOfSelection);
    cursor.deleteSelection();
  }
}

サンプル 3: 選択されたテキストを別の場所にコピーする

void copySelectionToClipboard() {
  QTextCursor cursor = textEdit->textCursor();
  int start = cursor.selectionStart();
  int end = cursor.selectionEnd();

  if (start != -1 && end != -1) {
    QClipboard *clipboard = QApplication::clipboard();
    clipboard->setText(cursor.selectedText());
  }
}

サンプル 4: 選択されたテキストを検索する

void findSelection() {
  QTextCursor cursor = textEdit->textCursor();
  int start = cursor.selectionStart();
  int end = cursor.selectionEnd();

  if (start != -1 && end != -1) {
    QString textToFind = cursor.selectedText();
    bool found = textEdit->find(textToFind, QTextEditor::BackwardSearch);
    if (!found) {
      found = textEdit->find(textToFind, QTextEditor::ForwardSearch);
    }
  }
}
  • サンプル 4 では、選択されたテキストを検索する処理を行っています。
  • サンプル 3 では、選択されたテキストをクリップボードにコピーする処理を行っています。
  • サンプル 2 では、選択されたテキストを削除する処理を行っています。
  • サンプル 1 では、選択されたテキストを太字にする処理を行っています。


QTextBlock::selectionStart()

QTextBlock::selectionStart() メソッドは、選択範囲を含むテキストブロックの開始位置を取得します。このメソッドは、選択範囲が複数のブロックにまたがっている場合に役立ちます。

QTextBlock block = cursor.currentBlock();
int start = block.selectionStart();

QTextDocument::findBlockByLineNumber() と QTextBlock::selectionStart()

QTextDocument::findBlockByLineNumber() メソッドと QTextBlock::selectionStart() メソッドを組み合わせることで、行番号に基づいて選択範囲の開始位置を取得することができます。

int lineNumber = 10; // 行番号
QTextBlock block = document->findBlockByLineNumber(lineNumber);
int start = block.selectionStart();

イテレータを用いた選択範囲の解析

QTextCursor::selectionStart() メソッドを使用せずに、イテレータを用いて選択範囲を解析することも可能です。この方法は、より柔軟な処理が可能ですが、複雑さも増します。

QTextCursor cursor = textEdit->textCursor();
QTextSelection sel = cursor.selection();

for (QTextBlock block : sel.blocks()) {
  for (QTextFragment fragment : block.fragments()) {
    if (fragment.range().contains(sel.start())) {
      int start = fragment.range().start();
      // 処理を行う
    }
  }
}

選択方法

上記で紹介した代替方法は、それぞれ異なる状況で役立ちます。

  • より柔軟な処理が必要な場合は、イテレータを用いた選択範囲の解析を検討します。
  • 行番号に基づいて選択範囲の開始位置を取得したい場合は、QTextDocument::findBlockByLineNumber()QTextBlock::selectionStart() を組み合わせます。
  • 選択範囲が複数のブロックにまたがっている場合は、QTextBlock::selectionStart() が適切です。
  • 選択範囲が単一のブロックに収まっている場合は、QTextCursor::selectionStart() が最もシンプルで効率的な方法です。