I'm using PyQt to build a simple IDE and getting weird errors if you load an empty file. A small example script is posted below:
#!/usr/bin/env python
import sys
from PyQt4 import QtGui
class TestApp(QtGui.QMainWindow):
def __init__(self, filename=None):
super(TestApp, self).__init__()
self._editor = QtGui.QPlainTextEdit()
self._editor.modificationChanged.connect(self._change_modified)
self.setCentralWidget(self._editor)
self._editor.setPlainText('a')
def _change_modified(self, have_change):
print(have_change)
if __name__ == '__main__':
a = QtGui.QApplication([])
app = TestApp()
app.show()
sys.exit(a.exec_())
As expected, this shows a window with a plain text editor. As soon as the setPlainText
method is called, the editor emits two events: One modificationChanged
event with changes=True
, a second with changes=False
.
A bit weird, but fine.
However, if you change setPlainText('a')
to setPlainText('')
, only a single event is emitted, this time with changes=True
. Even worse, after telling the editor it's not modified with setModified(False)
, it insists it's been changed somehow.
Does anyone know what's causing this and how I can work around this issue?
Update: It seems to be a bug & also affects QPlainTextEdit.clear()
.
The workaround below places a wrapper around the QPlainTextEdit
to fix clear()
and setPlainText('')
.
#!/usr/bin/env python
import sys
from PyQt4 import QtGui
class TestApp(QtGui.QMainWindow):
def __init__(self, filename=None):
super(TestApp, self).__init__()
self._editor = PlainTextEdit()
self._editor.modificationChanged.connect(self._change_modified)
self.setCentralWidget(self._editor)
self._editor.setPlainText('')
def _change_modified(self, have_change):
print(have_change)
class PlainTextEdit(QtGui.QPlainTextEdit):
def clear(self):
self.selectAll()
cursor = self.textCursor()
cursor.removeSelectedText()
doc = self.document()
doc.clearUndoRedoStacks()
doc.setModified(False)
self.modificationChanged.emit(False)
def setPlainText(self, text):
if text:
super(PlainTextEdit, self).setPlainText(text)
else:
self.clear()
if __name__ == '__main__':
a = QtGui.QApplication([])
app = TestApp()
app.show()
sys.exit(a.exec_())