I'm working in a Python App. In some parts of the program I inform the user that different files are created. I show this information in a QTextBrowser
widget. I want that this text is hyperlinked, so if the user clicks on the hyperlink, the file opens in an external application. If the path of file has no blank spaces, the links work - but if the path has blank spaces the links don't work.
I read a lot of questions about this, but I don't find a solution.
I wrote these two tests.
Code 1 - I use QLabel
and the link works perfectly, but in QTextBrowser
it opens inside the browser.
Option 1 works, but the rest of the options don't work because the path has blank spaces.
Option 7 and 10, open the file but inside the browser.
CODE 1:
import sys
from PyQt5.QtWidgets import QApplication, QTextBrowser,QTextEdit,QLabel
from PyQt5.QtCore import QUrl
app = QApplication(sys.argv)
label=QLabel()
file_2='c:/temp/test 2/test.docx'
urlLink="<a href='file:///%s'>'Option_12'</a>"%(file_2)
label.setText(urlLink)
label.setOpenExternalLinks(True)
label.show()
sys.exit(app.exec_())
CODE 2:
import sys
from PyQt5.QtWidgets import QApplication, QTextBrowser,QTextEdit
from PyQt5.QtCore import QUrl
if __name__ == '__main__':
app = QApplication(sys.argv)
text_area = QTextBrowser()
file='c:/temp/test.docx'
link='<a href='"'{}'"'>Option_1</a>'.format(file)
text_area.insertHtml(link)
file_2='c:/temp/test 2/test.docx'
link='<br><a href='"'{}'"'>Option_2</a></br>'.format(file_2)
text_area.insertHtml(link)
file_2_reformated=file_2.replace(" ", "\\ ")
link='<br><a href='"'{}'"'>Option_3</a></br>'.format(file_2_reformated)
text_area.insertHtml(link)
file_2_reformated=file_2.replace(" ", "%20")
link='<br><a href='"'{}'"'>Option_4</a></br>'.format(file_2_reformated)
text_area.insertHtml(link)
file_2_reformated=chr(34)+file_2+chr(34)
link='<br><a href='"'{}'"'>Option_5</a></br>'.format(file_2_reformated)
text_area.insertHtml(link)
file_2_reformated = " \"" + file_2 + " \""
link='<br><a href='"'{}'"'>Option_6</a></br>'.format(file_2_reformated)
text_area.insertHtml(link)
link='<br><a href='"'file:///{}'"'>Option_7</a></br>'.format(file_2)
text_area.insertHtml(link)
link='<br><a href='"'https://{}'"'>Option_8</a></br>'.format(file_2)
text_area.insertHtml(link)
file_3="file:///c:/temp/test 2/test.docx"
link='<br><a href='"'https://{}'"'>Option_9</a></br>'.format(file_3)
text_area.insertHtml(link)
file_2='c:/temp/test 2/test.docx'
link = '<br><a href="{}">Option_10</a></br>'.format(QUrl.fromLocalFile(file_2).toString())
text_area.insertHtml(link)
file_2='c:/temp/test 2/test.docx'
link = '<br><a href="\'{}\'">Option_11</a></br>'.format(QUrl.fromLocalFile(file_2).toString())
text_area.insertHtml(link)
from pathlib import PureWindowsPath
file_3 = PureWindowsPath("c:/temp/test 2/test.docx")
link = '<br><a href="{}">Option_13</a></br>'.format(file_3.as_uri())
text_area.insertHtml(link)
text_area.setOpenExternalLinks(True)
text_area.show()
sys.exit(app.exec_())
SOLUTION BY @ekhumoro
import sys
from PyQt5.QtWidgets import QApplication, QTextBrowser
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
if __name__ == '__main__':
app = QApplication(sys.argv)
text_area = QTextBrowser()
text_area.setOpenLinks(False)
def handle_links(url):
if not url.scheme():
url = QUrl.fromLocalFile(url.toString())
QDesktopServices.openUrl(url)
text_area.anchorClicked.connect(handle_links)
file='c:/temp/test.docx'
link='<a href='"'{}'"'>Option_1</a>'.format(file)
text_area.insertHtml(link)
file_2='c:/temp/test 2/test.docx'
link='<br><a href='"'file:///{}'"'>Option_7</a></br>'.format(file_2)
text_area.insertHtml(link)
link = '<br><a href="{}">Option_10</a></br>'.format(QUrl.fromLocalFile(file_2).toString())
text_area.insertHtml(link)
from pathlib import PureWindowsPath
file_3 = PureWindowsPath("c:/temp/test 2/test.docx")
link = '<br><a href="{}">Option_13</a></br>'.format(file_3.as_uri())
text_area.insertHtml(link)
text_area.show()
sys.exit(app.exec_())
The problem is that setOpenExternalLinks(True) will not open urls with a file: scheme - but you must use a file: scheme to open file-paths that contain spaces. To work around this, you can use a custom link handler. The following script shows how to do that:
import sys
from PyQt5.QtWidgets import QApplication, QTextBrowser
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
if __name__ == '__main__':
app = QApplication(sys.argv)
text_area = QTextBrowser()
text_area.setOpenLinks(False)
def handle_links(url):
if not url.scheme():
url = QUrl.fromLocalFile(url.toString())
QDesktopServices.openUrl(url)
text_area.anchorClicked.connect(handle_links)
file = 'c:/temp/test.docx'
link = '<a href="{}">Option_1</a>'.format(file)
text_area.insertHtml(link)
file_2 = 'c:/temp/test 2/test.docx'
link = '<br><a href="{}">Option_2</a></br>'.format(file_2)
text_area.insertHtml(link)
text_area.show()
sys.exit(app.exec_())