Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » PyQT4 | Следующий результат поиска в QTextEdit [RSS Feed]

#1 Апрель 30, 2018 11:04:28

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

Как находить следующие результаты поиска текста?

 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                             QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                             QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,
                             QGroupBox, QFileDialog)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
from PyQt4.QtCore import QSize
tx = '''Константин бежал по дорожке, а потом колол дрова.
Кондрат собирал корения. На улице стоял колотун.
Иван же лежал в гамаке и пил кофе с конфетами.
ваер  р
вп
фп пр
ко
афвп
ырап
авпопр
рпавап
фпре
ре р пар
ер екр
рвек'''
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'")
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(600, 250) # шир / выс окна
        self.setWindowTitle('Поиск текста') # Заголовок
        # ПЕРЕМЕННЫЕ КЛАССА
        self.find_index = 0
        # БЛОК РАЗМЕТКИ
        #grid_os = QGridLayout()
        vbox = QVBoxLayout()
        # ---
        self.pole_vivod = QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.pole_vivod.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) # QtCore.Qt.TextEditorInteraction
        vbox.addWidget(self.pole_vivod)
        # ---
        grid_UT = QGridLayout()
        vbox.addLayout(grid_UT)
        # --- --- поиск ---
        self.btn_find_clear = QtGui.QPushButton('X')
        self.btn_find_clear.clicked.connect(self.on_find_clear)
        grid_UT.addWidget(self.btn_find_clear, 1,0)
        # ---
        self.btn_find_backward = QtGui.QPushButton('◄')
        self.btn_find_backward.clicked.connect(self.on_find_backward)
        grid_UT.addWidget(self.btn_find_backward, 1,1)
        # ---
        self.btn_find_forward = QtGui.QPushButton('►')
        self.btn_find_forward.clicked.connect(self.on_find_forward)
        grid_UT.addWidget(self.btn_find_forward, 1,2)
        # ---
        self.pole_find = QLineEdit(self)
        self.pole_find.setToolTip('Поиск текста')
        self.pole_find.textChanged.connect(self.on_find_text)
        grid_UT.addWidget(self.pole_find, 1,3,1,10)
        # настройка:
        grid_UT.setColumnStretch(10, 1)
        for i in range(10):
            grid_UT.setColumnMinimumWidth(i, 10) # индекс / высота
        # --- --- end: поиск ---
        
        # ---
        self.setLayout(vbox)
        # --- ---
        Window.on_start(self)
    # ЛОГИКА
    
    def on_start(self):        
        self.pole_vivod.append(str(tx))
        self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
    # === >>> ПОИСК ТЕКСТА ===
    def on_find_text(self):
        # self.find_index # как-то использовать для списка найденных индексов
        text = self.pole_find.text()
        self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
        self.pole_vivod.find(text)
    def on_find_forward(self): # поиск вперёд
        self.find_index += 1
        self.on_find_text()
    def on_find_backward(self): # поиск назад
        self.find_index -= 1
        self.on_find_text()
    def on_find_clear(self): # очистить поиск
        self.find_index = 0
        self.pole_find.blockSignals(1) # блокировка сигналов
        self.pole_find.clear()
        self.pole_find.blockSignals(0) # отмена блокировки сигналов
        cursor = self.pole_vivod.textCursor()
        posit = cursor.position() # позиц курсора
        cursor.movePosition(posit) # происходит сброс выделения        
        self.pole_vivod.setTextCursor(cursor)
        
    # === >>> END: ПОИСК ТЕКСТА === 
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window()   
    window.show()
    sys.exit(app.exec_())
    

Отредактировано Kyrym (Апрель 30, 2018 12:48:26)

Офлайн

#2 Май 3, 2018 18:11:54

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

Это потому что вы делаете self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) тоесть каждый раз пр поиске вы возвращаете курсор на начало документа, вот оно вам и ищет каждый раз с начала. закаментите его для начала и увидите.
Для поиска в обратную сторону, нужно в find указать второй аргумент QTextDocument.FindBackward
http://doc.crossplatform.ru/qt/4.7.x/qtextedit.html#find



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Май 3, 2018 18:12:30)

Офлайн

#3 Май 12, 2018 11:45:11

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

PEHDOM
Для поиска в обратную сторону, нужно в find указать второй аргумент QTextDocument.FindBackward
Такого вопроса не было )))
PEHDOM
Это потому что вы делаете self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) то есть каждый раз пр поиске вы возвращаете курсор на начало документа, вот оно вам и ищет каждый раз с начала. закаментите его для начала и увидите.
self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) - эта строчка написана не просто так, без неё поиск становится не правильным.
Попробуйте следующую задачу. Нам надо найти текст “кон”, результатом поиска должен стать “Константин” - это самое первое слово. Однако, когда мы введём “ко”, то будет выделено слово “колокол” - это второе вхождение “ко”, потом добавляем букву “н” и получаем слово “Кондрат” - это второе вхождение “кон”, а не первое. Напомню, что найтись должен был “Константин”.

