Beispiel #1
0
 def __init__(self):
     super(HTMLWidget, self).__init__()
     self.settings().setAttribute(
         QWebSettings.LocalContentCanAccessRemoteUrls, True)
     self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
     self.setPage(WebPage())
     self._obj = None
     self._styles = [_DEFAULT_STYLES]
     self._header = ''
     self._body = ''
     self.add_to_js('widget', self)
     self._event = EventEmitter()
     self.add_header('''<script>
                     var emit = function (name, arg) {
                         widget._emit_from_js(name, JSON.stringify(arg));
                     };
                     </script>''')
     self._pending_js_eval = []
Beispiel #2
0
 def __init__(self):
     super(HTMLWidget, self).__init__()
     self.settings().setAttribute(
         QWebSettings.LocalContentCanAccessRemoteUrls, True)
     self.settings().setAttribute(
         QWebSettings.DeveloperExtrasEnabled, True)
     self.setPage(WebPage())
     self._obj = None
     self._styles = [_DEFAULT_STYLES]
     self._header = ''
     self._body = ''
     self.add_to_js('widget', self)
     self._event = EventEmitter()
     self.add_header('''<script>
                     var emit = function (name, arg) {
                         widget._emit_from_js(name, JSON.stringify(arg));
                     };
                     </script>''')
     self._pending_js_eval = []
Beispiel #3
0
class HTMLWidget(QWebView):
    """An HTML widget that is displayed with Qt.

    Python methods can be called from Javascript with `widget.the_method()`.
    They must be decorated with `pyqtSlot(str)` or similar, depending on
    the parameters.

    """
    title = 'Widget'
    body = ''

    def __init__(self):
        super(HTMLWidget, self).__init__()
        self.settings().setAttribute(
            QWebSettings.LocalContentCanAccessRemoteUrls, True)
        self.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
        self.setPage(WebPage())
        self._obj = None
        self._styles = [_DEFAULT_STYLES]
        self._header = ''
        self._body = ''
        self.add_to_js('widget', self)
        self._event = EventEmitter()
        self.add_header('''<script>
                        var emit = function (name, arg) {
                            widget._emit_from_js(name, JSON.stringify(arg));
                        };
                        </script>''')
        self._pending_js_eval = []
        self._built = None

    # Events
    # -------------------------------------------------------------------------

    def emit(self, *args, **kwargs):
        return self._event.emit(*args, **kwargs)

    def connect_(self, *args, **kwargs):
        self._event.connect(*args, **kwargs)

    def unconnect_(self, *args, **kwargs):
        self._event.unconnect(*args, **kwargs)

    # Headers
    # -------------------------------------------------------------------------

    def add_styles(self, s):
        """Add CSS styles."""
        self._styles.append(s)

    def add_style_src(self, filename):
        """Link a CSS file."""
        self.add_header(('<link rel="stylesheet" type="text/css" '
                         'href="{}" />').format(filename))

    def add_script_src(self, filename):
        """Link a JS script."""
        self.add_header('<script src="{}"></script>'.format(filename))

    def add_header(self, h):
        """Add HTML code to the header."""
        self._header += (h + '\n')

    # HTML methods
    # -------------------------------------------------------------------------

    def set_body(self, s):
        """Set the HTML body."""
        self._body = s

    def add_body(self, s):
        """Add HTML code to the body."""
        self._body += '\n' + s + '\n'

    def html(self):
        """Return the full HTML source of the widget."""
        return self.page().mainFrame().toHtml()

    def rebuild(self):
        styles = '\n\n'.join(self._styles)
        html = _PAGE_TEMPLATE.format(
            title=self.title,
            styles=styles,
            header=self._header,
            body=self._body,
        )
        logger.log(5, "Set HTML: %s", html)
        static_dir = op.join(op.realpath(op.dirname(__file__)), 'static/')
        base_url = QUrl().fromLocalFile(static_dir)
        self.setHtml(html, base_url)

    def build(self):
        """Build the full HTML source."""
        if self.is_built():  # pragma: no cover
            return
        with _wait_signal(self.loadFinished, 20):
            self.rebuild()
        self._built = True

    def is_built(self):
        return self._built

    # Javascript methods
    # -------------------------------------------------------------------------

    def add_to_js(self, name, var):
        """Add an object to Javascript."""
        frame = self.page().mainFrame()
        frame.addToJavaScriptWindowObject(name, var)

    def eval_js(self, expr):
        """Evaluate a Javascript expression."""
        if not self.is_built():
            self._pending_js_eval.append(expr)
            return
        logger.log(5, "Evaluate Javascript: `%s`.", expr)
        out = self.page().mainFrame().evaluateJavaScript(expr)
        return _to_py(out)

    @pyqtSlot(str, str)
    def _emit_from_js(self, name, arg_json):
        self.emit(text_type(name), json.loads(text_type(arg_json)))

    def show(self):
        self.build()
        super(HTMLWidget, self).show()
        # Call the pending JS eval calls after the page has been built.
        assert self.is_built()
        for expr in self._pending_js_eval:
            self.eval_js(expr)
        self._pending_js_eval = []
