ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何将Python flask应用程序加载到gtk Webview(Webkit)

2019-11-21 10:06:27  阅读:378  来源: 互联网

标签:mathjax webkit flask gtk python


我目前正在开发一个需要渲染数学表达式(从乳胶)并且需要某种本机gui的应用程序(即使它仅使用gtk,然后在webkit中渲染html).

我进行了一些研究,并确定一种简单的方法是使用webkit加载网页并使用像MathJax这样的JavaScript库来渲染数学.
之所以选择这种方式而不是其他解决方案,还有其他一些原因,例如,我有相当多的使用python开发Web应用程序的经验(尽管有一段时间),缺乏使用本机GUI的经验以及它提供的可移植性.

对于Web应用程序框架,我选择使用flask,因为它是我最熟悉的框架.

问题是此应用程序最好通过gtk(即使只是使用webkit渲染html)也需要具有自己的本机GUI,并且最好也不应将http服务器附加到某些套接字.

所以我的问题是,除了运行flask的服务器外,还有其他方法可以执行以下操作:

import gtk
import webkit

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "<h1>Hello World!</h1>"

if __name__ == '__main__': 
    window = gtk.Window()

    webview = webkit.WebView()

    webview.load_string(
        app.load_from_uri('/'),
        "text/html",
        "utf-8",
        '/'
    )

    window.add(webview) 
    window.show_all() 

其中app.load_from_uri(‘/’)仅用作为Flask应用程序的给定uri加载网页的方法的示例.但这仅是示例,如何在真实代码中完成app.load_from_uri(‘/’)?

无论如何,当用户单击链接时也可以覆盖它,因此它会执行以下操作:

def link_clicked(uri):
    webview.load_string(
        app.load_from_uri(uri),
        "text/html",
        "utf-8",
        uri
    )

谢谢任何帮助,不胜感激!

解决方法:

我最终找到了自己的解决方案(但可以接受更好的解决方案).

首先,加载页面非常简单. Flask提供了一种测试应用程序的方法,该方法主要是为WSGI设置一切以便能够处理请求.这正是我所需要的,所以我这样使用它:

from flask import Flask
class WebViewFlask(Flask):
    """
    Adds the ability to load a uri without the
    need of a HTTP server.
    """
    def load_from_uri(self, uri):
        """
        Loads a uri without a running HTTP server.
        """
        with self.test_client() as c:
            response = c.get(uri)
            return response.data, response.mimetype

第二部分覆盖“当用户单击链接时”,这更加棘手.

import os
import webkit
class FlaskAppView(webkit.WebView):
    """
    Loads pages for flask apps into a WebView.
    """
    def __init__(self, flask_app, *args, **kwargs):
        # Protocol for flask app, by default file:// is used
        # so a protocol is defined here to prevent that.
        self.PROTOCOL = 'flask://' 

        super(webkit.WebView, self).__init__(*args, **kwargs)

        self._flask_app = flask_app

        # Register new navigation handler.
        self.connect(
            "navigation-policy-decision-requested",
            self._nav_request
        )

        # For navigation handler.
        self.prev_uri = None

        # Redefine open like this as when using super
        # an error like this occurs:
        #   AttributeError: 'super' object has no attribute 'open'
        self._open = self.open
        self.open = self.open_

    def _nav_request(self, view, frame, net_req, nav_act, pol_dec):
        """
        WebView navigation handler for Flask apps.
        """
        # Get the uri
        uri = net_req.get_uri()

        # In order for flask apps to use relative links
        # the protocol is removed and it is made into an absolute
        # path.
        if uri.startswith(self.PROTOCOL):
            # In this case it is not relative but
            # it needs to have it's protocol removed
            uri = uri[len(self.PROTOCOL):]

        elif not self.prev_uri.endswith(uri):
            # It is relative and self.prev_uri needs to
            # be appended.
            uri = os.path.normpath(os.path.join(self.prev_uri, uri))

        # This is used to prevent an infinite recursive loop due
        # to view.load_string running this function with the same
        # input.
        if uri == self.prev_uri:
            return False

        self.prev_uri = uri

        # Create response from Flask app.
        response = app.load_from_uri(uri) + ('utf-8', uri)

        # Load response.
        view.load_string(*response)

        # Return False to prevent additional
        # handlers from running.
        return False

    def open_(self, uri):
        """
        Prepends protocol to uri for webkit.WebView.open.
        """
        self._open(self.PROTOCOL + uri)

基本上,新的导航事件处理程序已注册一些代码,以允许成功递归并支持相对路径.

无论如何,通过上面的代码,只需将Flask替换为WebViewFlask,将WebView替换为FlaskAppView,几乎所有东西都可以正常工作.

结果:

这是一个无需任何服务器即可在webkit.WebView中加载的flask应用.最好的办法是将应用程序切换回Flask实例而不是WebViewFlask实例.这又是一个普通的Webapp.

标签:mathjax,webkit,flask,gtk,python
来源: https://codeday.me/bug/20191121/2051140.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有