Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 10.02.2018
Сообщений: 22

Изменить цвета определенных символов в QTextEdit

24.04.2024, 02:03. Показов 1608. Ответов 8

Студворк — интернет-сервис помощи студентам
Есть 2 QTextEdit: textedit - для ввода текста; textedit_bg - фоновый текст, с которого вводятся символы.

Нужно, чтобы при вводе неверного символа, он окрашивался в красный в textedit, также символ заменяется и в textedit_bg, но уже без изменения цвета (т.к его не будет видно). Если неверный символ стирается, вернуть фоновый символ, который был до изменения. И так должно работать через интервалы, т.е правильные и неправильные символы могут чередоваться.

Пытался использовать QSyntaxHighlighter, но так ничего и не получилось.

Пока получилось сделать так, что фоновый символ менялся на неправильный, и при его удалении, фоновый становился прежним.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from sys import argv, exit
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from random import shuffle
 
texts = ['В тихой деревне жил старик. Он каждый день сажал цветы у своего дома. Однажды он обнаружил, '
               'что один из цветов начал говорить с ним. Цветок рассказывал ему о своей жизни и приключениях. Старик '
               'слушал его внимательно и улыбался.',
               'Господа, глубокий уровень погружения не даёт нам иного выбора, кроме определения системы массового '
               'участия. Равным образом, реализация намеченных плановых заданий в значительной степени обусловливает '
               'важность экономической целесообразности принимаемых решений. Есть над чем задуматься: действия '
               'представителей оппозиции объективно рассмотрены соответствующими инстанциями.',
               'Прежде всего, высокотехнологичная концепция общественного уклада является качественно новой ступенью '
               'анализа существующих паттернов поведения. Следует отметить, что новая модель организационной '
               'деятельности не даёт нам иного выбора, кроме определения укрепления моральных ценностей. Но '
               'реплицированные с зарубежных источников, современные исследования неоднозначны и будут обнародованы!']
 
 
class Window(QMainWindow):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle('TextEdit')
        self.setMinimumSize(820, 0)
        self.setMaximumSize(820, 1200)
 
        self.centralwidget = QWidget(self)
        self.centralwidget.setObjectName(u"centralwidget")
        self.setCentralWidget(self.centralwidget)
 
        self.layout = QGridLayout(self.centralwidget)
        self.layout.setObjectName(u"layout")
 
        self.textedit_bg = QTextEdit(self)
        self.textedit_bg.setObjectName(u"textedit_bg")
        self.textedit_bg.setStyleSheet('''
            #textedit_bg {
                background-color: #FF7F50;
                color: #FFFF00;
                font: 16pt "Lato";
            }
        ''')
        self.textedit_bg.setWordWrapMode(QTextOption.NoWrap)
 
        self.textedit = QTextEdit(self)  # !!! lineedit
        self.textedit.setObjectName(u"textedit")
        self.textedit.setStyleSheet('''
            #textedit {
                background-color: transparent;
                color: #0000CD;
                font: 16pt "Lato";
            }
        ''')
        self.textedit.setWordWrapMode(QTextOption.NoWrap)
 
        self.textedit.cursorPositionChanged.connect(self._change_cursor)
 
        self.layout.addWidget(self.textedit_bg, 1, 1)
        self.layout.addWidget(self.textedit, 1, 1)
 
        self.button = QPushButton('тык', self)
        self.layout.addWidget(self.button, 2, 1)
 
        self.button.clicked.connect(self.capacity)
 
        self.textedit_bg.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.textedit_bg.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.textedit.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.textedit.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.textedit_bg.setFixedHeight(132)
        self.textedit.setFixedHeight(132)
        self.textedit.setFocus()
 
        self.text_res = ''
        self.index = 0
 
        self.textedit.textChanged.connect(self.result)
 
    def result(self):
        text = self.textedit.toPlainText()
        text_bg = self.textedit_bg.toPlainText().split('\n')[0]
        text_no_mistakes = '\n'.join(self.text_res[self.index - 1:self.index + 3])
        text_entered = ''
 
        if 0 <= len(text) <= len(text_bg):
            for i, t in enumerate(text_bg[:len(text)]):
                if t != text[i]:
                    text_entered += text[i]
                    continue
                text_entered += t
            self.textedit_bg.setText(text_entered + text_no_mistakes[len(text):])
 
        if len(text) > len(text_bg.split('\n')[0]):
            self.textedit.textCursor().deletePreviousChar()
            return
 
    def capacity(self):
        if not self.text_res:
            self.text_res = self.get_texts()
 
        if self.index == len(self.text_res) - 4:
            for i in self.text_res[:self.index]:
                self.text_res.remove(i)
            self.text_res += self.get_texts()
            self.index = 0
 
        text = '\n'.join(self.text_res[self.index:self.index + 4])
        self.textedit_bg.setText(text)
        self.index += 1
 
    def get_texts(self):
        shuffle(texts)
 
        result = []
        for i, item in enumerate(texts):
            lst = []
            for w in item.split():
                if 787 < self.__get_pixels_wide(' '.join(lst + [w])):
                    result.append(lst)
                    lst = []
                lst.append(w)
            result.append(lst)
 
        return list(map(' '.join, result))
 
    def _change_cursor(self):
        cursor = self.textedit.textCursor()
        if cursor.positionInBlock() < len(self.textedit.document().toPlainText()):
            cursor.movePosition(QTextCursor.End)
            self.textedit.setTextCursor(cursor)
 
    def __get_pixels_wide(self, words):
        return self.textedit_bg.fontMetrics().boundingRect(words).width()
 
 
