C++ QDataStream序列化指针

C++ QDataStream序列化指针,c++,qt,qdatastream,C++,Qt,Qdatastream,我正在用Qt实现一个小接口。在我目前正在进行的步骤中,我有分数(自定义类),我可以在只能容纳一个分数的Dock(同样,自定义类)上移动 我用这个例子启发了自己:。 在这种配置中,由于通过QDataStream进行序列化,存储在mime数据中的QByteArray带来了被拖动对象的信息 我想要一个分数,当落在一个被占用的码头上时,让“居住”分数回到他原来的空间。我想我可以通过拥有一个包含其原始Dock地址的属性来实现这一点,但我无法将此指针存储在数据流中 下面是我的部分代码: /* Part of

我正在用
Qt
实现一个小接口。在我目前正在进行的步骤中,我有分数(自定义类),我可以在只能容纳一个分数的Dock(同样,自定义类)上移动

我用这个例子启发了自己:。
在这种配置中,由于通过
QDataStream
进行序列化,存储在mime数据中的
QByteArray
带来了被拖动对象的信息

我想要一个分数,当落在一个被占用的码头上时,让“居住”分数回到他原来的空间。我想我可以通过拥有一个包含其原始Dock地址的属性来实现这一点,但我无法将此指针存储在数据流中

下面是我的部分代码:

/* Part of the definition of my classes */

class Score : public QLabel
{
    Q_OBJECT

    protected:
        QString labelText;
        Dock * dock;
        QImage * click;
};

class Dock : public QFrame
{
Q_OBJECT

protected:
    Score * score;
};


/* And the 4 methods allowing the drag and drop */
void Dock::mousePressEvent(QMouseEvent *event)
{
    Score * child = dynamic_cast<Score *>(childAt(event->pos()));
    if (!child)
        return;

    QPoint hotSpot = event->pos() - child->pos();

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    dataStream << child->getLabelText() << child->getClick() << QPoint(hotSpot);

    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-score", itemData);
    mimeData->setText(child->getLabelText());

    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(QPixmap::fromImage(*child->getClick()));
    drag->setHotSpot(hotSpot);

    child->hide();

    if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
        child->close();
    else
        child->show();
}

void Dock::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-score"))
    {
        if (children().contains(event->source()))
        {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
            event->acceptProposedAction();
    }
    else
        event->ignore();

}

void Dock::dragMoveEvent(QDragMoveEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-score"))
    {
        if (children().contains(event->source()))
        {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
            event->acceptProposedAction();
    }
   else
        event->ignore();
}

void Dock::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("application/x-score"))
    {
        const QMimeData *mime = event->mimeData();

        QByteArray itemData = mime->data("application/x-score");
        QDataStream dataStream(&itemData, QIODevice::ReadOnly);

        QString text;
        QImage * img;
        QPoint offset;
        dataStream >> text >> img >> offset;

        Score * newScore = new Score(text, this);
        newScore->show();
        newScore->setAttribute(Qt::WA_DeleteOnClose);

        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
            event->acceptProposedAction();

    }
    else
        event->ignore();

    static_cast<FrameCC *>(parentWidget())->calcTotal();
}
/*我的类定义的一部分*/
班级分数:公共QLabel
{
Q_对象
受保护的:
QString标签文本;
船坞*船坞;
QImage*点击;
};
类驳接:公共QFrame
{
Q_对象
受保护的:
分数*分数;
};
/*以及允许拖放的4种方法*/
void Dock::MousePresseEvent(QMouseEvent*事件)
{
分数*child=dynamic_cast(childAt(event->pos());
如果(!child)
返回;
QPoint热点=事件->位置()-子->位置();
QByteArray项目数据;
QDataStream数据流(&itemData,QIODevice::WriteOnly);
dataStream getLabelText()getClick()setData(“应用程序/x分数”,itemData);
mimeData->setText(child->getLabelText());
QDrag*拖动=新的QDrag(本);
拖动->设置mimeData(mimeData);
拖动->setPixmap(QPixmap::fromImage(*child->getClick());
拖动->设置热点(热点);
子->隐藏();
如果(拖动->执行(Qt::MoveAction)=Qt::MoveAction)
子->关闭();
其他的
子->显示();
}
void Dock::dragEnterEvent(QDragEnterEvent*事件)
{
if(事件->mimeData()->hasFormat(“应用程序/x分数”))
{
if(children().contains(event->source()))
{
事件->setDropAction(Qt::MoveAction);
事件->接受();
}
其他的
事件->AcceptProposeAction();
}
其他的
事件->忽略();
}
无效驳接::dragMoveEvent(QDragMoveEvent*事件)
{
if(事件->mimeData()->hasFormat(“应用程序/x分数”))
{
if(children().contains(event->source()))
{
事件->setDropAction(Qt::MoveAction);
事件->接受();
}
其他的
事件->AcceptProposeAction();
}
其他的
事件->忽略();
}
void Dock::dropEvent(QDropEvent*事件)
{
if(事件->mimeData()->hasFormat(“应用程序/x分数”))
{
常量QMimeData*mime=event->mimeData();
QByteArray itemData=mime->data(“应用程序/x分数”);
QDataStream数据流(&itemData,QIODevice::ReadOnly);
QString文本;
QImage*img;
点偏移;
数据流>>文本>>img>>偏移量;
分数*newScore=新分数(文本,本);
新闻核心->显示();
新闻核心->设置属性(Qt::WA_DeleteOnClose);
如果(事件->源()==此){
事件->setDropAction(Qt::MoveAction);
事件->接受();
}
其他的
事件->AcceptProposeAction();
}
其他的
事件->忽略();
static_cast(parentWidget())->calcTotal();
}
我无法为
QDataStream
和Dock*重载>操作符,因为我发现使用指针实现这一点的唯一方法是存储实际数据。但问题是我不需要数据,我只需要指针


我想你有一个想法,即使这意味着我必须重新考虑做这件事的方式,我也很乐意听到。谢谢大家!

如果我理解正确,您想序列化一个指向dock的指针吗?我真的不明白你为什么这么辛苦

那么这个呢:

  • 将mime数据简化为指向分数的指针,如
    itemData.fromRawData(重新解释cast(&score,sizeof(score&ast;))
  • 在dropEvent()中
    • 使用事件->源()获取dock的指针
    • 使用另一个流和反向过程从mimeData或uber cast联合提取指针:
      
      联合{char chr[8];Score&ast;Score}scorecast;
      memcpy(scorecast.chr,itemData.data(),sizeof(Score&ast;);
      
      ,然后通过scorecast.score访问分数指针
这也可以避免你将分数中的所有数据发送给drop

最后想一想:QByteArray.data()为组成指针的数据提供一个常量char*。如何使用*reinterpret_cast(imageData.data())将指针取回来

最后一个想法是阅读我自己的QDataStream编组代码:

QDataStream和操作员(QDataStream&s、Score*&scoreptr)
{
曲龙龙;
s>>ptrval;
scoreptr=*重新解释演员阵容(&ptrval);
返回s;
}

因此,我改变了我在这个问题上的做法,将一个数字(int)赋予我的码头,并将这个数字赋予码头。它现在可以工作了(其他问题,但我不认为它们与此相关),但如果能有一个序列化这个指针的想法,那就太好了^^