【问题标题】:QDataStream serialize pointerQDataStream 序列化指针
【发布时间】:2014-08-12 07:09:41
【问题描述】:

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

我用这个例子启发了自己(很多):Fridge magnets
在此配置中,由于QByteArray 存储在 mime 数据中,通过QDataStream 序列化,带来了拖动对象的信息。

我希望乐谱在被放置在占用的码头上时,使“驻留”乐谱进入他的原始空间。我想我可以通过拥有一个包含其原始 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();
}

我无法为QDataStream 和Dock * 重载> 运算符,因为我发现使用指针执行此操作的唯一方法是存储实际数据。但问题是我不想要数据,我只需要指针!

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

【问题讨论】:

  • 所以我改变了对这个主题的处理方法,并将一个数字 (int) 分配给我的码头,并将这个数字提供给码头。它现在有点工作(其他问题,但我认为它们与此无关)但是有一个想法来序列化这个指针肯定会很好^^

标签: c++ qt qdatastream


【解决方案1】:

如果我理解正确,您想序列化一个指向停靠栏的指针吗?我真的不明白你为什么要这样做。

这个呢:

  • 让你的 mime-data 只是一个指向分数的指针,比如itemData.fromRawData(reinterpret_cast&lt;char*&gt;(&amp;score, sizeof(Score&amp;ast;)));
  • 在 dropEvent()
    • 使用 event->source() 获取 Dock 的指针
    • 使用另一个流和相反的过程从 mimeData 中提取指针,或者只是一个 uber-cast 联合: union {char chr[8]; Score &ast;score} scorecast; memcpy(scorecast.chr, itemData.data(), sizeof(Score&ast;)); ,然后通过 scorecast.score 访问您的分数指针

这也可以让您免于发送分数中的所有数据...

最后一个想法:QByteArray.data() 为构成指针的数据提供一个 const char *。怎么样 *reinterpret_cast(imageData.data()) 让你的指针回来?

最后一秒读到了我自己的 QDataStream 编组代码:

QDataStream & operator << (QDataStream & s, const Score * scoreptr)
{
    qulonglong ptrval(*reinterpret_cast<qulonglong *>(&scoreptr));
    return s << ptrval;
}
QDataStream & operator >> (QDataStream & s, Score *& scoreptr)
{
    qulonglong ptrval;
    s >> ptrval;
    scoreptr = *reinterpret_cast<Score **>(&ptrval);
    return s;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-01
    • 2012-04-25
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多