Beispiel #4
0
class HTMLWidget(QWebView):
    """An HTML widget that is displayed with Qt.

    Python methods can be called from Javascript with `widget.the_method()`.
    They must be decorated with `pyqtSlot(str)` or similar, depending on
    the parameters.

    """
    title = 'Widget'
    body = ''

    def __init__(self):
        super(HTMLWidget, self).__init__()
        self.settings().setAttribute(
            QWebSettings.LocalContentCanAccessRemoteUrls, True)
        self.settings().setAttribute(
            QWebSettings.DeveloperExtrasEnabled, True)
        self.setPage(WebPage())
        self._obj = None
        self._styles = [_DEFAULT_STYLES]
        self._header = ''
        self._body = ''
        self.add_to_js('widget', self)
        self._event = EventEmitter()
        self.add_header('''<script>
                        var emit = function (name, arg) {
                            widget._emit_from_js(name, JSON.stringify(arg));
                        };
                        </script>''')
        self._pending_js_eval = []
        self._built = None

    # Events
    # -------------------------------------------------------------------------

    def emit(self, *args, **kwargs):
        return self._event.emit(*args, **kwargs)

    def connect_(self, *args, **kwargs):
        self._event.connect(*args, **kwargs)

    def unconnect_(self, *args, **kwargs):
        self._event.unconnect(*args, **kwargs)

    # Headers
    # -------------------------------------------------------------------------

    def add_styles(self, s):
        """Add CSS styles."""
        self._styles.append(s)

    def add_style_src(self, filename):
        """Link a CSS file."""
        self.add_header(('<link rel="stylesheet" type="text/css" '
                         'href="{}" />').format(filename))

    def add_script_src(self, filename):
        """Link a JS script."""
        self.add_header('<script src="{}"></script>'.format(filename))

    def add_header(self, h):
        """Add HTML code to the header."""
        self._header += (h + '\n')

    # HTML methods
    # -------------------------------------------------------------------------

    def set_body(self, s):
        """Set the HTML body."""
        self._body = s

    def add_body(self, s):
        """Add HTML code to the body."""
        self._body += '\n' + s + '\n'

    def html(self):
        """Return the full HTML source of the widget."""
        return self.page().mainFrame().toHtml()

    def rebuild(self):
        styles = '\n\n'.join(self._styles)
        html = _PAGE_TEMPLATE.format(title=self.title,
                                     styles=styles,
                                     header=self._header,
                                     body=self._body,
                                     )
        logger.log(5, "Set HTML: %s", html)
        static_dir = op.join(op.realpath(op.dirname(__file__)), 'static/')
        base_url = QUrl().fromLocalFile(static_dir)
        self.setHtml(html, base_url)

    def build(self):
        """Build the full HTML source."""
        if self.is_built():  # pragma: no cover
            return
        with _wait_signal(self.loadFinished, 20):
            self.rebuild()
        self._built = True

    def is_built(self):
        return self._built

    # Javascript methods
    # -------------------------------------------------------------------------

    def add_to_js(self, name, var):
        """Add an object to Javascript."""
        frame = self.page().mainFrame()
        frame.addToJavaScriptWindowObject(name, var)

    def eval_js(self, expr):
        """Evaluate a Javascript expression."""
        if not self.is_built():
            self._pending_js_eval.append(expr)
            return
        logger.log(5, "Evaluate Javascript: `%s`.", expr)
        out = self.page().mainFrame().evaluateJavaScript(expr)
        return _to_py(out)

    @pyqtSlot(str, str)
    def _emit_from_js(self, name, arg_json):
        self.emit(text_type(name), json.loads(text_type(arg_json)))

    def show(self):
        self.build()
        super(HTMLWidget, self).show()
        # Call the pending JS eval calls after the page has been built.
        assert self.is_built()
        for expr in self._pending_js_eval:
            self.eval_js(expr)
        self._pending_js_eval = []