PyQt избегает попадания в бесконечный цикл при обработке события - PullRequest
2 голосов
/ 01 октября 2019

В PyQt я пытаюсь получать содержимое буфера обмена каждый раз, когда он изменяется, выполняю некоторые операции, чтобы вычислить вывод в виде текста и снова поместить его в буфер обмена.

Кажется, проблема в том, что когда я меняю содержимое буфера обмена внутри функции обработки событий «содержимое буфера обмена изменилось», это вызывает бесконечный вызов этой функции снова и снова.

Это код, который я использую:

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_() )

Я также безуспешно попробовал следующую функцию clipboardChanged, сбой Python:

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)

Яиспользуя Windows.

После выполнения этого

from PyQt5.Qt import PYQT_VERSION_STR
print("PyQt version:", PYQT_VERSION_STR)

я получаю

PyQt version: 5.9.2

1 Ответ

2 голосов
/ 01 октября 2019

Решение состоит в том, чтобы предотвратить передачу сигнала QClipBoard dataChanged в метод clipboardChanged с использованием blockSignals():

def clipboardChanged(self):
    text = self.cb.text()
    print(text)
    self.b.insertPlainText(text + '\n')
    <b>self.cb.blockSignals(True)</b>
    self.cb.clear(mode=self.cb.Clipboard)
    self.cb.setText("this is a text", mode=QClipboard.Clipboard)   
    <b>self.cb.blockSignals(False)</b>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...