PySide/PyQt: Is it possible to make strings that you attach to the QTextBrowser separate clickable units

StackOverflow https://stackoverflow.com/questions/19454113

Pergunta

This might be a silly question but:

When you append a given string to a QTextBrowser object, can you make it a link to a signal to a function that takes its text and does something with it? All I need is for it to save the text to a variable actually.

As in, can a link lead to a function instead of to a website.

Foi útil?

Solução

It certainly is possible.

Here is a code example:

import sys

from PyQt4 import QtGui
from PyQt4 import QtCore

class MainWindow(QtGui.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        main_layout = QtGui.QVBoxLayout()

        self.browser = QtGui.QTextBrowser()
        self.browser.setHtml('''<html><body>some text<br/><a href="some_special_identifier://a_function">click me to call a function</a><br/>
        <a href="#my_anchor">Click me to scroll down</a><br>foo<br>foo<br>foo<br>foo<br>foo<br>foo<br>
        foo<a id="my_anchor"></a><br>bar<br>bar<br>bar<br>bar<br>bar<br>bar<br>hello!<br>hello!<br>hello!<br>hello!<br>hello!<br>hello!<br>hello!<br>hello!</body></html''')

        self.browser.anchorClicked.connect(self.on_anchor_clicked)

        main_layout.addWidget(self.browser)

        self.setLayout(main_layout)

    def on_anchor_clicked(self,url):
        text = str(url.toString())
        if text.startswith('some_special_identifier://'):
            self.browser.setSource(QtCore.QUrl()) #stops the page from changing
            function = text.replace('some_special_identifier://','')
            if hasattr(self,function):
                getattr(self,function)()

    def a_function(self):
        print 'you called?'

app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()

sys.exit(app.exec_())

Any link that has a url that begins with "some_special_identifier://" will be picked up and the text after that will be used to look up and call a function of the same name. Please note that this could be a little risky as there is the potential for all sorts of functions to be called that perhaps you don't intend, if the user has any control over what is displayed in the TextBrowser. It might be better to only allow certain functions to be run, and perhaps only at certain times. That is of course up to you to enforce!

P.S. my code is written for Python 2.7 (I see you are using Python 3). So I think you will need to change print 'text' to print('text') at the very least!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top