slot of QClipboard::dataChanged() was called twice

638 views Asked by At

The slot detectClipboardUrl of QClipboard::dataChanged() was called twice sometimes when I copy url in Google Chrome's address bar in this code, tested with PyQt5.7,Python3.5 on Win7 32bit, also on Linux Mint 18, while I need the slot to be called only once , is this a bug ? any solutions ?

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class MainWindow(QTableView):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.clipboard = QApplication.clipboard()
        self.clipboard.dataChanged.connect(self.detectClipboardUrl)  

    @pyqtSlot()
    def detectClipboardUrl(self):
        print(self.clipboard.text())



if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_())
1

There are 1 answers

5
ekhumoro On

If the changes are duplicates, you can do something like:

class MainWindow(QTableView):
    def __init__(self, parent=None):
    self.clipboard = QApplication.clipboard()
    self._cb_last = hash(self.clipboard.text())
    self.clipboard.dataChanged.connect(self.detectClipboardUrl)  

    @pyqtSlot()
    def detectClipboardUrl(self):
        text = self.clipboard.text()
        cb_current = hash(text)
        if cb_current != self._cb_last:
            print('clipboard text changed:', text)
            self._cb_last = cb_current

The reason for using hash is simply to avoid keeping very large strings in memory.

Alternatively, if the two signals arrive very close together, you could use a QTimer to block any changes that occur within a few milliseconds of the first one.

UPDATE:

As I suspected, the problem is caused by a bug in Chromium: see Issue 173691.