通过QWebEngineView和QWebChannel搭建交互式web&python应用

通过QWebEngineView和QWebChannel搭建交互式web&python应用

首先来说说通过QWebEngineView和QWebChannel搭建交互式web&python应用的好处哈哈,万事皆是有需要才有创造嘛哈哈

1、可以大幅缩短您的开发周期,众所周知,web开发技术和周期都非常优秀,而UI也是我们开发过程中繁琐费时的开发工作之一,如果python应用的UI和部分逻辑可以用web技术实现那将节省太多太多时间;
2、这可以让python应用和web技术深入融合,开拓python的运用范围,web工程师可以轻松与python工程师合作开发出具有python优势和web技术优势的应用。

代码地址:https://github.com/wenyehaiyang/web-pyqt5

内容

1、准备环境
2、在QWebEngineView注册QWebChannel
3、在html前端页面注册QWebChannel
4、在QWebEngineView端写待调用函数(可附带参数)
5、在html前端页面通过QWebChannel调用对应的QWebEngineView端的函数
6、在QWebEngineView端调用HTML前端代码,执行javascript代码
7、补充本文中QWebEngineView加载的是本地html文件相当于是使用的是file协议,如果是设计其他静态资源请求等,建议可以利用python的http.server监听本地端口,即可实现

开始码字^^

1、准备环境:

(1)安装python,这就不多说了,网上很多教程嘿嘿。
(2)安装pyqt5,在pyqt5 5.12版本之前pyqt5包内包含QWebEngineView,可以直接pip install pyqt5==5.11或者之前的版本,安装完毕就可以导入了from PyQt5.QtWebEngineWidgets import QWebEngineView;在之后的版本,安装pyqt5之后,需要另外安装pyqtwebengine(pip install PyQtWebEngine),说明一下PyQtWebEngine可以适配多个版本的pyqt5,推荐与pyqt5版本一致。
(3)下载qwebchannel.js,下载地址:https://doc.qt.io/qt-5.9/qtwebengine-webenginewidgets-markdowneditor-resources-qwebchannel-js.html。(PS:这是官网地址,如果地址失效可以百度qwebchannel.js找到qwebchannel.js)

2、QWebEngineView端

直接看代码嘻嘻:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
import os
import time
import urllib.request

from PyQt5.QtWidgets import QApplication, QDesktopWidget
from PyQt5.QtCore import QObject, pyqtSlot, QUrl, Qt, QPoint
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
from httpSeve.server_tool import http_server_main

__Author__ = '''wenye'''


class CallHandler(QObject):

    def __init__(self):
        super(CallHandler, self).__init__()

    @pyqtSlot(str, result=str)  # 第一个参数即为回调时携带的参数类型
    def init_home(self, str_args):
        print('call received')
        print('resolving......init home..')
        print(str_args)  # 查看参数
        # #####
        # 这里写对应的处理逻辑比如:
        msg = '收到来自python的消息'
        view.page().runJavaScript("alert('%s')" % msg)
        view.page().runJavaScript("window.say_hello('%s')" % msg)
        return 'hello, Python'


class WebEngine(QWebEngineView):
    def __init__(self):
        super(WebEngine, self).__init__()
        self.setContextMenuPolicy(Qt.NoContextMenu)  # 设置右键菜单规则为自定义右键菜单
        # self.customContextMenuRequested.connect(self.showRightMenu)  # 这里加载并显示自定义右键菜单,我们重点不在这里略去了详细带吗

        self.setWindowTitle('QWebChannel与前端交互')
        self.resize(1100, 650)
        cp = QDesktopWidget().availableGeometry().center()
        self.move(QPoint(cp.x() - self.width() / 2, cp.y() - self.height() / 2))

    def closeEvent(self, evt):
        self.page().profile().clearHttpCache()  # 清除QWebEngineView的缓存
        super(WebEngine, self).closeEvent(evt)


if __name__ == '__main__':
    # 加载程序主窗口
    app = QApplication(sys.argv)
    view = WebEngine()
    channel = QWebChannel()
    handler = CallHandler()  # 实例化QWebChannel的前端处理对象
    channel.registerObject('PyHandler', handler)  # 将前端处理对象在前端页面中注册为名PyHandler对象,此对象在前端访问时名称即为PyHandler'
    view.page().setWebChannel(channel)  # 挂载前端处理对象
    url_string = urllib.request.pathname2url(os.path.join(os.getcwd(), "index.html"))  # 加载本地html文件
    # 当然您可以加载互联网行的url,也可自行监听本地端口,然后加载本地端口服务的资源,后面有介绍嘻嘻
    # url_string = 'localhost:64291'   # 加载本地html文件
    # print(url_string, '\n', os.path.join(os.getcwd(), "index.html"))
    view.load(QUrl(url_string))
    time.sleep(2)
    view.show()
    sys.exit(app.exec_())

2、HTML端

(1)新建index.html,并将qwebchannel.js放在index.html目录(其他目录也可以,在HTML中正确引入即可);
(2)在index.html中注册QWebChannel实例。
直接看代码哈哈:




    
    
    
    PyQt5通过QWebEngineView和QWebChannel搭建交互式浏览器
    
    
    



效果:

$运行程序
通过QWebEngineView和QWebChannel搭建交互式web&python应用_第1张图片
$javascript调用python端后
通过QWebEngineView和QWebChannel搭建交互式web&python应用_第2张图片
$python端的调用javascript后通过QWebEngineView和QWebChannel搭建交互式web&python应用_第3张图片

3、补充:如果您从本地端口加载web文件,可以使用http.server监听本地端口

直接看代码嘻嘻:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import http.server
import os
import queue
from functools import partial
from httpServe.asyncBase_native import runTask  # 这是我写的一个线程装饰器,被装饰的函数在被调用时会另外加载线程执行,具体代码请移步我的github嘿嘿

__Author__ = '''wenye&hunan'''

# 定义路径,以免在不同操作系统出错
STATIC_PATH_MAIN = os.path.join(os.getcwd(), 'dist', 'mainpage')  # 在这里拼接需要服务的静态文件路径

PORT_MAIN = 64291  # 监听的端口,对于的QWebEngineView的load函数加载的url即为:localhost:PORT_MAIN

Handler = http.server.SimpleHTTPRequestHandler
# 队列
q_line_main = queue.Queue()  # 这个队列用于盛放服务器的句柄,用于操作服务器,可在应用具体逻辑中导入此队列


@runTask
def http_server_main():
    handler_class = partial(Handler, directory=STATIC_PATH_MAIN)
    handler_class.protocol_version = "HTTP/1.0"
    with http.server.ThreadingHTTPServer(("", PORT_MAIN), handler_class) as httpd:
        q_line_main.put(httpd)
        print("serving at port", PORT_MAIN)
        httpd.serve_forever()

代码地址:https://github.com/wenyehaiyang/web-pyqt5

你可能感兴趣的:(python,python,pyqt,js)