Executing "SCI_GOTOLINE" API of Qscintilla inside indicatorReleased() event handler is not functioning properly
Asked Answered
S

1

1

I am developing a desktop application using "PyQt4". The application contains an XML editor implemented on top of Qscintilla. However I have an issue whenever I click a hyperlink-alike text defined via indicators. The "indicatorClicked" event is invoked, but when I execute "SCI_GOTOLINE" API inside it, it goes to the desirable line properly but unluckily, for some reason, it selects the text from the clicked text position till the destination line. For me, it seems as if mouse does not get released! I tried also to use "indicatorReleased" event with no luck! Do u have any idea how to resolve this?

This is how I am hooking to indicator released event:

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

event handler is simply invoking SCI_GOTOLINE API to some line number:

 def __on_indicator_released(self, line_number, index, keys):
    self.__editor.SendScintilla(QsciScintilla.SCI_GOTOLINE, line_number)
Stefaniestefano answered 17/12, 2019 at 19:19 Comment(4)
provide a minimal reproducible exampleNanete
The issue got fixed and I posted the solution below. However, I will edit the original question and paste the code state - before the fixStefaniestefano
It's great that you found an answer, but it would also be great (for future publications) to provide an MRE as it helps the community understand your question and therefore easier to try to help you.Nanete
Sure. I totally agree with you. Thanks for your understanding :)Stefaniestefano
S
1

I got a response from @Matic Kukovec & @K.Mulier on another thread. I am posting it here so others can benefit from it.

@Matic Kukovec replied to me: "There are two solutions: Use a QTimer.singleShot inside the indicatorReleased event to execute the SCI_GOTOLINE after a short delay (I use 50ms), or inside the indicatorReleased event use: while mouse_state != data.Qt.NoButton: PyQt5.QTest.qWait(1) to wait until there is no muse button pressed, and then execute SCI_GOTOLINE."

After trying the two approaches, the singleShot-based solution worked as charm:

Hooking to an indicator_released handler:

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

Corresponding event handler:

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

Calling SCI_GOTOLINE in __go_to_line API:

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

However, The mouse_state-based solution did not work, since mouse_button equals to "Qt.NoButton" all the time.

mouse_state = QtCore.QCoreApplication.instance().mouseButtons()
while mouse_state != Qt.NoButton:
    mouse_state = QtCore.QCoreApplication.instance().mouseButtons()
    QTest.qWait(1)
Stefaniestefano answered 17/12, 2019 at 19:36 Comment(2)
Hi @Rida, I'm happy that Matic solved your problem. Thank you for posting the solution here so others can benefit from it :-)Horodko
You and Matic showed great examples of how we should benefit others. You are teaching by example <3Stefaniestefano

© 2022 - 2024 — McMap. All rights reserved.