Qt Widgetsでハイパーリンクをもっと自由に!QLabel::openExternalLinksの使い方と応用例


QLabel::openExternalLinks は、QLabel ウィジェット内のテキストに含まれるハイパーリンクを自動的に開くかどうかを制御するプロパティです。デフォルトでは false に設定されており、リンクがクリックされたときに linkActivated() 信号が発行されます。このプロパティを true に設定すると、リンクがクリックされたときに linkActivated() 信号が発行されなくなり、代わりに QDesktopServices::openUrl() 関数を使用してリンクが自動的に開かれます。

利点

  • アプリケーション内で Web ブラウザを起動する必要がなくなり、コードが簡潔になります。
  • ユーザーが手動でリンクをクリックする必要がなくなり、操作が簡素化されます。

QLabel label;
label.setText("<a href=\"https://www.example.com\">Example Link</a>");
label.setOpenExternalLinks(true);

この例では、label ウィジェット内のテキストに "Example Link" というハイパーリンクが設定されています。setOpenExternalLinks(true) を呼び出すことで、このリンクがクリックされたときに自動的に開かれるようになります。

  • ユーザーがリンクの開くことを許可するかどうかの確認ダイアログを表示するかどうかを制御するには、QDesktopServices::setOpenUrlConfirmationDialog 関数を使用できます。
  • このプロパティは、HTML 形式のテキストのみをサポートします。プレーン テキスト形式のテキストには適用されません。
  • QLabel::openExternalLinks を使用すると、linkActivated() 信号が発行されなくなります。この信号を使用する必要がある場合は、このプロパティを false に設定する必要があります。
  • このプロパティは、QLabel ウィジェットだけでなく、QTextBrowserQTextEdit などの他のテキスト表示ウィジェットでも使用できます。
  • QLabel::openExternalLinks プロパティは、Qt Widgets 5.14 以降で使用できます。


例 1: 基本的な使用方法

#include <QApplication>
#include <QLabel>

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

  QLabel label;
  label.setText("<a href=\"https://www.example.com\">Example Link</a>");
  label.setOpenExternalLinks(true);
  label.show();

  return app.exec();
}
  1. QApplication オブジェクトを作成します。
  2. QLabel ウィジェットを作成し、テキストに "Example Link" というハイパーリンクを設定します。
  3. setOpenExternalLinks(true) を呼び出して、リンクがクリックされたときに自動的に開かれるようにします。
  4. ウィジェットを表示します。
  5. アプリケーションを実行します。

例 2: リンクの開くことを確認するダイアログを表示する

#include <QApplication>
#include <QLabel>
#include <QDesktopServices>

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

  QLabel label;
  label.setText("<a href=\"https://www.example.com\">Example Link</a>");
  label.setOpenExternalLinks(false);

  QObject::connect(&label, &QLabel::linkActivated, [](const QString &url) {
    if (QDesktopServices::openUrlConfirmationDialog(nullptr, "Open Link", url)) {
      QDesktopServices::openUrl(url);
    }
  });

  label.show();

  return app.exec();
}

この例では、以下の操作を行います。

  1. 例 1 と同様に、QLabel ウィジェットを作成し、テキストに "Example Link" というハイパーリンクを設定します。
  2. setOpenExternalLinks(false) を呼び出して、linkActivated() 信号を発行するようにします。
  3. linkActivated() 信号を QObject::connect() を使用してスロットに接続します。
  4. スロット内で、QDesktopServices::openUrlConfirmationDialog() 関数を使用して、リンクの開くことを確認するダイアログを表示します。
  5. ユーザーがダイアログで "Yes" を選択した場合、QDesktopServices::openUrl() 関数を使用してリンクを開きます。

この例では、QLabel::openExternalLinks プロパティを使用せずに、linkActivated() 信号を使用してリンクの開くことを確認するダイアログを表示する方法を示しています。

#include <QApplication>
#include <QLabel>
#include <QRegularExpression>

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

  QLabel label;
  label.setText("Visit our website at <a href=\"https://www.example.com\">Example Website</a> or contact us at <a href=\"mailto:[email protected]\">[email protected]</a>.");
  label.setOpenExternalLinks(true);

  label.show();

  return app.exec();
}
  1. 複数のハイパーリンクを含むテキストを QLabel ウィジェットに設定します。
  2. setOpenExternalLinks(true) を呼び出して、すべてのリンクがクリックされたときに自動的に開かれるようにします。


代替方法

  • カスタムリンク処理を実装する
    独自のロジックを使用して、リンクのクリックを処理し、必要なアクションを実行することができます。
  • QRegularExpression を使用する
    このクラスを使用して、テキスト内のハイパーリンクを検出し、QDesktopServices::openUrl() 関数を使用して開くことができます。
  • QTextBrowser または QTextEdit を使用する
    これらのウィジェットは、HTML 形式のテキストをレンダリングし、ハイパーリンクを自動的に開くことができます。

各方法の詳細

QTextBrowser または QTextEdit を使用する

#include <QApplication>
#include <QTextBrowser>

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

  QTextBrowser browser;
  browser.setOpenExternalLinks(true);
  browser.setHtml("<a href=\"https://www.example.com\">Example Link</a>");
  browser.show();

  return app.exec();
}

QRegularExpression を使用する

QRegularExpression クラスを使用して、テキスト内のハイパーリンクを検出できます。検出されたリンクは、QDesktopServices::openUrl() 関数を使用して開くことができます。

#include <QApplication>
#include <QLabel>
#include <QRegularExpression>

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

  QLabel label;
  label.setText("Visit our website at <a href=\"https://www.example.com\">Example Website</a> or contact us at <a href=\"mailto:[email protected]\">[email protected]</a>.");

  QRegularExpression regex("<a href=\"(.*?)\">");
  QRegularExpressionMatchIterator it = regex.globalMatch(label.text());

  while (it.hasNext()) {
    QRegularExpressionMatch match = it.next();
    QString url = match.captured(1);
    QDesktopServices::openUrl(url);
  }

  label.show();

  return app.exec();
}

カスタムリンク処理を実装する

独自のロジックを使用して、リンクのクリックを処理し、必要なアクションを実行することができます。たとえば、リンクを別のウィジェットで表示したり、データベースに保存したりすることができます。

#include <QApplication>
#include <QLabel>
#include <QMouseEvent>

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

  QLabel label;
  label.setText("Visit our website at <a href=\"https://www.example.com\">Example Website</a> or contact us at <a href=\"mailto:[email protected]\">[email protected]</a>.");

  label.installEventFilter(&label);

  label.show();

  return app.exec();
}

bool QLabel::eventFilter(QEvent *event) {
  if (event->type() == QEvent::MouseButtonPress) {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

    QRegularExpression regex("<a href=\"(.*?)\">");
    QRegularExpressionMatchIterator it = regex.globalMatch(text());

    while (it.hasNext()) {
      QRegularExpressionMatch match = it.next();
      QString url = match.captured(1);

      if (mouseEvent.pos() >= match.capturedStart(0) && mouseEvent.pos() <= match.capturedEnd(0)) {
        // リンクをクリックした処理
        QDesktopServices::openUrl(url);
        return true;
      }
    }
  }

  return QObject::eventFilter(event);
}