Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QT Drag and Drop a QLabel into a QGraphicsView, how to?
Forum Updated to NodeBB v4.3 + New Features

QT Drag and Drop a QLabel into a QGraphicsView, how to?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 4 Posters 7.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jiapei100J Offline
    jiapei100J Offline
    jiapei100
    wrote on last edited by
    #1

    Hi, all:

    Sorry to bug you once again.

    I'm trying to drag and drop a QLabel into a QGraphicsView.

    My inherited label class looks like:

    @class CQtShapesLabel : public QLabel
    {
    Q_OBJECT

    public:

    explicit CQtShapesLabel(QWidget *parent = 0, int type = 0) : QLabel(parent), m_iType(type)
    {
    

    // this->m_qMimeData = NULL;
    // this->m_qDrag = NULL;
    }

    virtual ~CQtShapesLabel() {}
    

    protected:
    // void dragEnterEvent(QDragEnterEvent *event);
    // void dragMoveEvent(QDragMoveEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

    private:
    // QMimeData* m_qMimeData;
    // QDrag * m_qDrag;
    int m_iType;
    };@

    and mousePressEvent() function is defined as:
    @
    void CQtShapesLabel::mousePressEvent(QMouseEvent *event)
    {
    QPixmap pixmap = *this->pixmap();

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    dataStream << pixmap << QPoint(event->pos());
    
    QMimeData* m_qMimeData = new QMimeData;
    m_qMimeData->setData("application/x-dnditemdata", itemData);
    
    QDrag* m_qDrag = new QDrag(this);
    m_qDrag->setMimeData(m_qMimeData);
    m_qDrag->setPixmap(pixmap);
    m_qDrag->setHotSpot(event->pos());
    
    QPixmap tempPixmap = pixmap;
    QPainter painter;
    painter.begin(&tempPixmap);
    painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
    painter.end();
    
    this->setPixmap(tempPixmap);
    
    if (m_qDrag->exec&#40;Qt::CopyAction | Qt::MoveAction, Qt::CopyAction&#41; == Qt::MoveAction)
        this->close();
    else
    {
        this->show();
        this->setPixmap(pixmap);
    }
    

    }@

    My inherited QGraphicsView class looks like:

    @class QTVIEWS_EXPORT CImageView : public QGraphicsView
    {
    Q_OBJECT

    protected:
    //void paintEvent(QPaintEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dragLeaveEvent(QDragLeaveEvent *event);
    void dropEvent(QDropEvent *event);
    // void mousePressEvent(QMouseEvent *event);

    public:

    CImageView( QWidget *parent = 0, unsigned int idx = 0 );
    virtual ~CImageView( );
    

    };@

    When testing, I tried to print out something in all functions, but no matter how I tried, I found

    bq. CQtShapesLabel::mouseReleaseEvent(QMouseEvent *event); // understandable
    CImageView::dragLeaveEvent(QDragLeaveEvent *event); // should be able to response when the drag leaves this view
    CImageView::dropEvent(QDropEvent *event); // should be able to response when the drag tries to drop something
    CImageView::dragMoveEvent(QDragMoveEvent *event) // should be able to response when the drag keeps moving inside the view

    never responses. Why is it so? Can anybody help to explain please....

    Best Regards
    Pei

    Welcome to Longer Vision
    https://www.longervision.com

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Did you "setAcceptDrops(true)" in your CImageView ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Code_ReaQtor
        wrote on last edited by
        #3

        Sorry but it is not really clear how you implemented receiving the "drops" - you only show what was in the header file of your subclassed QGraphicsView.

        Anyways, if you actually want to drag and drop a QWidget (QLabel, etc) into a QGraphicsView/Scene, you need to use "QGraphicsProxyWidget":http://qt-project.org/doc/qt-4.8/qgraphicsproxywidget.html

        Also, some devs, most of the time, forgets to enable "setAcceptDrops":http://doc-snapshot.qt-project.org/4.8/qwidget.html#acceptDrops-prop

        Please visit my open-source projects at https://github.com/Code-ReaQtor.

        1 Reply Last reply
        0
        • jiapei100J Offline
          jiapei100J Offline
          jiapei100
          wrote on last edited by
          #4

          Yes, I do have setAcceptDrops(true); in my code, which is the first line of CImageView constructor, before
          @ ......
          this->setScene( this->m_QTGraphicsScene );
          this->show();@

          [quote author="SGaist" date="1362479189"]Hi,

          Did you "setAcceptDrops(true)" in your CImageView ?[/quote]

          Welcome to Longer Vision
          https://www.longervision.com

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Sam
            wrote on last edited by
            #5

            Hi,

            I hope that you are checking the mimeData format in each of the drag funcions like

            @void CImageView::dragEnterEvent(QDragEnterEvent *event)
            {
            if (event->mimeData()->hasFormat("application/x-dnditemdata"))
            {
            event->accept();
            } else
            {
            event->ignore();
            }
            }@

            Can you share the code of CImageView class , that will give the exact picture of your implementation.

            1 Reply Last reply
            0
            • jiapei100J Offline
              jiapei100J Offline
              jiapei100
              wrote on last edited by
              #6

              Some more code is provided now:

              VO_ImageView.h
              @
              #ifndef VO_IMAGEVIEW_H
              #define VO_IMAGEVIEW_H

              #include "qtviews_global.h"

              #include <QGraphicsView>
              #include <QGraphicsPixmapItem>
              #include <QGraphicsItem>
              #include <QGraphicsLineItem>
              #include <QGraphicsItemGroup>
              #include <QLabel>
              #include <QBoxLayout>
              #include <QMouseEvent>

              using namespace std;

              /**
              show an image in the corresponding QGraphicsView
              */
              class QTVIEWS_EXPORT CImageView : public QGraphicsView
              {
              Q_OBJECT

              private:
              int m_iIdx;
              QGraphicsScene* m_QTGraphicsScene;
              QPixmap* m_QTBackGroundPixmap;
              QGraphicsPixmapItem* m_QTBackGroundItem;

              void init()
              {
              this->m_QTGraphicsScene = NULL;
              this->m_QTBackGroundPixmap = NULL;
              this->m_QTBackGroundItem = NULL;
              setAcceptDrops(true);
              }

              protected:
              void dragEnterEvent(QDragEnterEvent *event);
              void dragMoveEvent(QDragMoveEvent *event);
              void dropEvent(QDropEvent *event);

              public:
              CImageView( QWidget *parent = 0, unsigned int idx = 0 );
              virtual ~CImageView( );
              };

              #endif
              @

              VO_ImageView.cpp
              @
              #include <QBuffer>

              // main header
              #include "VO_ImageView.h"
              #include "LV_QtShapesLabel.h"

              CImageView::CImageView(QWidget *parent, unsigned int idx): QGraphicsView(parent), m_iIdx(idx)
              {
              this->init();
              this->m_QTGraphicsScene = new QGraphicsScene;
              this->m_QTBackGroundItem = new QGraphicsPixmapItem;
              this->setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
              this->setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
              this->setScene( this->m_QTGraphicsScene );
              this->show();
              this->m_QTBackGroundPixmap = new QPixmap( 320, 240);
              this->m_QTBackGroundItem->setPixmap ( *this->m_QTBackGroundPixmap );
              this->m_QTGraphicsScene->addItem(this->m_QTBackGroundItem);
              }

              CImageView::~CImageView( )
              {
              if(this->m_QTBackGroundPixmap) delete (this->m_QTBackGroundPixmap);
              if(this->m_QTGraphicsScene) delete (this->m_QTGraphicsScene);
              }

              void CImageView::dragEnterEvent(QDragEnterEvent event)
              {
              if (event->mimeData()->hasFormat("application/x-dnditemdata"))
              {
              switch( dynamic_cast<CQtShapesLabel
              >(event->source())->getType() )
              {
              case CQtShapesLabel::SPHERE:
              cout << "SPHERE" << endl;
              break;
              case CQtShapesLabel::CUBE:
              cout << "CUBOID" << endl;
              break;
              case CQtShapesLabel::CUBOID:
              cout << "CUBOID" << endl;
              break;
              case CQtShapesLabel::CYLINDER:
              cout << "CONE" << endl;
              break;
              case CQtShapesLabel::HEXAGONALPRISM:
              cout << "PYRAMID" << endl;
              break;
              case CQtShapesLabel::CONE:
              cout << "CONUS" << endl;
              break;
              case CQtShapesLabel::SQUAREBASEDPYRAMID:
              cout << "CYLINDER" << endl;
              break;
              case CQtShapesLabel::TRIANGULARBASEDPYRAMID:
              cout << "SPHERE" << endl;
              break;
              case CQtShapesLabel::TRIANGULARPRISM:
              cout << "SPHERE" << endl;
              break;
              case CQtShapesLabel::CIRCLE:
              cout << "CIRCLE" << endl;
              break;
              case CQtShapesLabel::OVAL:
              cout << "OVAL" << endl;
              break;
              case CQtShapesLabel::TRIANGLE:
              cout << "TRIANGLE" << endl;
              break;
              case CQtShapesLabel::SQUARE:
              cout << "SQUARE" << endl;
              break;
              case CQtShapesLabel::RECTANGLE:
              cout << "RECTANGLE" << endl;
              break;
              case CQtShapesLabel::RHOMBUS:
              cout << "RHOMBUS" << endl;
              break;
              case CQtShapesLabel::TRAPEZOID:
              cout << "TRAPEZOID" << endl;
              break;
              case CQtShapesLabel::SHAPE3D:
              default:
              event->ignore();
              break;
              }
              }
              else
              {
              event->ignore();
              }
              }

              void CImageView::dragMoveEvent(QDragMoveEvent *event)
              {
              if (event->mimeData()->hasFormat("application/x-dnditemdata"))
              {
              event->accept();
              int aaa = 9999;
              cout << aaa << endl;
              } else
              {
              event->ignore();
              }
              }

              void CImageView::dropEvent(QDropEvent *event)
              {
              if (event->mimeData()->hasFormat("application/x-dnditemdata"))
              {
              event->accept();
              int aaa = 44444444;
              cout << aaa << endl;
              } else
              {
              event->ignore();
              }
              }
              @

              Welcome to Longer Vision
              https://www.longervision.com

              1 Reply Last reply
              0
              • jiapei100J Offline
                jiapei100J Offline
                jiapei100
                wrote on last edited by
                #7

                Hi, thank you for your reply. I don't want to drag and drop a QWidget, but I want to draw a shape onto QGraphicsView when I drop the QLabel on the QGraphicsView. And I'm expecting the shape to be able to be modified/changed after a further drag within the QGraphicsView.

                Any demos?

                Cheers
                Pei

                [quote author="Code_ReaQtor" date="1362479727"]Sorry but it is not really clear how you implemented receiving the "drops" - you only show what was in the header file of your subclassed QGraphicsView.

                Anyways, if you actually want to drag and drop a QWidget (QLabel, etc) into a QGraphicsView/Scene, you need to use "QGraphicsProxyWidget":http://qt-project.org/doc/qt-4.8/qgraphicsproxywidget.html

                Also, some devs, most of the time, forgets to enable "setAcceptDrops":http://doc-snapshot.qt-project.org/4.8/qwidget.html#acceptDrops-prop[/quote]

                [quote author="Code_ReaQtor" date="1362479727"]Sorry but it is not really clear how you implemented receiving the "drops" - you only show what was in the header file of your subclassed QGraphicsView.

                Anyways, if you actually want to drag and drop a QWidget (QLabel, etc) into a QGraphicsView/Scene, you need to use "QGraphicsProxyWidget":http://qt-project.org/doc/qt-4.8/qgraphicsproxywidget.html

                Also, some devs, most of the time, forgets to enable "setAcceptDrops":http://doc-snapshot.qt-project.org/4.8/qwidget.html#acceptDrops-prop[/quote]

                Welcome to Longer Vision
                https://www.longervision.com

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Sam
                  wrote on last edited by
                  #8

                  Hi,

                  I tested your aplication and it works as required. The problem is that in your dragEnterEvent() you are not using
                  event->accept() anywhere, try to add the same and run again.

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Code_ReaQtor
                    wrote on last edited by
                    #9

                    [quote author="jiapei100" date="1362553970"]
                    I don't want to drag and drop a QWidget, but I want to draw a shape onto QGraphicsView when I drop the QLabel on the QGraphicsView.
                    [/quote]

                    When dropped, it should be changed into a QGraphicsItem.

                    I can't really see some major problems (or I am just missing something). Keep in mind to check the following using cout/qDebug/etc:

                    check if setAcceptDrops is set to true

                    check if "dynamic_cast" worked

                    are you using "enum" with these? CQtShapesLabel::SPHERE, CQtShapesLabel::CUBE, etc.... since I can't see them implemented in the code

                    Please visit my open-source projects at https://github.com/Code-ReaQtor.

                    1 Reply Last reply
                    0
                    • jiapei100J Offline
                      jiapei100J Offline
                      jiapei100
                      wrote on last edited by
                      #10

                      You are right Sam... Thank you so much !!

                      [quote author="Sam" date="1362568332"]Hi,

                      I tested your aplication and it works as required. The problem is that in your dragEnterEvent() you are not using
                      event->accept() anywhere, try to add the same and run again.

                      [/quote]

                      Welcome to Longer Vision
                      https://www.longervision.com

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        Sam
                        wrote on last edited by
                        #11

                        [quote author="jiapei100" date="1362607972"]
                        You are right Sam... Thank you so much !!

                        [quote author="Sam" date="1362568332"]Hi,

                        I tested your aplication and it works as required. The problem is that in your dragEnterEvent() you are not using
                        event->accept() anywhere, try to add the same and run again.

                        [/quote]

                        [/quote]

                        You are welcome :)

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved