Set within an Entry the selected content in a Text

1

I am finishing to implement a typical search engine in a text editor.

The call to open the search panel can be made from the available menu option "Search> " or with the key combination "CTRL + F".

Calling the search engine is when you build your entire panel with all the necessary elements (buttons, entry box, etc.).
And, within the same construction of the panel, I consider the fact if there is something selected in the Text , to load it as the initial content of Entry of the search engine.

(where self.text_01 is the name of the Text and '' the one of the entry of the search engine)

    # ...

    # Si hay un texto seleccionado...
    if(self.text_01.tag_ranges('sel')):
        TXT_seleccionado = self.text_01.get(tk.SEL_FIRST, tk.SEL_LAST)
        self.entr_str.insert(0, TXT_seleccionado)

    # ...

The consideration of a combination of keys to open the search panel I put it like this:

    # Combinación de teclas para abrir el panel de "Buscar"
    self.bind('<Control-f>', self.buscar)

Here you can see the complete code to which I refer (which already exists in response to another of my questions).

And the question would be, why do I get to load, initially, in Entry , the content selected in Text if I access the menu option but NO load if I access the key combination "CTRL + F"?

What would it take to do to load it, properly, by both options?
(provided there was something selected in Text , of course)

Thank you.

    
asked by zacktagnan 11.06.2018 в 13:19
source

1 answer

1

First you have to keep in mind that the combination Ctrl + F is one of the predefined key combinations for tkinter.Text and in fact the effect is exactly the same to press ▶ .

If you notice, when you press Ctrl + F the cursor advances one character to the right of the last selected character and then the secondary window opens. The events in Tkinter are propagated in the following order:

  • Instance of the widget on which the event occurs.
  • Class of the widgets in which the event is generated.
  • Widget father of the widget in which the event is generated.
  • Bindings defined by .bind_all() .
  • The error in your case is that you create the link at instance level of MainApp :

    self.bind('<Control-f>', self.buscar)
    

    So when the event is generated, it is first called the binding of the widget class self.text_01 (advances the cursor on a character) and then the event is propagated to its parent widget, in this case the instance of MainApp and the call to self.buscar occurs. Of course, it is no longer useful because when you move the cursor a character every selection is lost ...

    The solution is very simple in fact, perform the binding at self.text_01 , in __init__ of MainApp at any time after declaring self.text_01 haz:

    self.text_01.bind('<Control-f>', self.buscar)
    

    and remove self.bind('<Control-f>', self.buscar) .

    This overwrites the default binding associated with Ctrl + F in tkinter.Text .

    Remember that if you want the event not to propagate (in this case it does not matter since tkinter.Tk has no defined binding for Ctrl + F ) you must do that self.buscar (or whatever method) returns "break":

    self buscar(self, event=None):
      ...
      ...
      ...
      return "break"
    
        
    answered by 11.06.2018 / 23:23
    source