gpt4 book ai didi

c++ - QDataStream 序列化指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:53:21 29 4
gpt4 key购买 nike

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

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

我想要一个 Score,当它落在一个被占用的 Dock 上时,让“驻留”的 Score 回到他原来的空间。我以为我可以通过包含其原始 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 * 重载 << 和 >> 运算符,因为我发现使用指针执行此操作的唯一方法是存储实际数据。但问题是我不想要数据,我只需要指针!

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

最佳答案

如果我没理解错的话,您想序列化一个指向停靠栏的指针吗?我真的不明白你为什么要用这种艰难的方式来做这件事。

这个怎么样:

  • 让你的 mime-data 只是一个指向乐谱的指针,比如 itemData.fromRawData(reinterpret_cast<char*>(&score, sizeof(Score*)));
  • 在 dropEvent() 中
    • 使用 event->source() 获取 dock 的指针
    • 使用另一个流和反向过程从 mimeData 或简单的 uber-cast union 中提取指针:
      union {char chr[8]; Score *score} scorecast;
      memcpy(scorecast.chr, itemData.data(), sizeof(Score*));
      ,然后通过 scorecast.score 访问你的得分指针

这也可以避免您发送 Score-to-drop 中的所有数据......

只是最后一个想法: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;
}

关于c++ - QDataStream 序列化指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24345681/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com