Я использую виджет QScintilla в качестве редактора кода, и я хотел бы синхронизировать c с пользовательским EditorModel. Вот двусторонняя привязка, которая работает, когда модель обновляется каждый раз, когда вводится новый символ:
class EditorModel(QObject):
code_changed = pyqtSignal(str)
def __init__(self):
super().__init__()
self._code = ""
@pyqtProperty(str, notify=code_changed)
def code(self):
return self._code
@code.setter
def code(self, code):
if self._code != code:
self._code = code
self.code_changed.emit(code)
class Editor(Qsci.QsciScintilla):
def __init__(self, parent=None):
...
self.textChanged.connect(lambda : self.model.code = self.text())
self.model.code_changed.connect(self.on_code_changed)
...
@QtCore.pyqtSlot(str)
def on_code_changed(self, code):
if code != self.text():
self.setText(code)
Но производительность очень низкая, когда текст длинный.
Единственный Компромисс, который я нашел, заключается в обновлении модели только в геттере:
class EditorModel(QObject):
code_changed = pyqtSignal(str)
def __init__(self):
super().__init__()
self._code = ""
self._code_updater = None
def set_code_updater(self, func):
self._code_updater = func
@pyqtProperty(str, notify=code_changed)
def code(self):
if self._code_updater is not None:
self._code = self._code_updater()
return self._code
@code.setter
def code(self, code):
if self._code != code:
self._code = code
self.code_changed.emit(code)
class Editor(Qsci.QsciScintilla):
def __init__(self, parent=None):
...
self.model.set_code_updater(self.text) # no more textChanged.connect
self.model.code_changed.connect(self.on_code_changed)
...
@QtCore.pyqtSlot(str)
def on_code_changed(self, code):
if code != self.text():
self.setText(code)
Я не очень доволен этим обходным путем, и мне интересно, есть ли другие способы сделать это.