Как сделать текст в QTextBrowser доступным для выбора?

Я хочу иметь возможность выделять фрагмент текста нестандартным образом, как вы нажимаете на ссылку веб-сайта в середине текста ("Здравствуйте, меня зовут www.google.com", www.google.com). не выделяется, когда вы нажимаете на него. Когда вы нажимаете на него, вы попадаете на веб-сайт с тем же текстом, что и я. Я хочу, чтобы он выглядел так: «Привет, меня зовут Джефф, я живу в Лондоне, я ем картофеля каждый день», я хочу, чтобы пользователь мог выбирать каждую часть предложения отдельно («привет, меня зовут Джефф») отдельно («я живу в Лондоне») отдельно, поэтому, когда пользователь перемещает курсор мыши на предложение подсвечивается (например, готово к выбору), и после этого я хочу добавить к нему некоторые функции.

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

http://quran.ksu.edu.sa/tafseer/tabary/sura10-aya18.html

Я вас не понимаю, вы хотите, чтобы при нажатии на слово оно обязательно выделялось?

eyllanesc 29.05.2019 18:24

извините, если мое объяснение было плохим .... я хочу иметь возможность выбирать слово (или последовательность слов) вместо их выделения .... и нажимать на них так же, как вы нажимаете на внешнюю ссылку ..... www.google.com .... и иметь возможность связать это с некоторыми функциями (например: pushbutton.clicked.connect (функция)).... вся программа похожа на книгу, и я хочу иметь возможность делать дальше объяснение предложения ... поэтому, когда люди нажимают на него ... я хочу, чтобы появилась новая функция (например, появился новый текст для перевода этого предложения на другой язык)

Said Amir 29.05.2019 20:21

Хорошо, 1) выделение является частью действия по выбору 2) По вашим словам, я понимаю, что сначала вы хотите выбрать определенный текст, а затем, если вы нажмете на выбранный элемент, сработает сигнал, который вы можете подключить к функции, которая получает выбранный текст. Я не ошибаюсь?

eyllanesc 29.05.2019 20:25

С другой стороны, если вы видите, что ваше объяснение было неясным в вашей публикации, я предлагаю вам отредактировать его и улучшить.

eyllanesc 29.05.2019 20:26

и да, я отредактирую свой вопрос, как только пойму, что это даже хороший вопрос в первую очередь ... может быть, мой вопрос просто не в qt, поэтому я могу его удалить. Большое спасибо, что ответили мне

Said Amir 29.05.2019 21:03

Поскольку вы указываете, что выбор подразумевает выделение, вы не можете его отделить, выделение — это способ, которым приложение информирует пользователя о том, что что-то было выбрано. Или какова процедура, которую пользователь должен выполнить для выбора? Моя идея процедуры такова: 1) пользователь выбирает текст, например, пользователь выбирает текст «Кодирование легко», поэтому он будет выделен, а затем пользователь щелкнет где-нибудь в выделенной области, что вызовет сигнал, который отправляет выделенную (выбранную) информацию. Как вы понимаете, выделение и выделение являются синонимами в этом контексте.

eyllanesc 29.05.2019 21:07

Сделайте редактирование сейчас, чтобы улучшить его, если вы думаете, что позже вы можете улучшить его, вы тоже можете это сделать. В настоящее время ваш вопрос, основанный только на публикации, не по теме, потому что он неясен. Прочтите Как спросить и просмотрите тур

eyllanesc 29.05.2019 21:08

Да... точно... вот ссылка на то, как я хочу, чтобы это выглядело на арабском, но... quran.ksu.edu.sa/tafseer/tabary/sura10-aya18.html

Said Amir 29.05.2019 21:11

Прочитайте ссылки, которые я предоставил, отредактируйте свой вопрос (дайте более четкое объяснение, как мы обсуждаем в комментариях, а также добавьте изображение, которое всегда помогает), а когда вы это сделаете, просто попытайтесь помочь себе.

eyllanesc 29.05.2019 21:15

если это все еще сбивает с толку, я не знаю, что делать дальше, веб-сайт объясняет все, что я хочу сказать, за 2 секунды

Said Amir 29.05.2019 21:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
10
492
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот начало. В приведенном ниже коде кликабельные фразы в тексте преобразуются в упорядоченный список текстовых курсоров. При перемещении мыши (т. е. когда происходит событие mouseMove) позиция в тексте под указателем мыши сравнивается с этим списком текстовых курсоров. Если эта позиция попадает в границы курсора в списке, соответствующая фраза подсвечивается установкой дополнительных выборов браузера. Когда кнопка мыши нажата и мышь находится над кликабельной фразой, испускается сигнал, содержащий текстовый курсор, соответствующий выбранной фразе в тексте. Затем этот сигнал можно подключить к слоту другого виджета для дальнейших действий (например, открыть окно сообщения, как в примере ниже).

from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtWidgets import QTextBrowser, QApplication, QMessageBox
from PyQt5.QtGui import QFont, QSyntaxHighlighter, QTextCharFormat, QTextCursor

import bisect, re


class MyHighlighter(QSyntaxHighlighter):
    def __init__(self, keywords, parent):
        super().__init__(parent)
        self.keywords = keywords

    def highlightBlock(self, block):
        if not self.keywords:
            return
        charFormat = QTextCharFormat()
        charFormat.setFontWeight(QFont.Bold)
        charFormat.setForeground(Qt.darkMagenta)
        regex = re.compile('|'.join(self.keywords), re.IGNORECASE)
        result = regex.search(block, 0)
        while result:
            self.setFormat(result.start(),result.end()-result.start(), charFormat)
            result = regex.search(block, result.end())


class MyBrowser(QTextBrowser):
    text_clicked = pyqtSignal("QTextCursor")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setMouseTracking(True)
        self.setTextInteractionFlags(Qt.NoTextInteraction)

        # self.phrases contains all phrases that should be clickable.
        self.phrases = set()
        self.cursors = []

        # ExtraSelection object for highlighting phrases under the mouse cursor
        self.selection = QTextBrowser.ExtraSelection()
        self.selection.format.setBackground(Qt.blue)
        self.selection.format.setForeground(Qt.white)
        self.selected_cursor = None

        # custom highlighter for highlighting all phrases
        self.highlighter = MyHighlighter(self.phrases, self)
        self.document().contentsChange.connect(self.text_has_changed)

    @property
    def selected_cursor(self):
        return None if self.selection.cursor == QTextCursor() else self.selection.cursor

    @selected_cursor.setter
    def selected_cursor(self, cursor):
        if cursor is None:
            cursor = QTextCursor()
        if self.selection.cursor != cursor:
            self.selection.cursor = cursor
            self.setExtraSelections([self.selection])

    def mouseMoveEvent(self, event):
        ''' Update currently selected cursor '''
        cursor = self.cursorForPosition(event.pos())
        self.selected_cursor = self.find_selected_cursor(cursor)

    def mouseReleaseEvent(self, event):
        ''' Emit self.selected_cursor signal when currently hovering over selectable phrase'''
        if self.selected_cursor:
            self.text_clicked.emit(self.selected_cursor)
            self.selected_cursor = None

    def add_phrase(self, phrase):
        ''' Add phrase to set of phrases and update list of text cursors'''
        if phrase not in self.phrases:
            self.phrases.add(phrase)
            self.find_cursors(phrase)
            self.highlighter.rehighlight()

    def find_cursors(self, phrase):
        ''' Find all occurrences of phrase in the current document and add corresponding text cursor
        to self.cursors '''
        if not phrase:
            return
        self.moveCursor(self.textCursor().Start)
        while self.find(phrase):
            cursor = self.textCursor()
            bisect.insort(self.cursors, cursor)
        self.moveCursor(self.textCursor().Start)

    def find_selected_cursor(self, cursor):
        ''' return text cursor corresponding to current mouse position or None if mouse not currently
        over selectable phrase'''
        position = cursor.position()
        index = bisect.bisect(self.cursors, cursor)
        if index < len(self.cursors) and self.cursors[index].anchor() <= position:
            return self.cursors[index]
        return None

    def text_has_changed(self):
        self.cursors.clear()
        self.selected_cursor = None
        for phrase in self.phrases:
            self.find_cursors(phrase)
            self.highlighter.rehighlight()


def text_message(widget):
    def inner(cursor):
        text = cursor.selectedText()
        pos = cursor.selectionStart()
        QMessageBox.information(widget, 'Information',
                f'You have clicked on the phrase <b>{text}</b><br>'
                f'which starts at position {pos} in the text')
    return inner


if __name__= = "__main__":
    app = QApplication([])
    window = MyBrowser()
    window.resize(400,300)
    information = text_message(window)

    text = '''
    <h1>Title</h1>
    <p>This is a random text with. The following words are highlighted</p>
    <ul>
    <li>keyword1</li>
    <li>keyword2</li>
    </ul>
    <p>Click on either keyword1 or keyword2 to get more info. 
    '''

    window.add_phrase('keyword1')
    window.add_phrase('keyword2')
    window.setText(text)
    window.text_clicked.connect(information)
    window.show()
    app.exec()

Ты Мужчина ... большое спасибо ... это именно то, что я хотел. если бы я мог проголосовать за вас 1k, я бы сделал это ... но, к сожалению, я не могу делать видимые проголосования, потому что моя репутация меньше 15 (я новичок на этом сайте) ..... еще раз большое спасибо, вы спасли мой день.

Said Amir 01.06.2019 18:33

Другие вопросы по теме