Qt GUIアクセシビリティのヒント:QAccessibleTextRemoveEvent::textRemoved()でできること、できないこと


QAccessibleTextRemoveEvent::textRemoved()は、Qt GUIにおけるアクセシビリティ機能の一部であり、テキスト編集可能なウィジェットからテキストが削除された際に発生するイベントを通知します。このイベントは、スクリーンリーダーなどの補助技術が、テキスト編集操作をユーザーに伝えるために使用されます。

イベント情報

QAccessibleTextRemoveEventオブジェクトには、削除されたテキストに関する以下の情報が含まれています。

  • 削除されたテキスト
    削除されたテキストを表すQStringオブジェクト。
  • 削除位置
    削除されたテキストの先頭の位置を表す整数値。

イベントの処理

QAccessibleTextRemoveEventを受信した補助技術は、以下の処理を行うことができます。

  • 削除操作を取り消せるかどうかをユーザーに伝える。
  • 削除操作によって編集対象がどのように変化したかをユーザーに伝える。
  • 削除されたテキストをユーザーに読み上げる。

コード例

void MyWidget::textRemoved(int position, const QString &text)
{
    // 削除されたテキストをログに出力する
    qDebug() << "Text removed from position" << position << ":" << text;

    // スクリーンリーダーにイベントを通知する
    QAccessibleInterface *iface = accessibleInterface();
    if (iface) {
        QAccessibleTextRemoveEvent event(iface, position, text);
        QApplication::sendEvent(iface, &event);
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QAccessibleTextRemoveEventオブジェクトを作成して、スクリーンリーダーに送信しています。

  • QAccessibleTextRemoveEvent::textRemoved()は、テキスト編集操作だけでなく、テキスト挿入操作によっても発生します。


例1: 削除されたテキストをログに出力する

void MyWidget::textRemoved(int position, const QString &text)
{
    // 削除されたテキストをログに出力する
    qDebug() << "Text removed from position" << position << ":" << text;
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、削除されたテキストを単にログに出力しています。

例2: スクリーンリーダーにイベントを通知する

void MyWidget::textRemoved(int position, const QString &text)
{
    // スクリーンリーダーにイベントを通知する
    QAccessibleInterface *iface = accessibleInterface();
    if (iface) {
        QAccessibleTextRemoveEvent event(iface, position, text);
        QApplication::sendEvent(iface, &event);
    }
}

例3: 削除されたテキストをユーザーに読み上げる

void MyWidget::textRemoved(int position, const QString &text)
{
    // スクリーンリーダーにイベントを通知する
    QAccessibleInterface *iface = accessibleInterface();
    if (iface) {
        QAccessibleTextRemoveEvent event(iface, position, text);
        QApplication::sendEvent(iface, &event);

        // 削除されたテキストをユーザーに読み上げる
        QScreenReader *reader = QApplication::screenReader();
        if (reader) {
            reader->speak(text);
        }
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QAccessibleTextRemoveEventオブジェクトを作成して、スクリーンリーダーに送信し、さらに、削除されたテキストをユーザーに読み上げています。

例4: 削除操作によって編集対象がどのように変化したかをユーザーに伝える

void MyWidget::textRemoved(int position, const QString &text)
{
    // スクリーンリーダーにイベントを通知する
    QAccessibleInterface *iface = accessibleInterface();
    if (iface) {
        QAccessibleTextRemoveEvent event(iface, position, text);
        QApplication::sendEvent(iface, &event);

        // 削除操作によって編集対象がどのように変化したかをユーザーに伝える
        QScreenReader *reader = QApplication::screenReader();
        if (reader) {
            reader->announceStateChange(QAccessibleStateChange::TextRemoved);
        }
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QAccessibleTextRemoveEventオブジェクトを作成して、スクリーンリーダーに送信し、さらに、削除操作によって編集対象がどのように変化したかをユーザーに伝えています。

例5: 削除操作を取り消せるかどうかをユーザーに伝える

void MyWidget::textRemoved(int position, const QString &text)
{
    // スクリーンリーダーにイベントを通知する
    QAccessibleInterface *iface = accessibleInterface();
    if (iface) {
        QAccessibleTextRemoveEvent event(iface, position, text);
        QApplication::sendEvent(iface, &event);

        // 削除操作を取り消せるかどうかをユーザーに伝える
        QScreenReader *reader = QApplication::screenReader();
        if (reader) {
            reader->announceStateChange(QAccessibleStateChange::TextRemoved);

            // 削除操作を取り消せるかどうかを確認する
            if (canUndo()) {
                reader->announce(QAccessibleAction::Undo);
            }
        }
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QAccessibleTextRemoveEventオブジェクトを作成して、スクリーンリーダーに送信し、さらに、削除操作によって編集対象がどのように変化したかをユーザーに伝え、さらに、削除操作を取り消せるかどうかをユーザーに伝えています。



QAccessibleTextRemoveEvent::textRemoved()は、Qt GUIにおけるアクセシビリティ機能の一部であり、テキスト編集可能なウィジェットからテキストが削除された際に発生するイベントを通知します。しかし、このイベントにはいくつかの欠点があります。

  • 削除操作によって編集対象がどのように変化したかについての詳細な情報が提供されない。
  • 削除されたテキストの位置情報しか提供されないため、削除されたテキストの内容を直接取得できない。

これらの欠点を補うために、以下の代替方法を検討することができます。

QTextDocument::contentsChanged()シグナルを使用する

QTextDocumentクラスのcontentsChanged()シグナルは、ドキュメントの内容が変更された際に発生するシグナルです。このシグナルは、テキストが削除された場合にも発生します。

void MyWidget::textRemoved(const QTextDocument *document)
{
    QTextDocument::UndoRedoChange change = document->undoRedoChange();
    if (change.type() == QTextDocument::UndoRedoChange::RemoveText) {
        // 削除されたテキストを取得する
        QTextCursor cursor = change.from();
        QString removedText = cursor.selectedText();

        // 削除されたテキストの位置を取得する
        int position = cursor.position();

        // スクリーンリーダーにイベントを通知する
        QAccessibleInterface *iface = accessibleInterface();
        if (iface) {
            QAccessibleTextRemoveEvent event(iface, position, removedText);
            QApplication::sendEvent(iface, &event);
        }
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QTextDocumentクラスのcontentsChanged()シグナルを接続し、削除されたテキストと位置情報を取得して、スクリーンリーダーにイベントを送信しています。

QPlainTextEdit::undoRedoStack()を使用する

QPlainTextEditクラスのundoRedoStack()メソッドは、編集操作履歴を取得するためのメソッドです。このメソッドを使用して、削除されたテキストの内容と位置情報を取得することができます。

void MyWidget::textRemoved(const QPlainTextEdit *editor)
{
    QUndoStack *undoStack = editor->undoRedoStack();
    if (undoStack->canUndo()) {
        QUndoCommand *command = undoStack->currentCommand();
        if (command->type() == QTextEdit::UndoCommand::RemoveText) {
            // 削除されたテキストを取得する
            QString removedText = command->text();

            // 削除されたテキストの位置を取得する
            int position = command->position();

            // スクリーンリーダーにイベントを通知する
            QAccessibleInterface *iface = accessibleInterface();
            if (iface) {
                QAccessibleTextRemoveEvent event(iface, position, removedText);
                QApplication::sendEvent(iface, &event);
            }
        }
    }
}

このコード例では、MyWidgetクラスのtextRemoved()メソッドが、QPlainTextEditクラスのundoRedoStack()メソッドを使用して、削除されたテキストと位置情報を取得して、スクリーンリーダーにイベントを送信しています。

class MyTextRemovedEvent : public QEvent
{
public:
    MyTextRemovedEvent(int position, const QString &text)
        : QEvent(Type)
        , position(position)
        , text(text)
    {}

    int position;
    QString text;
};

void MyWidget::textRemoved(int position, const QString &text)
{
    // カスタムイベントを作成して送信する
    MyTextRemovedEvent event(position, text);
    QCoreApplication::instance()->sendEvent(this, &event);
}

void MyWidget::customEvent(QEvent *event)
{
    if (event->type() == MyTextRemovedEvent::Type) {
        MyTextRemovedEvent *myEvent = static_cast<MyTextRemovedEvent *>(event);

        // 削除されたテキストを取得する
        QString removedText = myEvent->text;

        // 削除されたテキストの位置を取得する
        int position = myEvent->position;

        // スクリーンリーダーにイベントを通知する
        QAccessibleInterface *iface = accessibleInterface();
        if (iface) {
            QAccessibleTextRemoveEvent event(iface, position, removedText);
            QApplication::sendEvent(iface