if __name__ == "__main__":
    app = QApplication(argv)
    window = Window()
    window.show()
    exit(app.exec())
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.04.2024, 02:03
Ответы с готовыми решениями:

Выравнивание символов и изменение цвета определённых символов
создание массива. как выровнять символы друг под другом при выводе. есть определённое задание, и нужно выделить символы выше главной...

Изменение цвета определенных символов в maskedTextBox
Можно ли в maskedTextBox изменить цвета определенных символов? Например, мне для наглядности нужно сделать 3-й и 4-й символы одним...

Как изменить цвет определенных символов в консоли
Мне нужно в консоли поменять цвет определённых символов и их фона. В C# это легко делается, а вот в C++ я не знаю как это делать. Короче,...

8
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,762
24.04.2024, 15:58
я правильно понял ,что неверный символ - это несовпадение текста в двух QTextEdit?
0
0 / 0 / 0
Регистрация: 10.02.2018
Сообщений: 22
24.04.2024, 17:34  [ТС]
Цитата Сообщение от vic5710 Посмотреть сообщение
я правильно понял ,что неверный символ - это несовпадение текста в двух QTextEdit?
Не всегда текста, а определенных символов, которые находятся на одинаковых индексах.
К примеру есть фраза: "Привет, мир!" - она написана на фоновом QTextEdit.
Пользователь вводит неверный символ - А, получается такой результат:
Фоновый текст - "Аривет, мир!", основной текст - А. Если пользователь стирает этот неверный символ, то фоновый текст становится прежнем, т.е "Привет, мир!".
Ну и как я написал, что неверные символы могут чередоваться.
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,762
24.04.2024, 17:45
не совсем я понял, ну типа так
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
 
pattern = 'qwerty asdfghj'
 
class Highlighter(QSyntaxHighlighter):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.idx =  []
        self.fmt = QTextCharFormat()
        self.fmt.setForeground(Qt.yellow)
        self.fmt.setBackground(Qt.black)
        self.fmt.setFontWeight(QFont.Bold)
 
    def highlightBlock(self, text):
        for i in self.idx:
            self.setFormat(i, 1, self.fmt)
 
class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.edit = QTextEdit()
        self.setCentralWidget(self.edit)
        self.h = Highlighter(self.edit.document())
        self.edit.textChanged.connect(self.result)
 
    def result(self):
        text = self.edit.toPlainText()
        pos = min(self.edit.textCursor().position(),len(pattern))
        if text:
            self.h.idx = []
            if pattern[:pos] != text[:pos]:
                for i in range(pos):
                    if text[i] != pattern[i]:
                        self.h.idx.append(i)
 
