2

Picture of my GUI for clarity

I made a tool that plays audio from youtube. I want it to pause when the spacebar is pressed. I do this by this piece of code:

win.bind('<space>',lambda event:funcPP(player, btnPP))

win is my window, funcPP is the play/pause function.

My problem is that I have also an Entry in my window (for searching videos) and of course it is impractical if the video pauses everytime when I search a new video and press Spacebar. And the real problem is that, once I have clicked the Entry field, the focus stays there. It doesn't go away after clicking somewhere else! This sabotages my Spacebar shortcut.

Any tips how I can solve this?

  • Instead of binding the event to `win`, you should bind it to some widget that has focus when the video is playing. When the user types something in the search bar, the focus will be shifted to the entry and hitting the space bar will not pause the video. – Sriram Srinivasan Apr 08 '22 at 16:43
  • After using the search bar, if the user clicks on some part of the video, the focus should default be transferred to the video widget. The transfer of focus will happen naturally. However, for some reason, if you want to force a widget to take focus, use `.focus_set()`. – Sriram Srinivasan Apr 08 '22 at 17:05
  • I have not totally explained well. it is not a video player, and there is no widget that shows the audio player; the audio plays in the background, and there is only buttons to do things like skip forward, skip back, pause play, etc. But once focus is on the Entry field, it doesnt go away from there – Willem van Houten Apr 08 '22 at 18:18
  • Could you post a minimal section of your code relevant to the problem you are facing? It would be easier to give you suggestions based on how you have coded till now. – Sriram Srinivasan Apr 09 '22 at 08:18
  • Ok, I can totally reformulate my problem and question. . . . .. . Problem: I have a GUI with an entry-widget in it. Once you click the entry, the focus will be on the entry, and doesnt go away, not even when I click on a button or anywhere in the GUI window. . . . . Question: how do I make it so that the focus goes away from the entry when I click anywhere else but on the entry? For example, if I click somewhere on the background of the window, I would like the focus to go there. – Willem van Houten Apr 09 '22 at 10:54
  • Use `.bind("", lambda e: .focus_set())` on every widget except the entry. Every time the user left-clicks on ``, the focus will be transferred to that widget. If you want to do the same for middle clicks and right clicks, you can use `` and `` respectively. – Sriram Srinivasan Apr 09 '22 at 10:59
  • Thank you, but the problem is this: How do I distinguish between the background of the window, and the entry field? So, if I say window.bind(...etc..) , then this includes my entry. So how do I get the focus to the entry when I click the entry, but away from the entry when I click on for example an empty space next to the entry? – Willem van Houten Apr 09 '22 at 11:19
  • 1
    SOLVED!! win.bind_all("", lambda event: event.widget.focus_set()) – Willem van Houten Apr 09 '22 at 11:21

1 Answers1

1

I found the solution.

With:

win.bind_all("<Button-1>", lambda event: event.widget.focus_set())

It is possible to put the focus whereever one clicks.

then:

win.bind('<space>',lambda event:funcPPTRANSFER(player))

To bind spacebar to the whole window

then:

def funcPPTRANSFER(player):
    if str(win.focus_get()) != str(".!entry"):
        funcPP(player)

Have the function check whether the spacebar was sent from the entry or from somwhere else in the window

EDIT: Another thing I found now: https://stackoverflow.com/a/56519799/18664063

if isinstance(event.widget,tk.Tk): #check if event widget is Tk root window

very nice function that might help as well in this project.

  • Please consider accepting your answer (by clicking the little gray check under the vote arrows), so that other users know the question has been answered satisfactorily. – Sylvester Kruin Apr 12 '22 at 21:12