Qt中Webassembly

Qt webassembly
请问各位有办法通过qt-webassembly编译器在网页中实现串口通信吗。目前画了个框架,但是发现webassembly不支持QSerialPort

img

该回答引用GPT3.5:是的,你所说的是正确的。Qt WebAssembly 编译器目前不支持 QSerialPort 模块,因此无法直接在 WebAssembly 中实现串口通信。

由于 WebAssembly 的安全限制,浏览器中的 JavaScript 环境无法直接访问本地的串口设备。因此,在 WebAssembly 中实现串口通信是一个相对复杂的问题。

然而,你可以考虑使用其他的解决方案来实现在网页中的串口通信。一种常见的方法是通过 WebSockets 或者 WebRTC 来建立浏览器和服务器之间的通信,然后在服务器端实现串口通信,将数据传输到浏览器中。

以下是一个基本的思路:

  1. 在服务器端,使用 Qt 来实现串口通信功能,可以使用 QSerialPort 模块。
  2. 在服务器端,使用 WebSockets 或者 WebRTC 与浏览器进行通信,将串口数据传输到浏览器中。
  3. 在浏览器端,使用 JavaScript 处理接收到的串口数据,并在网页中进行相应的处理。

需要注意的是,这种方案需要你有一个运行服务器端代码的服务器,并且需要一些后端开发的知识。

希望这个解决方案对你有帮助!如果还有其他问题,请随时提问。

  • 关于该问题,我找了一篇非常好的博客,你可以看看是否有帮助,链接:Qt中搭建WebAssembly
  • 同时,你还可以查看手册:qt WebEngineAction 中的内容
  • 除此之外, 这篇博客: Qt for WebAssembly显示QML实例中的 1.2.4.2. 创建CDataClass类 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • CDataClass是Qt类,有以下功能:

    • 定义多线程,把数据处理移到线程里面处理
    • 定义命令处理函数,供页面调用
    • 定义发送命令信号,把从页面接受的命令发送到线程里面
    • 定义接收处理结果槽函数
    • 定义发送处理结果信号,把从数据返回到页面

    头文件

    class CDataClass;
    typedef void (CDataClass::*PTRFUN)(const CmdData &argcs); //函数指针,用于分发命令
    
    class CDataClass : public QObject
    {
        Q_OBJECT
    public:
        explicit CDataClass(QObject *parent = nullptr);
        ~CDataClass()
        {
            mWorkerThread.quit();
            mWorkerThread.wait();
        }
    
        Q_INVOKABLE void handleCmdDataQML(const QString &func, const QStringList &keys,
                                          const QStringList &values); //供页面调用的命令函数,分发到具体的处理函数
        Q_INVOKABLE void checkUserPwd(const CmdData &argcs); //验证输入的用户名和密码
        Q_INVOKABLE void getUsersData(const CmdData &argcs); //查询用户信息
        Q_INVOKABLE void addUsersData(const CmdData &argcs); //增加用户信息
        Q_INVOKABLE void editUsersData(const CmdData &argcs); //编辑用户信息
        Q_INVOKABLE void getLogsData(const CmdData &argcs); //查询日志信息
    
    signals:
    	//把页面接受的命令,发送到线程里面的槽函数
        void operate(const int type, const QString &func, const QString &cmd);
        //把线程里面的处理结果返回给页面
        void operateResult(const RstData &rstData);
     	//登录结果信号
        void signalLoginResult(const bool &result);
        //消息显示信号
        void signalMeaasge(const QString &msg);
    
    public slots:
         void handleResults(const RstData &rstData); //接受线程里面处理结果
    
    private:
        QThread mWorkerThread; //定义处理线程
        QMap<QString, PTRFUN> mFuncMap; //定义命令处理函数映射关系
    };
    

    源文件

    CDataClass::CDataClass(QObject *parent) : QObject(parent)
    {
        Worker *worker = new Worker; //定义数据处理类
        worker->moveToThread(&mWorkerThread); //把数据处理类移到线程
        connect(&mWorkerThread, &QThread::finished, worker, &QObject::deleteLater);
        //定义信号槽,把命令发送到线程里面的槽函数
        connect(this, &CDataClass::operate, worker, &Worker::doWork);
        //定义信号槽,接收线程里面发送的结果
        connect(worker, &Worker::resultReady, this, &CDataClass::handleResults);
        mWorkerThread.start(); //开启线程
    
    	//初始化命令处理函数映射关系
        mFuncMap["checkUserPwd"] = &CDataClass::checkUserPwd;
        mFuncMap["getUsersData"] = &CDataClass::getUsersData;
        mFuncMap["addUsersData"] = &CDataClass::addUsersData;
        mFuncMap["editUsersData"] = &CDataClass::editUsersData;
        mFuncMap["getLogsData"] = &CDataClass::getLogsData;
    }
    
    void CDataClass::handleResults(const RstData &rstData)
    {
        if (rstData.func == "checkUserPwd")
        {
            if (rstData.result.size() > 0)
            {
                emit signalLoginResult(true);
            }
            else
            {
                emit signalLoginResult(false);
            }
        }
        else
        {
            emit operateResult(rstData);
        }
    }
    
    void CDataClass::handleCmdDataQML(const QString &func, const QStringList &keys,
                                      const QStringList &values)
    {
        qDebug() << "[CDataClass::handleCmdDataQML]" << func << keys << values;
        CmdData argcs;
        argcs.func = func;
        if (keys.size() != values.size())
        {
            return;
        }
        for (int var = 0; var < keys.size(); ++var)
        {
            argcs.params[keys[var]] = values[var];
        }
        handleCmdData(argcs);
    }
    
    void CDataClass::handleCmdData(const CmdData &argcs)
    {
        RstData rstData;
        if (!mFuncMap.contains(argcs.func))
        {
            rstData.retCode = RET_NOFUNC;
            rstData.msg = RET_MSG[rstData.retCode];
            rstData.func = argcs.func;
            emit signalMeaasge(rstData.msg);
            return;
        }
    
        //(this->*mFuncMap[argcs.func])(argcs);return;
        // 因为Qt for WebAssembly现在不支持多线程和数据库访问,所以这里注释掉,下面是模拟生成返回数据代码
        rstData.retCode = RET_OK;
        rstData.msg = RET_MSG[rstData.retCode];
        rstData.func = argcs.func;
        for (int i = 0; i < 100000; ++i)
        {
            QVector<QString> tmp(10);
            tmp[0] = QString::number(i+1);
            tmp[1] = QString("test%1").arg(i+1);
            tmp[2] = tmp[1];
            tmp[7] = "1";
            tmp[8] = "";
            tmp[9] = "";
            rstData.result.push_back(tmp);
        }
        handleResults(rstData);
    }