如何在QTextBrowser中显示可点击的超链接

时间:2020-02-24 14:25:27

标签: python pyqt pyqt5 qtextbrowser

我创建了一个GUI,您可以在其中输入内容,然后在搜索栏中直接进入duckduckgo并搜索输入的元素,然后将所有超链接打印在QTextBrowser中。但是链接不可单击。我不知道如何使其可点击。如果你们能帮助我,我将不胜感激。 主要功能是input_value,我在其中编写了后端过程。这是我的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtCore import QAbstractTableModel, Qt
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import pyautogui


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(875, 648)
        MainWindow.setAutoFillBackground(False)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.searchforpoi = QtWidgets.QPushButton(self.centralwidget)
        self.searchforpoi.setGeometry(QtCore.QRect(730, 20, 111, 34))
        self.searchforpoi.setObjectName("searchforpoi")
        self.searchforpoi.clicked.connect(self.input_value)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 20, 691, 31))
        self.lineEdit.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.lineEdit.setObjectName("lineEdit")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(25, 71, 821, 551))
        self.textBrowser.setObjectName("textBrowser")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "POI Updation app"))
        self.searchforpoi.setText(_translate("MainWindow", "Search for POI"))

    def input_value(self):
        options = webdriver.ChromeOptions()
        options.headless = True
        textboxValue = self.lineEdit.text()
        browser = webdriver.Chrome()
        browser.implicitly_wait(30)
        browser.maximize_window()

        browser.get("http://www.duckduckgo.com")
        elem = browser.find_element_by_name("q")
        elem.clear()

        elem.send_keys(textboxValue)
        elem.submit()

        lists = browser.find_elements_by_class_name("result__url__domain")

        for a in browser.find_elements_by_xpath('.//a'):
            ab = a.get_attribute('href')
            self.textBrowser.append(ab)

        browser.quit()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

编辑:-单击链接时,它将打开默认的Web浏览器,并且QTextBrowser应该保留所有其他链接。

1 个答案:

答案 0 :(得分:2)

消耗大量时间的任务必须在辅助线程中执行,并通过信号发送信息,另一方面,将url作为文本传递不会使其可点击,您应该做的是使用“ href” 。为了不更改页面,QTextBrowser(未删除链接)必须将属性OpenLinks打开为False。要在OS默认浏览器中打开url,则必须使用QDesktopServices.openUrl()

import threading

from PyQt5 import QtCore, QtGui, QtWidgets

from selenium import webdriver
from selenium.webdriver.common.keys import Keys


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(875, 648)
        MainWindow.setAutoFillBackground(False)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.searchforpoi = QtWidgets.QPushButton(self.centralwidget)
        self.searchforpoi.setGeometry(QtCore.QRect(730, 20, 111, 34))
        self.searchforpoi.setObjectName("searchforpoi")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(20, 20, 691, 31))
        self.lineEdit.setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.lineEdit.setObjectName("lineEdit")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(25, 71, 821, 551))
        self.textBrowser.setObjectName("textBrowser")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "POI Updation app"))
        self.searchforpoi.setText(_translate("MainWindow", "Search for POI"))


class DriverWorker(QtCore.QObject):
    urlsSignals = QtCore.pyqtSignal(list)

    def get_urls(self, text):
        threading.Thread(target=self._task, args=(text,), daemon=True).start()

    def _task(self, text):
        options = webdriver.ChromeOptions()
        options.headless = True
        browser = webdriver.Chrome()
        browser.implicitly_wait(30)
        browser.maximize_window()

        browser.get("http://www.duckduckgo.com")
        elem = browser.find_element_by_name("q")
        elem.clear()

        elem.send_keys(text)
        elem.submit()

        lists = browser.find_elements_by_class_name("result__url__domain")

        urls = []
        for a in browser.find_elements_by_xpath(".//a"):
            ab = a.get_attribute("href")
            urls.append(ab)
        self.urlsSignals.emit(urls)
        browser.quit()


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.searchforpoi.clicked.connect(self.input_value)
        self.worker = DriverWorker()
        self.worker.urlsSignals.connect(self.on_urls)
        self.textBrowser.anchorClicked.connect(QtGui.QDesktopServices.openUrl)
        self.textBrowser.setOpenLinks(False)

    @QtCore.pyqtSlot()
    def input_value(self):
        textboxValue = self.lineEdit.text()
        self.worker.get_urls(textboxValue)

    @QtCore.pyqtSlot(list)
    def on_urls(self, urls):
        self.textBrowser.clear()
        for url in urls:
            html = """<a href="{url}">{url}</a>""".format(url=url)
            self.textBrowser.append(html)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())