Я вижу решение своей задачи через создание списка всех вхождений искомого текста, ну и работа с индексами этого списка. Однако, может есть какой-то стандартный простой метод?

Офлайн

#4 Май 12, 2018 20:14:30

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

Ладно. Пока сделал поиск так, но работает по нажатию на кнопки:

 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                             QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                             QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,
                             QGroupBox, QFileDialog, QTextDocument)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
from PyQt4.QtCore import QSize
tx = '''Константин бежал по дорожке, а потом колол дрова.
Кондрат собирал корения. На улице стоял колотун.
Иван же лежал в гамаке и пил кофе с конфетами.
ваер  р
вп
фп пр
ко
афвп
ырап
авпопр
рпавап
фпре
ре р пар
ер екр
рвек'''
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'")
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(600, 250) # шир / выс окна
        self.setWindowTitle('Поиск текста') # Заголовок
        # ПЕРЕМЕННЫЕ КЛАССА
        self.find_index = 0
        # БЛОК РАЗМЕТКИ
        #grid_os = QGridLayout()
        vbox = QVBoxLayout()
        # ---
        self.pole_vivod = QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.pole_vivod.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) # QtCore.Qt.TextEditorInteraction
        vbox.addWidget(self.pole_vivod)
        # ---
        grid_UT = QGridLayout()
        vbox.addLayout(grid_UT)
        # --- --- поиск ---
        self.btn_find_clear = QtGui.QPushButton('X')
        self.btn_find_clear.clicked.connect(self.on_find_clear)
        grid_UT.addWidget(self.btn_find_clear, 1,0)
        # ---
        self.btn_find_backward = QtGui.QPushButton('◄')
        self.btn_find_backward.clicked.connect(self.on_find_backward)
        grid_UT.addWidget(self.btn_find_backward, 1,1)
        # ---
        self.btn_find_forward = QtGui.QPushButton('►')
        self.btn_find_forward.clicked.connect(self.on_find_forward)
        grid_UT.addWidget(self.btn_find_forward, 1,2)
        # ---
        self.pole_find = QLineEdit(self)
        self.pole_find.setToolTip('Поиск текста')
        grid_UT.addWidget(self.pole_find, 1,3,1,10)
        # ---        
        self.check_find_r = QtGui.QCheckBox("Р")
        self.check_find_r.setToolTip('Учёт регистра')
        grid_UT.addWidget(self.check_find_r, 1,14)
        # настройка:
        grid_UT.setColumnStretch(10, 1)
        for i in range(10):
            grid_UT.setColumnMinimumWidth(i, 10) # индекс / высота
        # --- --- end: поиск ---
        
        # ---
        self.setLayout(vbox)
        # --- ---
        Window.on_start(self)
    # ЛОГИКА
    
    def on_start(self):        
        self.pole_vivod.append(str(tx))
        self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
    # === >>> ПОИСК ТЕКСТА ===
    def on_find_forward(self): # поиск вперёд
        text = self.pole_find.text()
        check_find_r = self.check_find_r.isChecked()
        if check_find_r == 0: # без регистра
            self.pole_vivod.find(text)
        else:
            self.pole_vivod.find(text, QTextDocument.FindCaseSensitively)
    def on_find_backward(self): # поиск назад
        text = self.pole_find.text()
        check_find_r = self.check_find_r.isChecked()
        if check_find_r == 0: # без регистра
            self.pole_vivod.find(text, QTextDocument.FindBackward)
        else:
            self.pole_vivod.find(text, QTextDocument.FindBackward | QTextDocument.FindCaseSensitively)
    def on_find_clear(self): # очистить поиск
        self.pole_find.clear()
        cursor = self.pole_vivod.textCursor()
        posit = cursor.position() # позиц курсора
        cursor.movePosition(posit) # происходит сброс выделения        
        self.pole_vivod.setTextCursor(cursor)
        
    # === >>> END: ПОИСК ТЕКСТА === 
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window()   
    window.show()
    sys.exit(app.exec_())
    

Отредактировано Kyrym (Май 12, 2018 20:15:50)

Офлайн

#5 Май 12, 2018 21:30:54

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

Kyrym
эта строчка написана не просто так, без неё поиск становится не правильным.
нету “неправильного” поиска, есть логика вашей программы, которую вы пока не смогли ясно описать. Вы спросили как сделать чтобы оно искало следующее входжение, я ответил, что пока вы в начале каждого поска делаете moveCursor(QtGui.QTextCursor.Start) оно всегда будет искать первое вхождение. как вы это реализуете в вашем случае, зависит только от вас.Вам нужно или писать три метода для поиска: поиск сначала, поиск следующего и поиск предыдущего, или в on_find_text добавить аргумент и в зависимости от него делать поиск или сначала или с тек-позиции.
типа такого:
 ....
    # === >>> ПОИСК ТЕКСТА ===
    def on_find_text(self, text, opt=0):
        '''
        opt:
            0 искать с начала текста
            1 искать вперед с тек. позиции
            2 искать назад с тек позиции
        '''
        if opt == 0:
            self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
            self.pole_vivod.find(text)
        elif opt == 1:
            self.pole_vivod.find(text)
        elif opt == 2:
            self.pole_vivod.find(text, QTextDocument.FindBackward)
    def on_find_forward(self): # поиск вперёд
        text = self.pole_find.text()
        self.on_find_text(text, 1)
    def on_find_backward(self): # поиск назад
        text = self.pole_find.text()
        self.on_find_text(text, 2)
