在QPlainTextEdit Dedenting功能使段错误如果最后一行是参与(Dedenting

2019-10-22 09:50发布

我的工作应该有智能缩进/ DEDENT语言行为源代码编辑器。 然而,我dedenting方法似乎导致分段错误。 我会很高兴,如果有人可以明白为什么。

这里有一个小例子:

#!/usr/bin/env python
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
from PyQt4 import QtGui
from PyQt4.QtCore import Qt
class Editor(QtGui.QPlainTextEdit):
    def keyPressEvent(self, event):
        key = event.key()
        if key == Qt.Key_Backtab:
            cursor = self.textCursor()
            start, end = cursor.selectionStart(), cursor.selectionEnd()
            cursor.beginEditBlock()
            b = self.document().findBlock(start)
            while b.isValid() and b.position() <= end:
                t = b.text()
                p1 = b.position()
                p2 = p1 + min(4, len(t) - len(t.lstrip()))
                cursor.setPosition(p1)
                cursor.setPosition(p2, QtGui.QTextCursor.KeepAnchor)
                cursor.removeSelectedText()
                b = b.next()
            cursor.endEditBlock()
        else:
            super(Editor, self).keyPressEvent(event)
class Window(QtGui.QMainWindow):
    """
    New GUI for editing ``.mmt`` files.
    """
    def __init__(self, filename=None):
        super(Window, self).__init__()
        self.e = Editor()
        self.e.setPlainText('Line 1\n    Line 2\n    Line 3')
        self.setCentralWidget(self.e)
        self.e.setFocus()
if __name__ == '__main__':
    a = QtGui.QApplication([])
    w = Window()
    w.show()
    a.exec_()

为了重建,进行选择开始在第二行和第三行结束,然后按Shift+Tab以DEDENT语言和End触发段错误。

平台:

  • 运行在Fedora(Linux版)
  • 蟒2.7.8(默认情况下,2014年11月10日,8时19分18秒)[GCC 4.9.2 20141101(红帽4.9.2-1)]
  • PyQt的4.8.6(但它在PySide发生过)

更新:

  • 看来,这个错误只发生如果cursor.beginEditBlock()cursor.endEditBlock()的使用,也可参见: QTextCursor和beginEditBlock

谢谢

Answer 1:

这似乎是在Qt的错误:

https://bugreports.qt.io/browse/QTBUG-30051

显然,编辑从QTextCursor.beginEditBlock(内多块),导致最后一个块的布局打破,这在我的情况是导致段错误。

一个变通可重写dedenting代码作为一个单一的动作(确定文本dedenting后,删除所有选定的线,具有新的文本替换)

如果有人知道一个更好的解决办法,请让我知道!



文章来源: Dedenting function in QPlainTextEdit causes segfault if last line is involved