c++ - QGraphicsPixmapItem 不显示在 QGraphicsView 中

标签 c++ qt drag-and-drop qt5 qgraphicsview

我继承了 QGraphicsView(类 Display)并实现了从 QTableView 拖放。 QGraphicsScene 中有预先存在的项目,并且 scene()->itemsBoundingRect 覆盖了整个地球。 如果我人为地将QGraphicsPixmapItem的boundingRect设置为QGraphicsView的viewPort(),我看不到我在QGraphicsPixmapItem中设置并添加到scene()中的QPixmap。如果我 fitInView the scene()->itemsBoundingRect,像素图将被丢弃在整个世界上。我希望它落在我的视口(viewport)上,但本质上 fitInView viewPort 不显示该项目,即使根据调试它是可见的和 notObscured()。

void Display::dragEnterEvent(QDragEnterEvent* event)
{

    event->acceptProposedAction();
    update();
}

void Display::dragMoveEvent(QDragMoveEvent* event){
    event->acceptProposedAction();
    update();
}

  void TableView::mouseMoveEvent(QMouseEvent *event)
    {
        QDrag* drag = new QDrag(this);
        QMimeData *mime = new QMimeData();
        drag->setMimeData(mime);
        QImage image("/Users/sb/Downloads/puffin.jpeg");
        mime->setImageData(image);
        drag->setPixmap(QPixmap::fromImage(image).scaled(10,10));
        drag->exec();
        QTableView::mouseMoveEvent(event);

编辑以尝试@Eyllanesc 的建议

void Display::dropEvent(QDropEvent* event)
{

    setCacheMode(QGraphicsView::CacheBackground);
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

    if(event->mimeData()->hasImage())
    {
        pixMap = qvariant_cast<QPixmap>(event->mimeData()->imageData());
        pixMap = pixMap.scaledToHeight(10);
        pixMap = pixMap.scaledToWidth(10);
        bool h = pixMap.isNull(); //returns false

        posn = mapToScene(event->pos());

        QRectF ff  = mapToScene(viewport()->geometry()).boundingRect();
        bool ps = ff.contains(posn); //returns true

        item = new QGraphicsPixmapItem(pixMap);
        scene()->addItem(item);

        item->setPos( posn);
        item->setZValue(100);
        item->setVisible(true);
        item->setOpacity(1.0);
        item->update();
        scene()->update();
        auto lView = qobject_cast<QGraphicsView*>(this);
        lView->fitInView(ff, Qt::KeepAspectRatio);// no pixmap is shown
        invalidateScene(ff);
        bool i = item->isObscured(); //returns false
        repaint();
        update();
    }
    event->acceptProposedAction();

}

-

最佳答案

在下一部分中,我将向您展示如何实现从 QTableView 到 QGraphicsView 的拖放操作的工作示例:

#include <QApplication>
#include <QDrag>
#include <QGraphicsView>
#include <QHBoxLayout>
#include <QMimeData>
#include <QMouseEvent>
#include <QTableView>
#include <QGraphicsPixmapItem>
#include <random>
#include <QStandardItemModel>


static std::random_device rd;
static std::mt19937 rng(rd());


class TableView: public QTableView{
public:
    using QTableView::QTableView;
protected:
    void mousePressEvent(QMouseEvent *event){
        if (event->button() == Qt::LeftButton)
            dragStartPosition = event->pos();
    }
    void mouseMoveEvent(QMouseEvent *event){
        if (!(event->buttons() & Qt::LeftButton))
            return;
        if ((event->pos() - dragStartPosition).manhattanLength()
                < QApplication::startDragDistance())
            return;

        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;

        // create image
        QImage image(100, 100, QImage::Format_RGB32);
        std::uniform_int_distribution<int> uni(0, 255);
        image.fill(QColor(uni(rng), uni(rng), uni(rng)));

        mimeData->setImageData(image);
        drag->setPixmap(QPixmap::fromImage(image).scaled(10,10));
        drag->setMimeData(mimeData);

        drag->exec();
        QTableView::mouseMoveEvent(event);
    }
private:
    QPoint dragStartPosition;
};

class Display: public QGraphicsView{
public:
    using QGraphicsView::QGraphicsView;
protected:
    void dragMoveEvent(QDragMoveEvent *event){
        if(event->mimeData()->hasFormat("application/x-qt-image"))
            event->acceptProposedAction();
    }

    void dropEvent(QDropEvent *event){
        if (event->source() == this)
            return;
        QPixmap pixmap = qvariant_cast<QPixmap>(event->mimeData()->imageData());
        QGraphicsPixmapItem *pixmap_item = scene()->addPixmap(pixmap);
        pixmap_item->setPos(mapToScene(event->pos()));
        event->acceptProposedAction();
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    QHBoxLayout* lay = new QHBoxLayout(&w);
    QGraphicsScene scene;
    Display view(&scene);
    view.setAcceptDrops(true);
    TableView table;
    QStandardItemModel model(10, 10);
    table.setModel(&model);
    lay->addWidget(&table);
    lay->addWidget(&view);
    w.show();

    return a.exec();
}

enter image description here

关于c++ - QGraphicsPixmapItem 不显示在 QGraphicsView 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52196347/

相关文章:

c# - 将文件拖放到 wpf/C# 应用程序时,如何维护 Windows 资源管理器中的文件顺序?

c# - 如何更改 Windows 窗体应用程序中的拖动阈值?

c# - 在 Windows 上拦截/重定向传出的 http 连接

C++ 应用程序无法正确启动 (0xc000000d)

c++ - CRichEditCtrl::StreamIn 丢失格式

c++ - QLabel 占用完整空间

c++ - 将 Qt 添加到现有的 GNU C++ 程序

c++ - 在 QString 中连接 STL string+int+int+int

javascript - 在放置事件中将图像显示为无

c++ - 加载仅具有 alpha 值的纹理