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 save the image in clipboard in variable and restore it to clipboard later?

How to save the image in clipboard in variable and restore it to clipboard later?

Scheduled Pinned Locked Moved Unsolved General and Desktop
21 Posts 6 Posters 4.3k Views
  • 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
    yetanotherqtfan
    wrote on 19 Jan 2020, 10:06 last edited by yetanotherqtfan
    #1

    I connect a slot to the dataChanged signal of QClipboard to store the image in the clipboard to a variable mimedata(reference):

    void MyWin::clipboardDataChanged()
    {
        const QMimeData * m=QApplication::clipboard()->mimeData();
        mimedata = new QMimeData();
        
        foreach(QString format, m->formats())
        {
            QByteArray data = m->data(format);
            if(format.startsWith("application/x-qt"))
            {
                int index1 = format.indexOf('"') + 1;
                int index2 = format.indexOf('"', index1);
                format = format.mid(index1, index2 - index1);
            }
            mimedata->setData(format, data);
        }
    }
    

    And restore mimedata to clipboard as follows:

    void MyWin::onrestore()
    {
         QApplication::clipboard()->setMimeData(mimedata);
    }
    

    However, the data set to the clipboard seems corrupted. If I paste from the clipboard to Paint, it says "The information on the Clipboard can't be inserted into Paint." I printed the format of the data in the clipboard, i.e., "application/x-qt-image". So I think it is not a format that is supported by other applications. Is this a bug of Qt?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 19 Jan 2020, 10:17 last edited by
      #2

      Why do you modify the format? What do you try to achieve in the first place?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • Y Offline
        Y Offline
        yetanotherqtfan
        wrote on 19 Jan 2020, 10:25 last edited by
        #3

        I just use the code in the reference link which is said the correct way to copy mime data. But that does not matter, even if I do not modify the format, the result is the same.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 19 Jan 2020, 10:46 last edited by
          #4

          Is still don't see a point on what you're trying to do - do you want to put something into the clipboard ord do you want to read from? Currently you read data from the clipboard, modify it in a strange way and later set it back - what's the reason for this?

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          0
          • Y Offline
            Y Offline
            yetanotherqtfan
            wrote on 19 Jan 2020, 11:47 last edited by
            #5

            I just want to save the clipboard, then restore it later in case its content is changed.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on 19 Jan 2020, 12:51 last edited by
              #6

              Then don't modify the mime-data and simply copy it over.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              1
              • Y Offline
                Y Offline
                yetanotherqtfan
                wrote on 19 Jan 2020, 15:16 last edited by yetanotherqtfan
                #7

                Simply copying it over does not help. I think qt should return the format like application/x-qt-image;value="image/bmp", so my code will change the format to "image/bmp" before setting it back to clipboard. But it only returns "application/x-qt-image", which is not a standard mime type, and my code does not change the format actually. I'm on Windows. Don't know if it is the case on Linux. I think it should be bug of Qt.

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 19 Jan 2020, 16:28 last edited by
                  #8

                  application/x-qt-image is only a qt-internal format, when you iterate over the available formats you will also find the others - there is absolutely no need to modify them and I still don't understand why you want to restore the clipboard.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  1
                  • Y Offline
                    Y Offline
                    yetanotherqtfan
                    wrote on 20 Jan 2020, 07:06 last edited by
                    #9

                    "application/x-qt-image" is the only format when I press the Print-Screen key to take a screenshot. This problem seems related to the bug:https://bugreports.qt.io/browse/QTBUG-4110. Qt Experts, can you confirm it?

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      VRonin
                      wrote on 20 Jan 2020, 10:02 last edited by
                      #10

                      You can use auto image = qvariant_cast<QImage>(m->imageData()); to get a QImage from an application/x-qt-image mime and you can do whatever you want with that.
                      For example you can use:

                      QByteArray imageData;
                      QBuffer imageBuffer(&imageData);
                      imageBuffer.open(QIODevice::WriteOnly);
                      if(image->save(&imageBuffer,"PNG")){
                          mime = new QMimeData;
                          mime->setData(QStringLiteral("image/png"),imageData);
                          QApplication::clipboard()->setMimeData(mime);
                      }
                      

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      2
                      • Y Offline
                        Y Offline
                        yetanotherqtfan
                        wrote on 20 Jan 2020, 11:42 last edited by
                        #11

                        I've tried your code, unfortunately, it does not work. After I press the Print-Screen key and go to MS Paint, the "Paste“ button is enabled, which means there is something in the clipboard that can be pasted. After I run your code and go to Paint again, the "Paste" button is disabled. So the data in clipboard is corrupted.

                        1 Reply Last reply
                        0
                        • V Offline
                          V Offline
                          VRonin
                          wrote on 20 Jan 2020, 14:29 last edited by
                          #12

                          Actually, it's much easier than I was thinking, you can load images in the clipboard just by using QApplication::clipboard()->setPixmap or QApplication::clipboard()->setImage.
                          For example:

                          #include <QApplication>
                          #include <QPushButton>
                          #include <QClipboard>
                          #include <QPixmap>
                          int main(int argc, char *argv[])
                          {
                              QApplication app(argc,argv);
                              QPushButton quitButton(QStringLiteral("SaveImage"));
                              QObject::connect(&quitButton,&QPushButton::clicked,[&quitButton](){
                                  QApplication::clipboard()->setPixmap(quitButton.grab());
                              });
                              quitButton.show();
                              return app.exec();
                          }
                          

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          0
                          • Y Offline
                            Y Offline
                            yetanotherqtfan
                            wrote on 20 Jan 2020, 15:07 last edited by yetanotherqtfan
                            #13

                            Yes, it has no problem to set a QImage or QPixmap to clipboard. But it has problem getting the image from clipboard and setting it back to clipboard. And I want to restore every component in the clipboard not just image, which means I must copy the mimedata.

                            V 1 Reply Last reply 20 Jan 2020, 15:10
                            0
                            • Y yetanotherqtfan
                              20 Jan 2020, 15:07

                              Yes, it has no problem to set a QImage or QPixmap to clipboard. But it has problem getting the image from clipboard and setting it back to clipboard. And I want to restore every component in the clipboard not just image, which means I must copy the mimedata.

                              V Offline
                              V Offline
                              VRonin
                              wrote on 20 Jan 2020, 15:10 last edited by
                              #14

                              @yetanotherqtfan said in How to save the image in clipboard in variable and restore it to clipboard later?:

                              And I want to restore every component in the clipboard not just image

                              "application/x-qt-image" is the only format when I press the Print-Screen key to take a screenshot.

                              I don't think I follow

                              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                              ~Napoleon Bonaparte

                              On a crusade to banish setIndexWidget() from the holy land of Qt

                              C 1 Reply Last reply 20 Jan 2020, 17:34
                              0
                              • Y Offline
                                Y Offline
                                yetanotherqtfan
                                wrote on 20 Jan 2020, 15:26 last edited by
                                #15

                                For the print-screen case, there is only one format "application/x-qt-image". But in most cases,e.g., copying images and text in a word document, there would be more components in the clipboard. In the print-screen case, you can copy the clipboard image to a QImage object then set it to clipboard later. But for other cases, you may get a null image. Even you get a valid QImage, setting it back to clipboard will destroy other components in it. So the general method would be copying the mimedata object, and this would fail even for the print-screen case.

                                1 Reply Last reply
                                0
                                • V Offline
                                  V Offline
                                  VRonin
                                  wrote on 20 Jan 2020, 15:59 last edited by
                                  #16

                                  Something like this?

                                  bool skipOne = false;
                                      QObject::connect(app.clipboard(),&QClipboard::dataChanged,[&skipOne](){
                                          if(skipOne){
                                              skipOne=false;
                                              return;
                                          }
                                          const QMimeData* mime = QApplication::clipboard()->mimeData();
                                          const QStringList formats = mime->formats();
                                          const int imageIdx = formats.indexOf(QLatin1String("application/x-qt-image"));
                                          if(imageIdx<0)
                                              return;
                                          const QImage image = qvariant_cast<QImage>(mime->imageData());
                                          if(image.isNull())
                                              return;
                                          QMimeData* adjMime = new QMimeData;
                                          adjMime->setImageData(image);
                                          for(int i=0;i<formats.size();++i){
                                              if(i==imageIdx)
                                                  continue;
                                              adjMime->setData(formats.at(i),mime->data(formats.at(i)));
                                          }
                                          skipOne=true;
                                          QApplication::clipboard()->setMimeData(adjMime);
                                      });
                                  

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  1 Reply Last reply
                                  1
                                  • Y Offline
                                    Y Offline
                                    yetanotherqtfan
                                    wrote on 20 Jan 2020, 16:14 last edited by
                                    #17

                                    @VRonin said in How to save the image in clipboard in variable and restore it to clipboard later?:

                                    dat

                                    I will try your latest code. But all my attempts in setting the QMimeData failed.

                                    1 Reply Last reply
                                    0
                                    • V VRonin
                                      20 Jan 2020, 15:10

                                      @yetanotherqtfan said in How to save the image in clipboard in variable and restore it to clipboard later?:

                                      And I want to restore every component in the clipboard not just image

                                      "application/x-qt-image" is the only format when I press the Print-Screen key to take a screenshot.

                                      I don't think I follow

                                      C Offline
                                      C Offline
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on 20 Jan 2020, 17:34 last edited by
                                      #18

                                      @VRonin said in How to save the image in clipboard in variable and restore it to clipboard later?:

                                      "application/x-qt-image" is the only format when I press the Print-Screen key to take a screenshot.

                                      I don't think I follow

                                      The problem is that @yetanotherqtfan does not understand that this is the one and only format you will get from Qt since when the data is retrieved from the native clipboard and there is image data it will be converted to this internal mime-format. And the other way round so there is absolutely no need to replace the mime-type (it's even counter-productive - see https://code.woboq.org/qt5/qtbase/src/plugins/platforms/windows/qwindowsmime.cpp.html#1140 )

                                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                      Visit the Qt Academy at https://academy.qt.io/catalog

                                      1 Reply Last reply
                                      3
                                      • D Offline
                                        D Offline
                                        derekleesoft
                                        wrote on 18 Jun 2020, 10:08 last edited by
                                        #19

                                        @Christian-Ehrlicher I have one question. I tried to save the transparent image to clipboard but it's not working on windows but on ubuntu. I am not sure why. When I used setImage or setPixmap, the image was always opaque even it has transparency. How can I fix this?

                                        1 Reply Last reply
                                        0
                                        • S Offline
                                          S Offline
                                          SilentSight
                                          wrote on 9 Mar 2024, 21:32 last edited by
                                          #20

                                          I'm having a similar issue to the original poster (Qt5 for Python), and I think I can clarify what they're trying to say.

                                          So when copying from the Clipboard, many programs add additional MimeType metadata. For example, GIMP's XCF when copying images will include XCF metadata, plus several different variations of the image's binary data.

                                          For example:

                                          ['TIMESTAMP', 'TARGETS', 'MULTIPLE', 'SAVE_TARGETS', 'image/x-xcf', 'image/png', 'image/bmp', 'image/x-bmp', 'image/x-MS-bmp', 'image/x-icon', 'image/x-ico', 'image/x-win-bitmap', 'image/vnd.microsoft.icon', 'application/ico', 'image/ico', 'image/icon', 'text/ico', 'image/tiff', 'image/jpeg', 'application/x-qt-image']
                                          

                                          However, Qt does not allow one to faithfully recreate said mimeType metadata. If one tries to use 'setImage', for example, Qt forces their proprietary format:

                                          application/x-qt-image
                                          

                                          This is not a valid image mimetype for image data (which must start with "image/" and should be a common recognised format, E.G. png), which means applications like GIMP will not recognise the image data as valid.

                                          There's little point using Qt-specific tags in a global clipboard meant to be used/referenced by external programs.

                                          Trying to use the Qt5 ecosystem, it feels very much like one is coerced into using 'Q-types' even if they might not be suitable nor desirable for third party application specific purposes.

                                          Even if one tries to set a custom mimetype via 'setMimeData', and specifies explicitly what the raw binary data is (E.G. 'image/png'), third party applications still do not recognise it as valid PNG data - even if it is a verbatim cloned copy of the raw image/png data straight from Qt!

                                          Even if this was to work, any subsequent calls to 'setMimeData' overwrites the last set format (so if I try to also set 'image/jpeg' trying to recreate XCF's metadata, it will just replace 'image/png'). There's presently no way to set multiple types of mimetype metadata at once.

                                          C 1 Reply Last reply 10 Mar 2024, 05:10
                                          0

                                          • Login

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