Qt GUIプログラミング: 選択範囲操作をレベルアップさせる QTextCursor::hasSelection()の使い方


QTextCursor::hasSelection()は、Qt GUIにおけるテキスト編集において重要な役割を果たす関数です。この関数は、テキストカーソルが現在選択範囲を持っているかどうかを判断し、その結果を真偽値として返します。選択範囲とは、カーソル位置とアンカー位置の間にあるテキスト部分のことを指します。

使い方

QTextCursor::hasSelection()関数は、テキストカーソルオブジェクトに対して呼び出されます。この関数は、以下のいずれかの方法で使用できます。

  • メンバ関数として直接呼び出す:
QTextCursor cursor = myTextEdit->textCursor();
bool hasSelection = cursor.hasSelection();
  • if ステートメント内で条件として使用する:
QTextCursor cursor = myTextEdit->textCursor();
if (cursor.hasSelection()) {
  // 選択範囲がある場合の処理
} else {
  // 選択範囲がない場合の処理
}

返り値

  • 選択範囲がない場合はfalseを返します。
  • 選択範囲がある場合はtrueを返します。

以下のコードは、テキストエディタ内の選択範囲の有無を判断し、選択範囲がある場合はその内容をコンソールに出力する例です。

QTextEdit *textEdit = new QTextEdit;
textEdit->setText("This is some text.");

QTextCursor cursor = textEdit->textCursor();
cursor.setPosition(5, 0);
cursor.setSelectionAnchor(0, 0);

if (cursor.hasSelection()) {
  QString selectedText = cursor.selectedText();
  qDebug() << "Selected text:" << selectedText;
} else {
  qDebug() << "No selection.";
}

このコードを実行すると、以下の出力がコンソールに表示されます。

Selected text: This is some
  • テキストドキュメント内に複数のカーソルが存在する場合は、QTextCursor::hasSelection()関数は現在アクティブなカーソルの選択範囲のみを判断します。
  • QTextCursor::hasSelection()関数は、カーソル位置とアンカー位置の相対的な位置関係のみを判断します。カーソル位置とアンカー位置が同じであっても、選択範囲が存在するとみなされます。


例1: 選択範囲の有無を判定し、メッセージボックスを表示

この例では、テキストエディタ内の選択範囲の有無を判定し、選択範囲がある場合はその内容をメッセージボックスに表示します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QMessageBox>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QTextEdit *textEdit = new QTextEdit;
  textEdit->setText("This is some text.");
  textEdit->show();

  QObject::connect(textEdit, &QTextEdit::cursorPositionChanged,
                   &app, [&]() {
                     QTextCursor cursor = textEdit->textCursor();
                     if (cursor.hasSelection()) {
                       QString selectedText = cursor.selectedText();
                       QMessageBox::information(textEdit, "Selection",
                                               "Selected text:\n" + selectedText);
                     }
                   });

  return app.exec();
}

例2: 選択範囲を削除

この例では、テキストエディタ内の選択範囲を削除します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QTextEdit>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QTextEdit *textEdit = new QTextEdit;
  textEdit->setText("This is some text.");
  textEdit->show();

  QObject::connect(textEdit, &QTextEdit::cursorPositionChanged,
                   &app, [&]() {
                     QTextCursor cursor = textEdit->textCursor();
                     if (cursor.hasSelection()) {
                       cursor.removeSelectedText();
                     }
                   });

  return app.exec();
}

例3: 選択範囲をコピーしてクリップボードに保存

この例では、テキストエディタ内の選択範囲をコピーしてクリップボードに保存します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QTextEdit>
#include <QClipboard>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QTextEdit *textEdit = new QTextEdit;
  textEdit->setText("This is some text.");
  textEdit->show();

  QObject::connect(textEdit, &QTextEdit::cursorPositionChanged,
                   &app, [&]() {
                     QTextCursor cursor = textEdit->textCursor();
                     if (cursor.hasSelection()) {
                       QString selectedText = cursor.selectedText();
                       QClipboard *clipboard = QApplication::clipboard();
                       clipboard->setText(selectedText);
                     }
                   });

  return app.exec();
}

上記の例では、カーソル位置変更シグナル(cursorPositionChanged)を使用して、選択範囲の変更を検出しています。これは、選択範囲が変更されるたびにQTextCursor::hasSelection()関数を呼び出す最も簡単な方法です。



QTextSelection クラスを使用する

QTextSelectionクラスは、選択範囲を表すオブジェクトです。このクラスには、選択範囲の開始位置と終了位置、選択範囲の長さ、選択範囲の内容などに関する情報が含まれています。

QTextSelectionクラスを使用して、選択範囲の有無を判断するには、以下の手順を実行します。

  1. QTextCursorオブジェクトを使用して、選択範囲を取得します。
  2. 取得した選択範囲オブジェクトをQTextSelectionオブジェクトに変換します。
  3. QTextSelectionオブジェクトのisEmpty()メンバ関数を呼び出して、選択範囲が空かどうかを判断します。
QTextCursor cursor = myTextEdit->textCursor();
QTextSelection selection = cursor.selection();

if (!selection.isEmpty()) {
  // 選択範囲がある場合の処理
} else {
  // 選択範囲がない場合の処理
}

QTextBlock クラスを使用する

QTextBlockクラスは、テキストブロックを表すオブジェクトです。テキストブロックとは、改行文字で区切られた一連のテキストのことです。

QTextBlockクラスを使用して、選択範囲の有無を判断するには、以下の手順を実行します。

  1. QTextCursorオブジェクトを使用して、カーソル位置に対応するテキストブロックを取得します。
  2. 取得したテキストブロックオブジェクトのisSelected()メンバ関数を呼び出して、テキストブロックが選択されているかどうかを判断します。
QTextCursor cursor = myTextEdit->textCursor();
QTextBlock block = cursor.block();

if (block.isSelected()) {
  // テキストブロックが選択されている場合の処理
} else {
  // テキストブロックが選択されていない場合の処理
}

独自のロジックを実装する

上記の方法以外にも、独自のロジックを実装して選択範囲の有無を判断することもできます。例えば、以下の方法が考えられます。

  • テキストドキュメントの内部構造を直接操作する
  • 選択範囲フラグをチェックする
  • カーソル位置とアンカー位置を比較する