You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QRemoteObject跨进程信号无法触发,求排查问题原因

问题描述

我是Qt新手,学习使用QRemoteObject实现跨进程数据共享,根据文档编写了.rep文件并集成到两个进程中,但跨进程信号传递失效:按下APP1的F2键,APP2中绑定的lambda未触发;按下APP2的F2键,APP1中的lambda也未触发。

相关代码

.rep文件内容

class SharedObject
{
    SIGNAL(signalAPP1(QString text))
    SIGNAL(signalAPP2(QString text))
};

app1.h

#include "rep_sharedobject_source.h"

class SharedObject : public SharedObjectSource
{
    Q_OBJECT 
 public:
signals:
    void signalAPP1(QString text);
    void signalAPP2(QString text);
};

QT_BEGIN_NAMESPACE
namespace Ui { class APP1Class; };
QT_END_NAMESPACE

class APP1 : public QMainWindow
{
    Q_OBJECT
public:
    SharedObject* sharedObject = nullptr;
    QRemoteObjectHost srcNode;
    Ui::APP1Class *ui;

    APP1(QWidget *parent = nullptr) : QMainWindow(parent), ui(new Ui::APP1Class())
    {
        ui->setupUi(this);

        sharedObject = new SharedObject();
        sharedObject->setObjectName("sharedObject");
        srcNode.setHostUrl(QUrl(QStringLiteral("local:sharedObject")));
        srcNode.enableRemoting(sharedObject);

        QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this);
        connect(shortcut, &QShortcut::activated, [=] {
            qDebug() << "emiting...";
            emit sharedObject->signalAPP1("hello from APP1");
        });

        connect(sharedObject, &SharedObject::signalAPP2, this, [=](QString text)  {
            qDebug() << "signalAPP2! text:" << text;
        });
    }
};

app2.h

#include "rep_sharedobject_replica.h"

QT_BEGIN_NAMESPACE
namespace Ui { class APP2Class; };
QT_END_NAMESPACE

class APP2 : public QMainWindow
{
    Q_OBJECT
public:
    Ui::APP2Class *ui;
    QSharedPointer<SharedObjectReplica> ptr;
    QRemoteObjectNode repNode;

    APP2(QWidget *parent = nullptr) : QMainWindow(parent), ui(new Ui::APP2Class())
    {
        ui->setupUi(this);
 
        repNode.connectToNode(QUrl(QStringLiteral("local:sharedObject")));
        ptr.reset(repNode.acquire<SharedObjectReplica>());

        connect(ptr.data(), &SharedObjectReplica::initialized, this, [=]
        {
            qDebug() << "conected...";

            connect(ptr.data(), &SharedObjectReplica::signalAPP1, this, [](QString text) {
                qDebug() << "signalAPP1! text:" << text;
            });
        });  

        QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this);
        connect(shortcut, &QShortcut::activated, [=] {
            QString str = "hello from APP2";
            emit ptr.data()->signalAPP2(str);
        });
    }
};

问题分析与解决

1. 自定义信号与生成代码冲突

SharedObjectSource是由.rep文件自动生成的类,已经包含了signalAPP1和signalAPP2的信号定义。你手动在子类SharedObject中重复声明信号,导致实际发出的信号不是QRemoteObject框架需要的实例,跨进程同步失效。

修复: 删除SharedObject类中手动添加的signals:块,直接使用父类提供的信号:

#include "rep_sharedobject_source.h"

class SharedObject : public SharedObjectSource
{
    Q_OBJECT 
public:
    // 无需手动声明信号,父类已包含
};

2. 双向信号未正确声明

QRemoteObject默认仅同步Source端发出的信号到Replica,Replica发出的信号不会自动转发回Source。需要在.rep文件中将需要双向传递的信号标记为REPLICASIGNAL。

修复: 修改.rep文件:

class SharedObject
{
    SIGNAL(signalAPP1(QString text))
    REPLICASIGNAL(signalAPP2(QString text))
};

标记为REPLICASIGNAL后,框架会自动处理Replica到Source的信号转发。

3. 额外检查点

  • 确保先启动APP1(Source端),再启动APP2(Replica端),否则APP2无法连接到共享节点
  • 检查APP2控制台是否输出conected...,如果没有说明节点连接失败,确认URLlocal:sharedObject在两个进程中完全一致
  • 确认编译时没有因rep文件生成的头文件报错,保证代码正确引用了自动生成的类

内容的提问来源于stack exchange,提问作者Cesar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:48:07