if __name__ == "__main__":
    app = QApplication([])
    w = Window()
    w.setFont(QFont('Arial',16))
    w.show()
    app.exec()
0
0 / 0 / 0
Регистрация: 10.02.2018
Сообщений: 22
24.04.2024, 21:17  [ТС]
Если писать неверный символ, он не сразу окрашивается
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,762
24.04.2024, 23:05
Цитата Сообщение от HyperBomj Посмотреть сообщение
не сразу окрашивается
таки да
запилил так
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
 
pattern = 'qwerty asdfghj'
 
class Highlighter(QSyntaxHighlighter):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.idx = set()
        self.fmt = QTextCharFormat()
        self.fmt.setForeground(Qt.yellow)
        self.fmt.setBackground(Qt.black)
        
    def highlightBlock(self, text):
        print(text,self.idx)
        for i in self.idx:
            self.setFormat(i, 1, self.fmt)
            
class TextDocument(QTextDocument):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.h = Highlighter(self)
        self.contentsChange.connect(self.on_change)
        
    def on_change(self,pos,num_rm, num_add):
        text = self.toPlainText()
        if not text: return
        pos = pos - num_rm + num_add - 1
        if text[pos] != pattern[pos]:
            self.h.idx.add(pos)
            self.h.rehighlight()
        else: 
            try: self.h.idx.remove(pos)
            except: pass
                                
class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.edit = QTextEdit()
        self.edit.setDocument(TextDocument())
        self.setCentralWidget(self.edit)        
 
if __name__ == "__main__":
    app = QApplication([])
    w = Window()
    w.setFont(QFont('Arial',16))
    w.show()
    app.exec()
может не оптимально но работает
0
0 / 0 / 0
Регистрация: 10.02.2018
Сообщений: 22
25.04.2024, 01:32  [ТС]
Когда стираешь символ, он не пропадает из множества
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,762
25.04.2024, 16:01
Лучший ответ Сообщение было отмечено HyperBomj как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
    def on_change(self,pos, num_rm, num_add):
        text = self.toPlainText()
        if not text: 
            return
        pos = pos + num_add
        self.h.idx = []
        if text[:pos] != pattern[:pos]:
            for i in range(pos):
                if text[i] != pattern[i]:
                    self.h.idx.append(i)
        self.h.rehighlight()
Добавлено через 49 секунд
дальше сами уже

Добавлено через 4 часа 20 минут
после утреннего кофе все оказалось проще
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
 
 
pattern = 'qwerty asdfghj'
class Highlighter(QSyntaxHighlighter):
    
    def highlightBlock(self, text):
        ln = min(len(text),len(pattern))
        for i in range(ln):
            if text[i] != pattern[i]:
                self.setFormat(i, 1, Qt.red)
            
class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.edit = QTextEdit()
        self.hi = Highlighter(self.edit.document())
        self.setCentralWidget(self.edit)        
 
if __name__ == "__main__":
    app = QApplication([])
    w = Window()
    w.setFont(QFont('Arial',16))
    w.show()
    app.exec()
1
0 / 0 / 0
Регистрация: 10.02.2018
Сообщений: 22
25.04.2024, 17:58  [ТС]
Большое спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.04.2024, 17:58
Помогаю со студенческими работами здесь

Вывод символов, расположенных после определённых символов в определённых строках заданного файла
Есть файл &quot;work/Разобранные/%capp%/apktool.yml&quot; (Значение %capp% задаётся свыше...) Такого типа: version: 2.0.0-Beta9 apkFileName:...

QTextEdit + разные цвета букв
Каким образом можно выводить буквы разного цвета в QPlainTextEdit/QTextEdit не используя html? Я пытался это делать вот так: void...

Смена цвета границ QTextEdit
здравствуйте, столкнулся с проблемой смены цвета границ QTextEdit. прописываю следующим образом...

Подсчёт количество символов в QTextEdit
Возникла такая проблема. Хочу создать небольшую программку, которая показывает количество символов в введённой строке(TextEdit). Но при...

Как изменить логику отображения текста в QTextEdit
В графическом компоненте QTextEdit имеются вертикальная и горизонтальная полосы прокрутки. Сейчас логика работы этих элементов такова:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru