How to get ownership of QClipboard

305 views Asked by At

I'm using PyQt 5.15 and python 3.10 on Windows 10. In my application I have a loop which checks if there is a image in the QClipboard. After reading it I like to clear the clipboard and wait for the next image which will be copied by the user from any other application (like screenshot etc.)

But after QApplication.clipboard().clear(QClipboard.Clipboard) the pixmap is not deleted and still has its old size. Tested with QApplication.clipboard().pixmap().height()

The call of QApplication.clipboard().ownsClipboard() returns allways False, so I think I have to take the ownership of the clipboard. I can't find any reference to do that.

According to the documentation:

bool QClipboard::ownsClipboard() const

Returns true if this clipboard object owns the clipboard data; otherwise returns false.

I think the data in the clipboard are protected by the application where I copied the data from. So, how can I get this ownership?

I found some information on this site: How ownership of the Windows clipboard is tracked in Win32, but I have no idea how to adapt this to python.

The basic working loop is like this:

def copyloop(self):
    clipboard = QGuiApplication.clipboard()
    mimeData = clipboard.mimeData (QClipboard.Clipboard)
    loop = True
    while loop:
        if mimeData.hasImage ():
            pixmap = QPixmap(mimeData.imageData ())
            # do something with pixmap
            #self.label.setPixmap(pixmap)
            QMessageBox.information(self, "Clip me", "before clear clipboard: " + str(clipboard.pixmap(QClipboard.Clipboard).width()))
            clipboard.clear(QClipboard.Clipboard)
            QMessageBox.warning(self, "Clip me", "After clear clipboard: " + str(clipboard.pixmap(QClipboard.Clipboard).width()))
            loop = False
        else:
            #self.label.setPixmap(QPixmap())
            loop = True

The code works as long as I use it in standalone (simple GUI with one QDialog class), but in my programm (Stacked layouts with QMainwindow's and mutiple Dialogs) it doesn't clear the clipboard.

EDIT:

Working loop including comment of @Musicamente:

        while  pushButton.isChecked():
            mimeData = clipboard.mimeData()
            if mimeData.hasImage ():
                pixmap = QPixmap(mimeData.imageData ())
                # do something with pixmap
            QApplication.processEvents()
1

There are 1 answers

0
Papageno On

From the docs of MS Windows App development

In general, the clipboard owner is the window that last placed data in clipboard. The EmptyClipboard function assigns clipboard ownership.

Seems to be the nearest answer.

Therefore its not possible to set it ;-)

EDIT:

Finally I got a maximum reduced sample to demonstrate the fault:

import sys
from PyQt5.QtWidgets import *

# if the following import is used, QApplication.clipboard() will not work as expected. 
# comment it out, copy any text and run. Enjoy the different output

from pywinauto import application


def clipboard_test():
    print("-> clipboard_test")
    clipboard = QApplication.clipboard()
    print("Owner                    =", clipboard.ownsClipboard())
    print("before clear             =", clipboard.text(mode=clipboard.Clipboard))
    clipboard.clear(clipboard.Clipboard)
    QApplication.processEvents()
    print("after clear              =", clipboard.text(mode=clipboard.Clipboard))
    clipboard.setText(":-)", mode=clipboard.Clipboard)
    print("new content (should ;-)) =", clipboard.text(mode=clipboard.Clipboard))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    clipboard_test()
    sys.exit(app.exec_())