1
这些问题都是网络连接和页面加载问题。让我们修复这些问题,使用更可靠的测试方法和本地页面。
解决方案:使用本地HTML页面和更可靠的测试方法
1. 创建本地HTML文件
首先在项目目录中创建 localpage.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Qt-JS交互测试页面</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.container {
max-width: 800px;
margin: 0 auto;
background: rgba(255,255,255,0.1);
padding: 20px;
border-radius: 10px;
backdrop-filter: blur(10px);
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.control-panel {
background: rgba(255,255,255,0.2);
padding: 15px;
border-radius: 8px;
margin: 15px 0;
}
button {
background: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
margin: 5px;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background: #45a049;
}
.status {
background: rgba(0,0,0,0.3);
padding: 10px;
border-radius: 5px;
margin: 10px 0;
font-family: monospace;
}
.message-log {
background: rgba(0,0,0,0.5);
padding: 10px;
border-radius: 5px;
max-height: 200px;
overflow-y: auto;
font-family: monospace;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<h1>🎯 Qt-JavaScript 交互测试页面</h1>
<div class="control-panel">
<h3>控制面板</h3>
<button onclick="sendMessageToQt('Hello from JavaScript!')">发送消息到Qt</button>
<button onclick="sendMessageToQt('当前时间: ' + new Date().toLocaleString())">发送时间</button>
<button onclick="sendMessageToQt('页面标题: ' + document.title)">发送页面信息</button>
<button onclick="showAlert('这是一个测试弹窗')">显示弹窗</button>
</div>
<div class="status">
<strong>状态:</strong> <span id="statusText">等待Qt连接...</span>
</div>
<div class="message-log">
<strong>消息日志:</strong>
<div id="messageLog"></div>
</div>
<div class="control-panel">
<h3>测试Qt调用JavaScript</h3>
<p>在Qt中点击"测试JS"按钮来调用下面的函数:</p>
<ul>
<li><code>window.receiveFromQt(message)</code> - 接收Qt消息</li>
<li><code>window.changeBackground(color)</code> - 改变背景颜色</li>
<li><code>window.addMessage(text)</code> - 添加消息到日志</li>
</ul>
</div>
</div>
<script>
// 全局函数 - 供Qt调用
window.receiveFromQt = function(message) {
logMessage('📩 收到Qt消息: ' + message);
addStatus('✅ 收到Qt消息');
// 显示视觉反馈
showVisualFeedback('Qt消息: ' + message);
return 'JavaScript收到消息: ' + message;
};
window.changeBackground = function(color) {
document.body.style.background = color;
logMessage('🎨 背景颜色已更改为: ' + color);
return '背景颜色已更改';
};
window.addMessage = function(text) {
logMessage('💬 Qt添加消息: ' + text);
return '消息已添加';
};
// 发送消息到Qt的函数
function sendMessageToQt(message) {
logMessage('📤 发送到Qt: ' + message);
addStatus('🔄 发送消息到Qt...');
// 使用自定义URL方案与Qt通信
window.location = 'qt://message?data=' + encodeURIComponent(message);
}
function showAlert(message) {
alert('JavaScript弹窗: ' + message);
logMessage('弹窗显示: ' + message);
}
function showVisualFeedback(message) {
// 创建临时视觉反馈
const feedback = document.createElement('div');
feedback.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(76, 175, 80, 0.9);
color: white;
padding: 20px;
border-radius: 10px;
z-index: 10000;
font-size: 18px;
text-align: center;
`;
feedback.textContent = message;
document.body.appendChild(feedback);
setTimeout(() => {
document.body.removeChild(feedback);
}, 2000);
}
function logMessage(message) {
const log = document.getElementById('messageLog');
const entry = document.createElement('div');
entry.textContent = new Date().toLocaleTimeString() + ' - ' + message;
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
function addStatus(status) {
document.getElementById('statusText').textContent = status;
}
// 页面加载完成
document.addEventListener('DOMContentLoaded', function() {
logMessage('✅ 页面加载完成');
addStatus('✅ 就绪 - 等待交互');
console.log('Qt-JS测试页面已就绪');
});
// 暴露函数到全局作用域
window.sendMessageToQt = sendMessageToQt;
window.logMessage = logMessage;
window.addStatus = addStatus;
</script>
</body>
</html>
2. 更新QML文件 - 使用本地页面
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtWebView 1.1
ApplicationWindow {
id: window
width: 360
height: 640
visible: true
title: "Qt Android Browser"
property string jsMessage: "等待JavaScript消息..."
property bool isPageLoaded: false
property int loadProgress: 0
// 本地页面URL
property url localPageUrl: "file:///android_asset/localpage.html"
header: ToolBar {
height: 50
background: Rectangle {
color: "#2196F3"
}
Row {
anchors.fill: parent
spacing: 5
padding: 5
Button {
width: 80
height: 40
text: "加载本地页"
onClicked: loadLocalPage()
background: Rectangle {
color: parent.down ? "#1976D2" : "#2196F3"
radius: 3
}
contentItem: Text {
text: parent.text
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 12
}
}
Button {
width: 80
height: 40
text: "测试JS"
onClicked: testJavaScript()
enabled: isPageLoaded
background: Rectangle {
color: parent.enabled ? (parent.down ? "#1976D2" : "#2196F3") : "#cccccc"
radius: 3
}
contentItem: Text {
text: parent.text
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 12
}
}
Button {
width: 80
height: 40
text: "改变背景"
onClicked: changeBackground()
enabled: isPageLoaded
background: Rectangle {
color: parent.enabled ? (parent.down ? "#1976D2" : "#2196F3") : "#cccccc"
radius: 3
}
contentItem: Text {
text: parent.text
color: "white"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 12
}
}
}
}
Column {
anchors.fill: parent
anchors.topMargin: 50
// 状态显示区域
Rectangle {
width: parent.width
height: 60
color: isPageLoaded ? "#E8F5E8" : "#FFF3CD"
Column {
anchors.fill: parent
anchors.margins: 5
spacing: 2
Label {
text: isPageLoaded ? "✅ 页面已加载完成" : "⏳ 页面加载中..."
color: isPageLoaded ? "green" : "#856404"
font.pixelSize: 12
font.bold: true
}
Label {
text: "加载进度: " + loadProgress + "%"
color: isPageLoaded ? "green" : "#856404"
font.pixelSize: 10
}
Label {
width: parent.width
text: jsMessage
color: isPageLoaded ? "green" : "#856404"
font.pixelSize: 10
elide: Text.ElideRight
wrapMode: Text.WrapAnywhere
maximumLineCount: 2
}
}
}
// WebView
WebView {
id: webView
width: parent.width
height: parent.height - 60
url: localPageUrl
onLoadingChanged: {
console.log("=== 加载状态变化 ===")
console.log("状态:", loadRequest.status)
console.log("URL:", loadRequest.url)
if (loadRequest.status === WebView.LoadStartedStatus) {
isPageLoaded = false
loadProgress = 0
jsMessage = "页面开始加载..."
console.log("🚀 开始加载页面")
}
else if (loadRequest.status === WebView.LoadSucceededStatus) {
isPageLoaded = true
loadProgress = 100
jsMessage = "✅ 页面加载成功!"
console.log("✅ 页面加载成功")
}
else if (loadRequest.status === WebView.LoadFailedStatus) {
isPageLoaded = false
jsMessage = "❌ 页面加载失败"
console.log("❌ 页面加载失败")
// 如果本地页面加载失败,尝试使用在线页面作为备选
loadFallbackPage()
}
}
onLoadProgressChanged: {
console.log("加载进度:", loadProgress + "%")
window.loadProgress = loadProgress
if (loadProgress < 100) {
jsMessage = "加载中... " + loadProgress + "%"
isPageLoaded = false
} else if (loadProgress === 100) {
isPageLoaded = true
jsMessage = "✅ 页面加载完成"
}
}
onUrlChanged: {
console.log("URL改变:", url)
// 处理来自JavaScript的消息
if (url.toString().startsWith('qt://')) {
handleJSMessage(url)
// 阻止实际导航,保持当前页面
webView.url = Qt.binding(function() { return localPageUrl })
}
}
}
}
// 加载本地页面
function loadLocalPage() {
console.log("=== 加载本地页面 ===")
isPageLoaded = false
loadProgress = 0
jsMessage = "正在加载本地页面..."
webView.url = localPageUrl
}
// 加载备用的在线页面(如果本地页面失败)
function loadFallbackPage() {
console.log("尝试加载备用页面...")
// 使用一个简单的在线测试页面
webView.url = "https://httpbin.org/html"
}
// 处理来自JavaScript的消息
function handleJSMessage(url) {
var urlString = url.toString()
console.log("收到JS消息:", urlString)
if (urlString.includes('message?')) {
var message = decodeURIComponent(urlString.split('data=')[1] || '未知消息')
jsMessage = "📩 来自JS: " + message
console.log("解析出的消息:", message)
}
}
// 测试JavaScript功能
function testJavaScript() {
if (!isPageLoaded) {
jsMessage = "❌ 页面尚未加载完成"
return
}
console.log("=== 开始JavaScript测试 ===")
jsMessage = "🚀 正在调用JavaScript..."
// 测试1: 调用receiveFromQt函数
var message = "Hello from Qt! 时间: " + new Date().toLocaleTimeString()
var jsCode = "window.receiveFromQt('" + message + "')"
webView.runJavaScript(jsCode, function(result) {
console.log("receiveFromQt返回值:", result)
jsMessage = "✅ JS函数调用成功: " + (result || "无返回值")
})
}
// 改变页面背景颜色
function changeBackground() {
if (!isPageLoaded) return
var colors = ["linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)",
"linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)",
"linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"]
var randomColor = colors[Math.floor(Math.random() * colors.length)]
var jsCode = "window.changeBackground('" + randomColor + "')"
webView.runJavaScript(jsCode, function(result) {
console.log("changeBackground返回值:", result)
jsMessage = "🎨 背景颜色已更改"
})
}
// 组件加载完成后的初始化
Component.onCompleted: {
console.log("=== 应用程序启动 ===")
console.log("本地页面URL:", localPageUrl)
// 自动加载本地页面
loadLocalPage()
}
}
3. 更新项目文件
AndroidBrowser.pro:
QT += quick webview
CONFIG += c++11
SOURCES += \
main.cpp
RESOURCES += qml.qrc
# 添加Android资产文件
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
# 确保资产文件被包含
android {
ANDROID_EXTRA_LIBS = $$PWD/android/libs/*
}
4. 将HTML文件添加到Android资产
将 localpage.html 文件放在:
项目目录/android/assets/localpage.html
如果 android/assets 目录不存在,请创建它。
主要改进
- 使用本地HTML文件 - 避免网络连接问题
- 完整的双向通信 - Qt调用JS和JS调用Qt
- 更好的错误处理 - 备用方案和状态反馈
- 可视化界面 - 本地页面有完整的控制面板
- 详细的日志 - 便于调试
现在运行应用应该能够正常加载本地页面,并且JavaScript交互应该可以正常工作。
浙公网安备 33010602011771号