Выполнение SCI_GOTOLINE API Qscintilla внутри обработчика события IndicatorReleased() не работает должным образом

Я разрабатываю настольное приложение, используя «PyQt4». Приложение содержит XML-редактор, реализованный поверх Qscintilla. Однако у меня возникает проблема всякий раз, когда я нажимаю текст, похожий на гиперссылку, определенный с помощью индикаторов. Событие "indicatorClicked" вызывается, но когда я запускаю API "SCI_GOTOLINE" внутри него, оно правильно переходит к желаемой строке, но, к сожалению, по какой-то причине оно выбирает текст из щелкнутой текстовой позиции до строки назначения. Для меня кажется, что мышь не освобождается! Я также пытался использовать событие "indicatorReleased", но безуспешно! У вас есть идеи, как это решить?

Вот как я подключаюсь к событию выпуска индикатора:

self.__editor.indicatorReleased.connect(self.__on_indicator_released)

обработчик события просто вызывает API SCI_GOTOLINE для некоторого номера строки:

 def __on_indicator_released(self, line_number, index, keys):
    self.__editor.SendScintilla(QsciScintilla.SCI_GOTOLINE, line_number)

person Rida Shamasneh    schedule 17.12.2019    source источник
comment
предоставьте минимальный воспроизводимый пример   -  person eyllanesc    schedule 17.12.2019
comment
Проблема была исправлена, и я разместил решение ниже. Однако я отредактирую исходный вопрос и вставлю состояние кода - до исправления   -  person Rida Shamasneh    schedule 17.12.2019
comment
Замечательно, что вы нашли ответ, но было бы также здорово (для будущих публикаций) предоставить MRE, поскольку это помогает сообществу понять ваш вопрос и, следовательно, легче попытаться вам помочь.   -  person eyllanesc    schedule 17.12.2019
comment
Конечно. Я полностью согласен с тобой. Спасибо за понимание :)   -  person Rida Shamasneh    schedule 17.12.2019


Ответы (1)


Я получил ответ от @Matic Kukovec и @K.Mulier в другой ветке. Я публикую его здесь, чтобы другие могли извлечь из этого пользу.

@Matic Kukovec ответил мне: "Есть два решения: использовать QTimer.singleShot внутри события IndicatorReleased для выполнения SCI_GOTOLINE после небольшой задержки (я использую 50 мс), или внутри использования события IndicatorReleased: while mouse_state != data.Qt.NoButton: PyQt5.QTest.qWait(1), чтобы дождаться, пока не будет нажата кнопка мыши, а затем выполнить SCI_GOTOLINE."

Попробовав два подхода, решение на основе singleShot сработало как нельзя лучше:

Подключаемся к обработчику index_released:

self.__editor.indicatorReleased.connect(self.__on_indicator_released)

Соответствующий обработчик события:

def __on_indicator_released(self, line_number, index, keys):
    QTimer.singleShot(50, lambda: self.__go_to_line(line_number))

Вызов SCI_GOTOLINE в API __go_to_line:

def __go_to_line(self, line_number):
    self.__editor.SendScintilla(QsciScintilla.SCI_GOTOLINE, line_number)

Однако решение на основе mouse_state не сработало, так как mouse_button все время равно "Qt.NoButton".

mouse_state = QtCore.QCoreApplication.instance().mouseButtons()
while mouse_state != Qt.NoButton:
    mouse_state = QtCore.QCoreApplication.instance().mouseButtons()
    QTest.qWait(1)
person Rida Shamasneh    schedule 17.12.2019
comment
Привет @Rida, я рад, что Matic решил твою проблему. Спасибо, что разместили решение здесь, чтобы другие могли извлечь из него пользу :-) - person K.Mulier; 18.12.2019
comment
Вы и Матич показали отличные примеры того, как мы должны приносить пользу другим. Вы учите на примере ‹3 - person Rida Shamasneh; 18.12.2019