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. How to catch a paste action from a widget other than Text container
Forum Updated to NodeBB v4.3 + New Features

How to catch a paste action from a widget other than Text container

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.1k 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.
  • Y Offline
    Y Offline
    YvesB
    wrote on 15 Sept 2020, 20:12 last edited by
    #1

    Hello,
    I'm working on an application which displays a void area at start. I would like to catch a "paste" event to insert in this case a QPixmap in the area when the data are an image.
    I didn't find any way for that.
    What I see is that only Text containers can manage paste event, and if needed using insertFromMimeData to manage the pasted data.
    Is it really the only way to paste data ?

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Faruq
      wrote on 16 Sept 2020, 02:55 last edited by Faruq
      #2

      Hi,

      I am interested to learn and help as well. From your case, it would seems like you would like to put an image into the void space.
      Once dropped, the space will be filled with the chosen photo.

      I came across an example that may be the solution. Here is the link: https://evileg.com/en/post/240/

      I cut short the code and utilise the widget.cpp only. Its not clean but this is it. If it works, credit goes to Evgenij (evileg)

      widget.h

      #ifndef WIDGET_H
      #define WIDGET_H
      
      #include <QWidget>
      #include <QPalette>
      #include <QDragEnterEvent>
      #include <QMimeData>
      #include <QDropEvent>
      #include <QScrollArea>
      #include <QLabel>
      #include <QListView>
      #include <QGridLayout>
      #include <QStandardItemModel>
      
      class Widget : public QWidget
      {
          Q_OBJECT
      
      public:
          explicit Widget(QWidget *parent = 0);
          ~Widget();
      
          // Drag event method
          virtual void dragEnterEvent(QDragEnterEvent* event) override;
          // Method for drop an object with data
          virtual void dropEvent(QDropEvent *event) override;
      
      private slots:
          // Slot for processing clicks on list items
          void onImagesListViewClicked(const QModelIndex& index);
      
      private:
          QScrollArea*        m_scrollArea;       // Image scrolling area
          QLabel*             m_imageLabel;       // Label for displaying pictures
          QListView*          m_imagesListView;   // List with images
          QGridLayout*        m_gridLayout;       // Grid for the interface
          QStandardItemModel* m_imagesModel;      // Data Model with Images
      };
      
      #endif // WIDGET_H
      
      

      widget.cpp

      #include "widget.h"
      #include "ui_widget.h"
      
      #include <QStandardItem>
      #include "imagedelegate.h"
      
      Widget::Widget(QWidget *parent) :
          QWidget(parent)
      {
          setAcceptDrops(true);       // Allow drop events for data objects
          setMinimumWidth(640);
          setMinimumHeight(480);
      
          /// Configure the interface
          m_gridLayout = new QGridLayout(this);
          m_scrollArea = new QScrollArea(this);
          m_scrollArea->setBackgroundRole(QPalette::Dark);
          m_imageLabel = new QLabel(this);
          m_scrollArea->setWidget(m_imageLabel);
          m_gridLayout->addWidget(m_scrollArea, 0, 0);
      }
      
      Widget::~Widget()
      {
      
      }
      
      void Widget::dragEnterEvent(QDragEnterEvent *event)
      {
          // You must necessarily accept the data transfer event in the application window area
          event->accept();
      }
      
      void Widget::dropEvent(QDropEvent *event)
      {
          // When we drop the file into the application area, we take the path to the file from the MIME data
          QString filePath = event->mimeData()->urls()[0].toLocalFile();
          // Create an image
          QPixmap pixmap(filePath);
          // We place it in the scrolling area through QLabel
          m_imageLabel->setPixmap(pixmap);
          m_imageLabel->resize(pixmap.size());
      
          // Adding an item to the list
          m_imagesModel->appendRow(new QStandardItem(QIcon(pixmap), filePath));
      }
      
      void Widget::onImagesListViewClicked(const QModelIndex &index)
      {
          // When we click on an element in the list, we take the path to the file
          QPixmap pixmap(m_imagesModel->data(index).toString());
          // And install the file in the main view area
          m_imageLabel->setPixmap(pixmap);
          m_imageLabel->resize(pixmap.size());
      }
      
      
      Y 1 Reply Last reply 16 Sept 2020, 07:23
      1
      • B Offline
        B Offline
        Bonnie
        wrote on 16 Sept 2020, 03:20 last edited by
        #3

        You can look into the qt source file about how text containers handle a paste action:
        https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp.html#1313

        Y 1 Reply Last reply 17 Sept 2020, 10:12
        3
        • F Faruq
          16 Sept 2020, 02:55

          Hi,

          I am interested to learn and help as well. From your case, it would seems like you would like to put an image into the void space.
          Once dropped, the space will be filled with the chosen photo.

          I came across an example that may be the solution. Here is the link: https://evileg.com/en/post/240/

          I cut short the code and utilise the widget.cpp only. Its not clean but this is it. If it works, credit goes to Evgenij (evileg)

          widget.h

          #ifndef WIDGET_H
          #define WIDGET_H
          
          #include <QWidget>
          #include <QPalette>
          #include <QDragEnterEvent>
          #include <QMimeData>
          #include <QDropEvent>
          #include <QScrollArea>
          #include <QLabel>
          #include <QListView>
          #include <QGridLayout>
          #include <QStandardItemModel>
          
          class Widget : public QWidget
          {
              Q_OBJECT
          
          public:
              explicit Widget(QWidget *parent = 0);
              ~Widget();
          
              // Drag event method
              virtual void dragEnterEvent(QDragEnterEvent* event) override;
              // Method for drop an object with data
              virtual void dropEvent(QDropEvent *event) override;
          
          private slots:
              // Slot for processing clicks on list items
              void onImagesListViewClicked(const QModelIndex& index);
          
          private:
              QScrollArea*        m_scrollArea;       // Image scrolling area
              QLabel*             m_imageLabel;       // Label for displaying pictures
              QListView*          m_imagesListView;   // List with images
              QGridLayout*        m_gridLayout;       // Grid for the interface
              QStandardItemModel* m_imagesModel;      // Data Model with Images
          };
          
          #endif // WIDGET_H
          
          

          widget.cpp

          #include "widget.h"
          #include "ui_widget.h"
          
          #include <QStandardItem>
          #include "imagedelegate.h"
          
          Widget::Widget(QWidget *parent) :
              QWidget(parent)
          {
              setAcceptDrops(true);       // Allow drop events for data objects
              setMinimumWidth(640);
              setMinimumHeight(480);
          
              /// Configure the interface
              m_gridLayout = new QGridLayout(this);
              m_scrollArea = new QScrollArea(this);
              m_scrollArea->setBackgroundRole(QPalette::Dark);
              m_imageLabel = new QLabel(this);
              m_scrollArea->setWidget(m_imageLabel);
              m_gridLayout->addWidget(m_scrollArea, 0, 0);
          }
          
          Widget::~Widget()
          {
          
          }
          
          void Widget::dragEnterEvent(QDragEnterEvent *event)
          {
              // You must necessarily accept the data transfer event in the application window area
              event->accept();
          }
          
          void Widget::dropEvent(QDropEvent *event)
          {
              // When we drop the file into the application area, we take the path to the file from the MIME data
              QString filePath = event->mimeData()->urls()[0].toLocalFile();
              // Create an image
              QPixmap pixmap(filePath);
              // We place it in the scrolling area through QLabel
              m_imageLabel->setPixmap(pixmap);
              m_imageLabel->resize(pixmap.size());
          
              // Adding an item to the list
              m_imagesModel->appendRow(new QStandardItem(QIcon(pixmap), filePath));
          }
          
          void Widget::onImagesListViewClicked(const QModelIndex &index)
          {
              // When we click on an element in the list, we take the path to the file
              QPixmap pixmap(m_imagesModel->data(index).toString());
              // And install the file in the main view area
              m_imageLabel->setPixmap(pixmap);
              m_imageLabel->resize(pixmap.size());
          }
          
          
          Y Offline
          Y Offline
          YvesB
          wrote on 16 Sept 2020, 07:23 last edited by
          #4

          @Faruq Thanks for this. I will probably use it. But this does answer to the question which focus is on paste action, not drag-drop.
          @Bonnie I don't find documentation on QWidgetTextController, but this is interesting. I see that a keyPressEvent is caught to deal with the Paste action. I will try that.

          B 1 Reply Last reply 16 Sept 2020, 07:44
          0
          • Y YvesB
            16 Sept 2020, 07:23

            @Faruq Thanks for this. I will probably use it. But this does answer to the question which focus is on paste action, not drag-drop.
            @Bonnie I don't find documentation on QWidgetTextController, but this is interesting. I see that a keyPressEvent is caught to deal with the Paste action. I will try that.

            B Offline
            B Offline
            Bonnie
            wrote on 16 Sept 2020, 07:44 last edited by Bonnie
            #5

            @YvesB
            QWidgetTextController is an internal (private) controller class for almost all qt text containers.
            It doesn't have any documentation because we are not supposed to use it.

            1 Reply Last reply
            1
            • B Bonnie
              16 Sept 2020, 03:20

              You can look into the qt source file about how text containers handle a paste action:
              https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp.html#1313

              Y Offline
              Y Offline
              YvesB
              wrote on 17 Sept 2020, 10:12 last edited by
              #6

              @Bonnie said in How to catch a paste action from a widget other than Text container:

              You can look into the qt source file about how text containers handle a paste action:
              https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp.html#1313

              Following this example, I got a solution.
              I have a QAction added in the QMainWindow, with a shortcut being QKeySequence::Paste and connected to a paste function. I have edited this function to detect the context of the paste action. Some extracts of my program in Python:

                      self.actionPaste = QAction(
                              QIcon.fromTheme('edit-paste',
                                      QIcon(rsrcPath + '/editpaste.png')),
                              self.tr("&Paste"), self, priority=QAction.LowPriority,
                              shortcut=QKeySequence.Paste,
                              enabled=((len(QApplication.clipboard().text()) != 0) or QApplication.clipboard().mimeData().hasImage()))
                      tb.addAction(self.actionPaste)
              

              and

                  def paste(self):
                      #   send the command to the active section
                      widget = self.focusWidget()
                      if widget.metaObject().className() == "CTextEdit":
                          widget.paste()
                      if widget.metaObject().className() == "ChapterTab":
                          widget.edit.pasteDrawing()
              
              1 Reply Last reply
              1

              1/6

              15 Sept 2020, 20:12

              • Login

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