2

との小さなインターフェースを実装していますQt。現在取り組んでいるステップでは、スコア (カスタム クラス) があり、スコアを 1 つだけ保持できるドック (カスタム クラス) に移動できます。

私はこの例で (たくさん) インスピレーションを得ました:冷蔵庫のマグネット.
この構成では、ドラッグされたオブジェクトの情報は、QByteArrayによるシリアル化のおかげで、MIME データにストックされている のおかげで持ち込まれQDataStreamます。

スコアが占有されたドックにドロップされたときに、「存在する」スコアが元のスペースに移動するようにしたいと思います。元のドックのアドレスを含む属性を持つことでそれができると思ったのですが、このポインターをデータストリームにストックすることはできません。

ここに私のコードの一部が続きます:

/* 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();
}

<< と >> 演算子をQDataStreamand Dock * でオーバーロードすることはできませんでした。これは、ポインターを使用してそれを行う唯一の方法が、実際のデータをストックすることだったからです。しかし問題は、私はデータが欲しくないということです。文字通りポインターが必要なだけです!

アイデアがあれば、これを行う方法を再考しなければならないとしても、喜んでお聞きします. ありがとうございました!

4

1 に答える 1

0

私の理解が正しければ、ドックへのポインターをシリアル化したいですか? なぜあなたがこれを難しい方法で行っているのか、私にはよくわかりません。

これはどうですか:

  • あなたのmime-dataを単にスコアへのポインタにしてくださいitemData.fromRawData(reinterpret_cast<char*>(&score, sizeof(Score*)));
  • dropEvent() で
    • event->source() を使用してドックのポインタを取得します
    • 別のストリームと逆の手順を使用して、mimeData または単に uber-cast union: からポインターを抽出し、scorecast.score union {char chr[8]; Score *score} scorecast; memcpy(scorecast.chr, itemData.data(), sizeof(Score*)); を介してスコアポインターにアクセスします。

これにより、Score-to-drop 内のすべてのデータを送信する必要がなくなります ...

最後の考え: QByteArray.data() は、ポインターを構成するデータに const char * を与えます。*reinterpret_cast<Score * *>(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;
}
于 2014-09-24T19:43:31.817 に答える