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 目录不存在,请创建它。

主要改进

  1. 使用本地HTML文件 - 避免网络连接问题
  2. 完整的双向通信 - Qt调用JS和JS调用Qt
  3. 更好的错误处理 - 备用方案和状态反馈
  4. 可视化界面 - 本地页面有完整的控制面板
  5. 详细的日志 - 便于调试

现在运行应用应该能够正常加载本地页面,并且JavaScript交互应该可以正常工作。

posted @ 2025-10-10 18:13  远方是什么样子  阅读(7)  评论(0)    收藏  举报