Qt 语法突出显示无法从QMainWindow中工作

Qt 语法突出显示无法从QMainWindow中工作,qt,pyqt,qt4,Qt,Pyqt,Qt4,我正在尝试使用PyQt4实现语法高亮显示。我尝试过的示例工作得很好,但一旦我将其应用到应用程序中,突出显示就会停止工作 我创建了一个简单的示例来重现下面的问题。我已经删除了所有正则表达式,除了注释一:以#开头的行应该是粗体和绿色: from PyQt4 import QtGui, QtCore class Highlighter(QtGui.QSyntaxHighlighter): def __init__(self, document): QtGui.QSyntaxHi

我正在尝试使用PyQt4实现语法高亮显示。我尝试过的示例工作得很好,但一旦我将其应用到应用程序中,突出显示就会停止工作

我创建了一个简单的示例来重现下面的问题。我已经删除了所有正则表达式,除了注释一:以#开头的行应该是粗体和绿色:

from PyQt4 import QtGui, QtCore
class Highlighter(QtGui.QSyntaxHighlighter):
    def __init__(self, document):
        QtGui.QSyntaxHighlighter.__init__(self, document)
        rules = []
        style = QtGui.QTextCharFormat()
        style.setForeground(QtGui.QColor('darkGreen'))
        style.setFontWeight(QtGui.QFont.Bold)
        rules.append((r'#[^\n]*', style))
        self._rules = [(QtCore.QRegExp(pat), fmt) for (pat, fmt) in rules]
    def highlightBlock(self, text):
        for (pattern, style) in self._rules:
            i = pattern.indexIn(text, 0)
            while i >= 0:
                n = pattern.matchedLength()
                self.setFormat(i, n, style)
                i = pattern.indexIn(text, i + n)
        self.setCurrentBlockState(0)
如果我像这样使用荧光灯,它工作得很好:

app = QtGui.QApplication([])
editor = QtGui.QPlainTextEdit()
highlight = Highlighter(editor.document())
editor.show()
app.exec_()
class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        editor = QtGui.QPlainTextEdit()
        highlighter = Highlighter(editor.document())
        self.setCentralWidget(editor)
app = QtGui.QApplication([])
window = MainWindow()
window.show()
app.exec_()
但在qmain窗口中使用时失败,如下所示:

app = QtGui.QApplication([])
editor = QtGui.QPlainTextEdit()
highlight = Highlighter(editor.document())
editor.show()
app.exec_()
class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        editor = QtGui.QPlainTextEdit()
        highlighter = Highlighter(editor.document())
        self.setCentralWidget(editor)
app = QtGui.QApplication([])
window = MainWindow()
window.show()
app.exec_()
谁能告诉我我做错了什么

谢谢,
迈克尔

你需要保留一个荧光灯的参考号。所以,只要做:

    self.highlighter = Highlighter(editor.document())
编辑

更准确地说:您需要保留对
QSyntaxHighlighter
子类的python部分的引用。传递给构造函数的父对象将拥有highlighter,但Qt显然也不会自动管理python部分

这里是真正的区别:

    print(repr(self.editor.document().children())) ...

    # without keeping a reference
    [<PyQt4.QtGui.QPlainTextDocumentLayout object at 0x7f8590909b88>
     <PyQt4.QtGui.QSyntaxHighlighter object at 0x7f8590909c18>]

    # with a reference
    [<PyQt4.QtGui.QPlainTextDocumentLayout object at 0x7f56b7898c18>,
     <__main__.Highlighter object at 0x7f56b7898a68>]
print(repr(self.editor.document().children())。。。
#不保留推荐人
[
]
#引用
[,
]

因此,重新实现的
highlightBlock
函数将对Qt不可见,除非您保留一个引用。

您是否使用示例中的正则表达式?如果没有,你用类似的东西测试过吗?谢谢!还没有尝试过替代正则表达式,但是如果您查看示例的底部,您会发现它在直接运行时工作正常,只有在将编辑器小部件嵌入QMainWindow时,它才会停止工作。这表明正则表达式很好。我更新了这个问题,让它更清楚。非常感谢!这简直让我发疯。(我发现它在PySide中有效,显然有人引用了它…)所以这只是一个垃圾收集问题?@MichaelClerx。不完全正确:请参阅我的更新答案。在跟踪所有权等方面,PySide和PyQt之间有明显的区别。非常感谢!如果没有这篇文章,我永远也不会明白这一点!