Reputation: 1036
In PyQt I am trying to get the content of the clipboard every time it changes, do some operations to calculate the output as text and put it again in the clipboard.
The problem seems to be that when I change the content of the clipboard inside the "clipboard content changed" event handling function, this triggers and infinite calling that function over and over again.
This is the code I am using:
import sys
from PyQt5.Qt import QApplication, QClipboard
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QPlainTextEdit
from PyQt5.QtCore import QSize
class ExampleWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(440, 240))
self.setWindowTitle("PyQt5 Clipboard example")
# Add text field
self.b = QPlainTextEdit(self)
self.b.insertPlainText("Use your mouse to copy text to the clipboard.\nText can be copied from any application.\n")
self.b.move(10,10)
self.b.resize(400,200)
# clipboard
self.cb = QApplication.clipboard()
self.cb_changed_handler = self.cb.dataChanged.connect(self.clipboardChanged)
def clipboardChanged(self):
text = self.cb.text()
print(text)
self.b.insertPlainText(text + '\n')
self.cb.clear(mode=self.cb.Clipboard)
self.cb.setText("this is a text", mode=self.cb.Clipboard) # this creates an infinite loop!!
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = ExampleWindow()
mainWin.show()
sys.exit( app.exec_() )
I have also tried the following clipboardChanged
function without success, python crashes:
def clipboardChanged(self):
text = self.cb.text()
print(text)
self.b.insertPlainText(text + '\n')
# This does not work, python crashes!!
# let's disable the event listener, do what we should and restore the event
self.cb.dataChanged().disconnect()
self.cb.clear(mode=self.cb.Clipboard)
self.cb.setText("this is a text", mode=self.cb.Clipboard)
self.cb_changed_handler = self.cb.dataChanged.connect(self.clipboardChanged)
I am using Windows.
After executing this
from PyQt5.Qt import PYQT_VERSION_STR
print("PyQt version:", PYQT_VERSION_STR)
I get
PyQt version: 5.9.2
Upvotes: 2
Views: 598
Reputation: 243897
The solution is to prevent the QClipBoard dataChanged
signal from being emitted in the clipboardChanged method using blockSignals()
:
def clipboardChanged(self):
text = self.cb.text()
print(text)
self.b.insertPlainText(text + '\n')
self.cb.blockSignals(True)
self.cb.clear(mode=self.cb.Clipboard)
self.cb.setText("this is a text", mode=QClipboard.Clipboard)
self.cb.blockSignals(False)
Upvotes: 2