我有一个对象数组,我想发出一个包含这些对象中的一个的信号。但信号不能是指针

I have an array of objects, and I want to emit a signal containing a single one of these objects. But the signal can't be a pointer

本文关键字:一个 信号 一个对象 不能 指针 对象 数组 包含这      更新时间:2023-10-16

我正在开发一个GUI,它将控制不同的机械臂。GUI 所需的功能之一是它必须能够发送轨迹命令,其中轨迹包含可变数量的目的地(称为"设定点")。每个设定点是一系列关节角度,机器人的每个自由度一个角度。

我定义了以下类来包含单个轨迹:

class trajectory{
public:
    QString trajName;
    int DOF;
    int count;
    double** fullTraj;
    QString getTrajString(trajectory);
    trajectory(const QString&, const int&, const int&);
    trajectory operator = (const trajectory);
    ~trajectory();
};

其中trajName是轨迹的名称,count是该轨迹的设定点数,DOF是自由度,fullTraj将是一个维度计数为x DOF的2d数组。下面是构造函数、复制构造函数、赋值运算符和析构函数:

trajectory::trajectory (const QString& name, const int& trajcount, const int& trajDOF){
    trajName = name;
    count = trajcount;
    DOF = trajDOF;
    fullTraj = new double*[count];
}
trajectory::trajectory(const trajectory &traj){
    trajName = traj.trajName;
    count = traj.count;
    DOF = traj.DOF;
    fullTraj = new double*[count];
    for (int row = 0; row < count; row++){
        for (int column = 0; column<DOF; column++){
            fullTraj[row][column] = traj.fullTraj[row][column];
        }
    }
}
trajectory trajectory:: operator = ( const trajectory oldtraj){
    trajectory newTraj;
    newTraj.count = oldtraj.count;
    newTraj.DOF = oldtraj.DOF;
    newTraj.trajName = oldtraj.trajName;
    newTraj.fullTraj = new double*[newTraj.count];
    return newTraj;
}
trajectory::~trajectory(){
    delete fullTraj;
}

QString trajectory::getTrajString(trajectory* traj){
    QString trajString = "' " + traj->trajName + " 'n";
    for (int row = 0; row <traj->count; row++){
        trajString += "t [ ";
        for (int column = 0; column < traj->DOF; column++){
            trajString += "  " + QString::number(traj->fullTraj[row][column],'f',2 );
        }
        trajString += " ] n";
    }
    return trajString;
}

我想创建一个轨迹数组,我尝试这样做:

在我的头文件中:

trajectory* trajectories;

在CPP中:

 for (int i = 0; i<numberOfTrajs; i++){
     trajectories[i] =  new trajectory("Empty Trajectory", 0,0);
 }

当用户想要将机器人发送到特定信号时,他单击一个按钮。单击按钮时,我想发出具有用户想要发送的特定轨迹的信号。我可以这样做:

emit sigSendTrajCommand(trajectories[i]) 

其中 i 指示要发送的轨迹。但是以指针的形式发射信号似乎是错误的。无论如何,我都尝试将其作为指针发送,但是插槽接收的轨迹充满了垃圾,即使发出的轨迹不是(我使用 qDebug 验证了这一点,我可以在发出信号之前立即从轨迹中打印值,但应用程序崩溃,我尝试在插槽中打印值)。

这是发出具有特定轨迹的信号的插槽,稍后我将将其添加到轨迹数组中:

void robotTrajWidget::on_sendTraj_clicked()
{
   ui->trajDisplay->moveCursor(QTextCursor::Start);
   ui->trajDisplay->insertPlainText(QTime::currentTime().toString() + "tMoving robot to '" + thistrajName + "':n");
   getTrajectory();
   emit sigSendTrajectory(myTraj);
   delete myTraj->fullTraj;
}

其中 getTrajectory(); 从 QTableWidget 中读取值:

void robotTrajWidget::getTrajectory(){
        myTraj = new trajectory(thistrajName, trajCount, newDOF);
        for (int i = 0; i<trajCount; i++){
            myTraj->fullTraj[i] = new double[newDOF];
        }
        for (int row = 0; row<trajCount; row++){
            for (int column = 0; column<newDOF; column++){
                myTraj->fullTraj[row][column] = trajTable->item(row,column)->text().toDouble();
            }
        }
    }

当插槽接收轨迹时,我希望能够简单地将新轨迹添加到轨迹数组中。我尝试这样做:

void robotTabWidget::slotOnNewTrajButton(trajectory newTraj){

    trajectories[trajCount] = newTraj;
    setButtons[trajCount]->setText(newTraj.trajName);
    setButtons[trajCount]->setObjectName(newTraj.trajName);
    connect(setButtons[trajCount],SIGNAL(clicked(bool)),this,SLOT(onSetButtonsClicked(bool)));
    ui->jointsetPointLayout->addWidget(setButtons[trajCount],buttonRow,buttonColumn);
    if (buttonColumn == 3){
        buttonRow +=1;
        buttonColumn = 0;
    }
    else buttonColumn +=1;
    trajCount+=1;
}

但这给了我一个错误:

error: cannot convert 'trajectory' to 'trajectory*' in assignment
 trajectories[trajCount] = newTraj;
                         ^

我想将轨迹存储在数组中,然后能够在用户想要时发出单个轨迹作为信号。基本上,我想将它们作为非指针发送,将它们存储在指针数组中,然后再次将它们作为非指针发送。我该怎么做?

编辑:让我再澄清一点。最初,用户从文本文件加载轨迹。我希望用户能够存储多个轨迹,所以我有一个轨迹数组,每个加载的轨迹都添加到这个轨迹数组中。然后,当用户想要将机器人发送到轨迹时,我想从阵列中挑选出轨迹并发出该阵列作为信号。该信号将进入无法访问整个轨迹阵列的插槽,因此发送轨迹索引将不起作用。

发送轨迹 ID(数字)而不是指向轨迹实例的指针怎么样?并具有某种轨迹容器将轨迹 ID 映射到指针。像这样:

typedef unsigned long long TrajectoryID;
trajectory* TrajectoryContainer::getTrajectory(TrajectoryID id);

编辑

基本上,我想将它们作为非指针发送,将它们存储在数组中 的指针,然后再次将它们作为非指针发送。

这确实是一个糟糕的方法。将 na 对象作为"非指针"(即值表示)发送实际上意味着复制它。而不是存储指向这个新创建(复制)实例的指针,而不是让这个实例在插槽范围的末尾被删除?这将使指针立即无效。这真的不是要走的路。请考虑使用该 ID。

编辑 2

另一个想法:从QObject派生轨迹类。您应该能够通过指针比发送轨迹。

如果您真的想通过信号发送自定义对象 - 请尝试Q_DECLARE_METATYPE() .应该很容易实现。

个人观点:通过信号发送指针是可以的,只要你跟踪这个指针以防止泄漏(例如,一个容器,保持所有指针的发送;或者在创建后立即给每个对象一个父对象)。不过,提到的使用 ID 的想法似乎是一种更优雅的方式。我什至会说这是正确的方式,但每个人都有自己的理由。