gpt4 book ai didi

javascript - 如何使用QWebEngineView和qtwebchannel.js一步步加载javascript?

转载 作者:行者123 更新时间:2023-12-04 17:40:55 34 4
gpt4 key购买 nike

我正在设置一个在后端使用 python 并在前端使用 html/css/js 的框架。我的问题是在加载 QWebEngineView 时出现的。

我在网上搜索如何使用 QWebEngineView 在 python 和 javascript 之间建立通信,最后我尝试使用 QtWebChannel。所以我设置了所有内容,并且在 python 和 javascript 之间的通信中一切正常,但是下一个问题出现了:

  • 首先:我无法在带有标签 <script> 的 html 中直接加载 javascript 文件
  • 第二:javascript 随机加载,我尝试使用 my_view.page().runJavascript(my_js) 从 python 加载 javascript但它可以一次尝试两次。所以有时 jQuery 在最后加载,所以代码的其他部分不起作用。

基础.html:

<!DOCTYPE html>
<html lang="en">
<p id="log"></p>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<script>
window.onerror = function (error, url, line) {
console.error("ERROR: " + error.toString());
console.error("LINE: " + line.toString());
};
function load_app(){
new QWebChannel(qt.webChannelTransport, function (channel) {
window.app = channel.objects.app;
app.load_javascript(function(ret){
console.error("load javascript: " + ret)
});
});
}
load_app();
console.error("app loaded")
</script>
{{ application_html_content | safe }}
</html>

HTML的另一部分:

{% extends 'base.html' %}

{% block content %}
<div class="row">
{% for user_id, user in user_dict.items() %}
<div id="{{ user_id }}" class="col s12 m6">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">Visit Card</span>
<p>{{ user.name }}</p>
</div>
<div class="card-action">
<button id="btn_del_{{ user_id }}" class="btn blue waves-effect waves-light" onclick="delete_user({{ user_id }})">Delete</button>
<button class="btn blue waves-effect waves-light" onclick="detail_user({{ user_id }})">Detail</button>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

{% block javascript %}
<script>
$(document).ready(function() {
app.request_result.connect(function (result) {
if ("delete" in result) {
user_id = result.delete;
var element = document.getElementById(user_id);
element.parentNode.removeChild(element)
}
});
console.error("ready");
});

function delete_user(user_id) {
document.getElementById("btn_del_" + user_id).innerHTML = "Waiting ...";
app.request('DemoHtml:Default:delete', user_id);
}
function detail_user(user_id) {
app.path('detail_user', {"user_id": user_id});
}
</script>
{% endblock %}

load_javascript 函数:

JQUERY = "vendor/Resources/js/jquery.js"
MATERIALIZE = "vendor/Resources/css/materialize/js/materialize.js"

@pyqtSlot(result=str)
def load_javascript(self):
with open(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.MATERIALIZE), "r") as m_stream:
materialize_content = m_stream.read()
with open(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.JQUERY), "r") as j_stream:
jquery_content = j_stream.read()
self.template_view.view.page().runJavaScript(jquery_content)
self.template_view.view.page().runJavaScript(materialize_content)
return "ok"

如你所见,通常我必须在日志错误中看到:

  • 首先:“加载 javascript:确定”
  • 第二个:“应用已加载”

但是一次一两次,这是相反的:

  • js:应用已加载
  • js: 错误: Uncaught ReferenceError :$ 未定义
  • js: 行: 67
  • js: 未捕获的 ReferenceError: $ 未定义
  • js: 加载 javascript: ok

对此有什么帮助吗?

提前致谢!

最佳答案

我解决了我的问题,感谢@ekhumoro 试图帮助我,我在这个线程上找到了答案:

如何等待另一个JS加载继续操作?:https://stackoverflow.com/a/8618519/8293533

因此,为了让它工作,我将我的 javascript 更改为:我将此文件命名为 app.js

function set_app() {
try{
new QWebChannel(qt.webChannelTransport, function (channel) {
window.app_channel = channel.objects.app;
});
} catch (e) {
console.error("setting_app error: " + e)
}
}

set_app();

function request(route, args) {
let interval = 10;
window.setTimeout(function () {
if (window["app_channel"]) {
app_channel.request(route, args)
} else {
try {
set_app();
}
catch(error) {
console.error("app load error: " + error)
}
window.setTimeout(arguments.callee, interval);
}
}, interval)
}

function path(route, args) {
let interval = 10;
window.setTimeout(function () {
if (window["app_channel"]) {
app_channel.path(route, args)
} else {
try {
set_app();
}
catch(error) {
console.error("app load error: " + error)
}
window.setTimeout(arguments.callee, interval);
}
}, interval)
}

function request_result(callback) {
let interval = 10;
window.setTimeout(function () {
if (window["app_channel"]) {
app_channel.request_result.connect(callback)
} else {
try {
set_app();
}
catch(error) {
console.error("app load error: " + error)
}
window.setTimeout(arguments.callee, interval);
}
}, interval)
}

我删除我的代码 load_javascript在 python 中,因为我找到了用 <script> 调用 js 的方法标签和 qrc:///路径。

现在我的 html 头看起来像这样:

<!DOCTYPE html>
<html lang="en">
<p id="log"></p>
<script src="qrc:///qwebchannel.js"></script>
<script src="qrc:///app.js"></script>
<script src="qrc:///jquery.js"></script>
{{ application_html_content | safe }}
<script src="qrc:///materialize.min.js"></script>
</html>

使用qrc:///xxx.js我用了QResource.qrc , .rcc文件。这是我的代码示例,供需要的人使用:

class ApplicationContainer:

SRC_QRC_PATH = "src/*Bundle/Resources/qrc/*.qrc"
SRC_RCC_PATH = "src/*Bundle/Resources/qrc/*.rcc"
VENDOR_QRC_PATH = "vendor/*Bundle/Resources/qrc/*.qrc"
VENDOR_RCC_PATH = "vendor/*Bundle/Resources/qrc/*.rcc"

def __init__(self):
self.__pyqt_application = QApplication(sys.argv)
self.__pyqt_resources = QResource()
self.set_rcc_files()

@property
def application(self):
return self.__pyqt_application

@application.setter
def application(self, new_app: QApplication):
self.__pyqt_application = new_app

def set_rcc_files(self):
qrc_files = glob.glob(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.SRC_QRC_PATH))
qrc_files += glob.glob(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.VENDOR_QRC_PATH))
for qrc in qrc_files:
subprocess.call(["rcc", "-binary", qrc, "-o", qrc[:-3] + "rcc"])

rcc_files = glob.glob(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.SRC_RCC_PATH))
rcc_files += glob.glob(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), self.VENDOR_RCC_PATH))

for rcc in rcc_files:
self.__pyqt_resources.registerResource(rcc)

如你所见,我使用 rcc命令,而不是 pyrcc5

最后,这是我的 .qrc文件:

<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file alias="jquery.js">../js/jquery.js</file>
<file alias="app.js">../js/app.js</file>
<file alias="qwebchannel.js">../js/qwebchannel.js</file>
<file alias="materialize.js">../css/materialize/js/materialize.js</file>
<file alias="materialize.css">../css/materialize/css/materialize.css</file>
</qresource>
</RCC>

我知道 javascript 代码和 python 代码可以有很多改进和优化。但它是这样工作的!

谢谢,希望我也能帮到别人。

关于javascript - 如何使用QWebEngineView和qtwebchannel.js一步步加载javascript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54538300/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com