【问题标题】:How to display a clickable hyperlink in QTextBrowser如何在 QTextBrowser 中显示可点击的超链接
【发布时间】:2020-06-08 04:53:34
【问题描述】:

我创建了一个 GUI,您可以在其中输入内容,在搜索栏中,它直接进入 dadduckgo 并搜索输入的元素,然后在 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_())

编辑:- 当链接被点击时,它应该打开一个默认的网络浏览器并且 QTextBrowser 应该保留所有其他的链接。

【问题讨论】:

    标签: python pyqt pyqt5 qtextbrowser


    【解决方案1】:

    消耗大量时间的任务必须在辅助线程中执行并通过信号发送信息,另一方面,将url作为文本传递并不能使其可点击,你应该做的是使用“href” .为了不更改页面,QTextBrowser(未删除链接)必须将属性OpenLinks 设为 False。要在操作系统默认浏览器中打开 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_())
    

    【讨论】:

    • 谢谢你,虽然我可以看到可点击的链接,但是当我点击它们时,相应的链接没有打开,整个文本浏览器变成空白,我收到了这个QTextBrowser: No document for https://somelink.com/ PyQt5.QtCore.QUrl('https://somelink.com/')
    • @vesuvius 单击链接时您希望发生什么?在您的问题中,您只希望我的代码可以点击链接,然后我不知道点击链接时您想要发生什么。
    • 抱歉,我希望在单击链接时,它会在网络浏览器中打开它,当单击它时,文本浏览器不会变为空白,但仍应保留所有链接。
    • @vesuvius 1) 您希望此 URL 打开 webdriver 搜索引擎还是您操作系统的默认搜索引擎? 2)您应该编辑您的问题并添加点击时想要发生的事情
    • 我在问题的底部添加了Edit 部分,请您检查一下:)
    猜你喜欢
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2014-09-14
    相关资源
    最近更新 更多