Добавить подсветку синтаксиса к частям текста, вводимого в QLineEdit - PullRequest
0 голосов
/ 03 ноября 2018

Используя PySide / PyQT, мне нужно добавить подсветку синтаксиса для текста, вводимого в QLineEdit. Мне нужно выделить конкретные ключевые слова.

Я видел пост ниже с примером того, как сделать это в C ++, но я пытаюсь сделать это в Python. (Пробовал переводить с C ++ на Python, но не смог его получить ...) У кого-нибудь есть предложения, как это сделать в Python? Спасибо.

Как изменить цвет части текста в QLineEdit?

Дополнительная информация:

В настоящее время я меняю цвет всего QLineEdit следующим образом:

for dupLineEd in duplicates[1]:
    dupLineEd.setStyleSheet("QLineEdit{color:Khaki}")

Это не идеально. Что мне нужно сделать, это определить, соответствуют ли определенные слова в QLineEdit условию (в данном случае, являются ли они дубликатами слова в другом QLineEdit) и, если это так, то выделите только слово в пределах QLineEdit цветом, а не весь QLineEdit. Это выделение должно быть выполнено в режиме реального времени, когда пользователь печатает, чтобы, например, при завершении слова, если слово удовлетворяет условию, слово становится желтым. Остальная часть текста в QLineEdit не меняет цвет.

Заранее спасибо всем, у кого есть предложения!

1 Ответ

0 голосов
/ 28 ноября 2018

Лучший обходной путь, который я смог найти, - это создать новый класс QTextEdit, который ведет себя (частично) как QLineEdit.

На данный момент я заимствую класс Highligter, который работает с QTextEdit, написанный Игором Богомоловым, который размещен на github здесь: https://github.com/pyside/Examples/blob/master/examples/richtext/syntaxhighlighter/syntaxhighlighter.py

Мой полученный функциональный код выглядит следующим образом. (Вам нужно определить main_window в зависимости от вашей среды.)

class qTextEditTestUI(QtGui.QDialog):

    def __init__(self, parent=QtGui.QWidget):
        # Inherit __init__
        super(qTextEditTestUI, self).__init__(parent)


        # Set object name and window title
        self.setObjectName('qTextEditTestWindow')
        self.setWindowTitle('qTextEdit Test Window')

        # Window type (Qt.tool not Qt.Window)
        self.setWindowFlags(QtCore.Qt.Tool)


        # ATTRS

        self.highlighter = Highlighter()

        # CREATE WIDGETS

        variableFormat = QtGui.QTextCharFormat()
        #variableFormat.setFontWeight(QtGui.QFont.Bold)
        variableFormat.setForeground(QtGui.QColor('Khaki'))
        self.highlighter.addMapping('hello', variableFormat)


        # Make a TextEdit
        self.QTextEd = snglLnQTextEdit()

        # Add the TextEdit's document to the highlighter
        self.highlighter.addToDocument(self.QTextEd.document())


        # SET MASTER LAYOUT
        masterLayout = QtGui.QVBoxLayout()
        self.setLayout(masterLayout)

        # MASTER LAYOUT
        masterLayout.addWidget(self.QTextEd)
        masterLayout.addStretch()


## QLineEdit-Like QTextEdit
class snglLnQTextEdit(QtGui.QTextEdit):
    def __init__(self, parent=None):
        QtGui.QTextEdit.__init__(self, parent)

        QTextEdFontMetrics =  QtGui.QFontMetrics(self.font())
        self.QTextEdRowHeight = QTextEdFontMetrics.lineSpacing()
        self.setFixedHeight(2 * self.QTextEdRowHeight)
        self.setLineWrapMode(QtGui.QTextEdit.NoWrap)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        # CONNECT WIDGET SIGNAL
        self.textChanged.connect(self.validateCharacters)

    def validateCharacters(self):
        badChars = ['\n']
        cursor = self.textCursor()
        curPos = cursor.position()
        for badChar in badChars:
            origText = self.toPlainText()
            for char in origText:
                if char in badChars:
                    cleanText = origText.replace(char, '')
                    self.blockSignals(True)
                    self.setText(cleanText)
                    self.blockSignals(False)
                    cursor.setPosition(curPos-1)
        self.setTextCursor(cursor)

## Highligher Class written by igor-bogomolov
class Highlighter(QtCore.QObject):
    def __init__(self, parent=None):
        QtCore.QObject.__init__(self, parent)

        self.mappings = {}

    def addToDocument(self, doc):
        self.connect(doc, QtCore.SIGNAL('contentsChange(int, int, int)'), self.highlight)

    def addMapping(self, pattern, format):
        self.mappings[pattern] = format

    def highlight(self, position, removed, added):
        doc = self.sender()

        block = doc.findBlock(position)
        if not block.isValid():
            return

        if added > removed:
            endBlock = doc.findBlock(position + added)
        else:
            endBlock = block

        while block.isValid() and not (endBlock < block):
            self.highlightBlock(block)
            block = block.next()

    def highlightBlock(self, block):
        layout = block.layout()
        text = block.text()

        overrides = []

        for pattern in self.mappings:
            for m in re.finditer(pattern,text):
                range = QtGui.QTextLayout.FormatRange()
                s,e = m.span()
                range.start = s
                range.length = e-s
                range.format = self.mappings[pattern]
                overrides.append(range)

        layout.setAdditionalFormats(overrides)
        block.document().markContentsDirty(block.position(), block.length())


## Test Usage:

panl = qTextEditTestUI(parent=main_window())
panl.show()

Это сделает работу, но я не совсем доволен; это кажется неуклюжим. Я все еще надеюсь выяснить, как сделать такое выделение с помощью QLineEdit.

...