QWebChannel 加载 html 界面分离底层逻辑

前提,qt 提供的例程依赖,websocket ,这里不包含websokcet 

在同一进程中,实现底层 qt代码 与 html 界面分离。

一、 定义类  MyChannel  实现接口定义。

class MyChannel : public QObject
{
    Q_OBJECT
public:
    explicit MyChannel(QObject *parent = 0);

    Q_INVOKABLE void doSomeThing();
    Q_INVOKABLE void receiveText(const QString& txt);

signals:
    void sendText(QString txt);

public slots:
};


MyChannel::MyChannel(QObject *parent) : QObject(parent)
{
    QTimer::singleShot(3000,this,&MyChannel::doSomeThing);
}

void MyChannel::doSomeThing()
{
    emit sendText("doSomeThing!!!");
}

void MyChannel::receiveText(const QString& txt)
{
    qDebug() << txt;
    QTimer::singleShot(1000,this,&MyChannel::doSomeThing);
}

这里需要加上  Q_INVOKABLE 被调用,否则可能会报错,未定义  js: Uncaught TypeError: MyChannel.receiveText is not a function

二、主窗口添加 webView 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    webView(nullptr)
{
    ui->setupUi(this);
    webView = new QWebEngineView(this);
    setCentralWidget(webView);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setWebChannel(QWebChannel* ch)
{
    webView->page()->setWebChannel(ch);
    // 获取当前应用程序的运行目录
    QString currentDir(QCoreApplication::applicationDirPath());

    qDebug() << currentDir;

    // 构建HTML文件的相对路径
    QString relativePath = "index.html";
    QUrl url = QUrl::fromLocalFile(QDir(currentDir).absoluteFilePath(relativePath));

    // 加载HTML文件
    webView->load(url);

    // 设置窗口自适应大小
    webView->showMaximized();
}

需要注意,setWebChannel(ch) 设置通道,在 load("xx.html") 之前,确保通道被创建。

三、 main 函数 

    QApplication a(argc, argv);

    QWebChannel channel;  
    MyChannel myCh;
    channel.registerObject(QStringLiteral("MyChannel"), &myCh);


    MainWindow w;
    w.setWebChannel(&channel);
    w.show();
registerObject 将 MyChannel 类注册给 channel,再将 设只给 web->page(),

四、设置 index.html

            function output(message)
            {
                var output = document.getElementById("output");
                output.innerHTML = output.innerHTML + message + "\n";
            }
            window.onload = function() {
                output("WebSocket connected, setting up QWebChannel.");
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    // make MyChannel object accessible globally
                    window.MyChannel = channel.objects.MyChannel;

                    document.getElementById("send").onclick = function() {
                        var input = document.getElementById("input");
                        var text = input.value;
                        if (!text) {
                            return;
                        }

                        output("Sent message: " + text);
                        input.value = "";
                        MyChannel.receiveText(text);
                    }

                    MyChannel.sendText.connect(function(message) {
                        output("Received message: " + message);
                    });
                    MyChannel.doSomeThing();
                    MyChannel.receiveText("Client connected, ready to send/receive messages!");
                    output("Connected to WebChannel, ready to send/receive messages!");
                });
            }

这里的  QWebChannel(qt.webChannelTransport ... 是默认写法,由 webEngine 设置的通道,

Transport 如果要自定义,需要添加 sent(), onmessage() 方法。

从官方例程中可以看到,  QWebChannelAbstractTransport 【官】

class QJsonObject;
class Q_WEBCHANNEL_EXPORT QWebChannelAbstractTransport : public QObject
{
    Q_OBJECT
public:
    explicit QWebChannelAbstractTransport(QObject *parent = Q_NULLPTR);
    virtual ~QWebChannelAbstractTransport();

public Q_SLOTS:
    virtual void sendMessage(const QJsonObject &message) = 0;

Q_SIGNALS:
    void messageReceived(const QJsonObject &message, QWebChannelAbstractTransport *transport);
};

结果验证:

 控制台输出:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值