...



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Май 12, 2018 21:31:48)

Офлайн

#6 Май 12, 2018 23:02:50

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQT4 | Следующий результат поиска в QTextEdit

Да, меня тут осенило, если совместить мой первый код и второй, то получится то, что нужно. Ну собственно, уже слепил, работает.

 # Python 3
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                             QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                             QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,
                             QGroupBox, QFileDialog, QTextDocument)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
from PyQt4.QtCore import QSize
tx = '''Константин бежал по дорожке, а потом колол дрова.
Кондрат собирал корения. На улице стоял колотун.
Иван же лежал в гамаке и пил кофе с конфетами.
ваер  р
вп
фп пр
ко
афвп
ырап
авпопр
рпавап
фпре
ре р пар
ер екр
рвек'''
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'")
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(600, 250) # шир / выс окна
        self.setWindowTitle('Поиск текста') # Заголовок
        # БЛОК РАЗМЕТКИ
        #grid_os = QGridLayout()
        vbox = QVBoxLayout()
        # ---
        self.pole_vivod = QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.pole_vivod.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) # QtCore.Qt.TextEditorInteraction
        vbox.addWidget(self.pole_vivod)
        # ---
        grid_UT = QGridLayout()
        vbox.addLayout(grid_UT)
        # --- --- поиск ---
        self.btn_find_clear = QtGui.QPushButton('X')
        self.btn_find_clear.clicked.connect(self.on_find_clear)
        grid_UT.addWidget(self.btn_find_clear, 1,0)
        # ---
        self.btn_find_backward = QtGui.QPushButton('◄')
        self.btn_find_backward.clicked.connect(self.on_find_backward)
        grid_UT.addWidget(self.btn_find_backward, 1,1)
        # ---
        self.btn_find_forward = QtGui.QPushButton('►')
        self.btn_find_forward.clicked.connect(self.on_find_forward)
        grid_UT.addWidget(self.btn_find_forward, 1,2)
        # ---
        self.pole_find = QLineEdit(self)
        self.pole_find.setToolTip('Поиск текста')
        self.pole_find.textChanged.connect(self.on_find_text)
        grid_UT.addWidget(self.pole_find, 1,3,1,10)
        # ---        
        self.check_find_r = QtGui.QCheckBox("Р")
        self.check_find_r.setToolTip('Учёт регистра')
        grid_UT.addWidget(self.check_find_r, 1,14)
        # настройка:
        grid_UT.setColumnStretch(10, 1)
        for i in range(10):
            grid_UT.setColumnMinimumWidth(i, 10) # индекс / высота
        # --- --- end: поиск ---
        
        # ---
        self.setLayout(vbox)
        # --- ---
        Window.on_start(self)
    # ЛОГИКА
    
    def on_start(self):        
        self.pole_vivod.append(str(tx))
        self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
    # === >>> ПОИСК ТЕКСТА ===
    def on_find_text(self, text, opt=0):
        check_find_r = self.check_find_r.isChecked()
        if opt == 0:
            self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
        if check_find_r == 0: # без регистра
            if opt == 0 or opt == 1:
                self.pole_vivod.find(text)
            else:
                self.pole_vivod.find(text, QTextDocument.FindBackward)
        else: # с регистром
            if opt == 0 or opt == 1:
                self.pole_vivod.find(text, QTextDocument.FindCaseSensitively)            
            else:
                self.pole_vivod.find(text, QTextDocument.FindBackward | QTextDocument.FindCaseSensitively)
            
        
    def on_find_forward(self): # поиск вперёд
        text = self.pole_find.text()
        self.on_find_text(text, 1)
    def on_find_backward(self): # поиск назад
        text = self.pole_find.text()
        self.on_find_text(text, 2)
    def on_find_clear(self): # очистить поиск
        self.pole_find.blockSignals(1) # блокировка сигналов
        self.pole_find.clear()
        self.pole_find.blockSignals(0) # отмена блокировки сигналов
        cursor = self.pole_vivod.textCursor()
        posit = cursor.position() # позиц курсора
        cursor.movePosition(posit) # происходит сброс выделения        
        self.pole_vivod.setTextCursor(cursor)
        
    # === >>> END: ПОИСК ТЕКСТА === 
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window()   
    window.show()
    sys.exit(app.exec_())
    

Отредактировано Kyrym (Май 12, 2018 23:43:25)

Офлайн

  • Начало
  • » GUI
  • » PyQT4 | Следующий результат поиска в QTextEdit[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version