I am writing an application in Python using Tkinter to manage my GUI.
There is a text entry box on which I am trying to implement an autocompletion function which will bind to the Tab key.
I have bound the tab key to my entry box, but when I press tab, the program attempts to cycle between GUI elements.
How do I override this default behavior so that the GUI will only carry out my specified command on the key press?
Return 'break' at the end of your event handler. It interrupts event propagation.
def my_tab_handler(event):
... # handle tab event
return 'break' # interrupts event propagation to default handlers
Related
I have created a game which has a pause feature. Once the player presses the escape key whilst a game is playing, the menu enables, once escaped is pressed again it disables the menu and resumes the game. But when i open my program and press escape without launching a game first the game crashes causes theirs no game to resume. How could i disable the escape key until at least one game has started.
I am using the Pygame-menu module by ppizarror to create my gui, iv'e tried looking up my question but no one has a clear answer. Below is the main parts of code from two different classes that handles the pause feature.
Class EntertheGauntlet:
# a function used throughout the menus that disables the previous menu for
the new one to be displayed
def resume_feature():
# disables menu
self.main_menu.disable()
# resumes the game paused in the background by calling upon it
from the main gameloop
self.game.main()
Class GUI:
# a function used throughout the game that initiates when the new
game button is pressed
def start_new():
# disable previous menu
self.main_menu.disable()
# Start new game by calling variable from EscapeTheGauntlet.py
self.game = EscapeTheGauntlet(self.window, clock, self.sfx)
# sets this new updated screen to the new main window
self.game.main()
The only solution i can see is disabling the escape key until the start new game feature is called upon at least once. Could you please show me how i would do that.
What you're suggesting sounds unnecessarily complex. You cannot mess with the system drivers of the keyboard, or with the key-to-character mapping, because the user might be working in a different window with a different program where the escape key is needed.
Can't you re-write your code that handles the pause function to check whether there is a paused game? Initialize some variable with False when the application starts, and set it to True when the function you expect to be called is called.
I have a Python 3.7 tkinter GUI, and within the GUI I have implemented up-down arrow key controls for the main part of the application. Next to it I have a list box that also controls the application but in a different way, and by default AFTER a listbox selection has been made the listbox selection will scroll with up and down arrows. So, after I've used the list box in the app, the arrow key triggers an up arrow event in both the main part of the application and in the list box. This triggers my application to respond in the change in list box selection by loading new data into the main app. This is obviously unacceptable.
How can I disable the arrow key controls feature of tkinter's
ListBox?
I've tried configuring the listbox to not take focus, but this doesn't seem to disable the feature.
Edit:
I solved this by binding the list box's FocusIn event to a function that immediately focus's something else. This is far from ideal, as the code now focus's in then changes focus for no reason. If there is a way to disable focus on a widget completely or disable the list box key bindings that would be a preferred solution.
from tkinter import *
class App:
def __init__(self):
self.root = Tk()
self.dummy_widget = Label()
self.lb = ListBox(master=self.root)
self.lb.bind("<FocusIn>", lambda event: self.dummy_widget.focus())
# Additional setup and packing widgets...
if __name__ == '__main__':
mainloop()
This seems very "hacky", although it does the job perfectly.
How can I disable the arrow key controls feature of tkinter's ListBox?
Create your own bindings for the events you want to override, in the widget in which you want them overridden. Do anything you want in that function (including nothing), and then return the string break, which is the documented way to prevent events from being processed any further.
For a more extensive description of how bindings work, see this answer to the question Basic query regarding bindtags in tkinter. It describes how a character is inserted into an entry widget, but the mechanism is identical for all events and widgets in tkinter.
I want some of my class functions to be called when a some keyboard keys are pressed, no matter which window is active. how to do that in LINUX. What I was using until now is OpenCV and waitKey() function but for that I need to show a window and have it active when pressing a keyboard key. I do have a main loop always running where the pressed key can be checked but it would be nice to have a solution where no loop is needed.
I'm talking about <<NotebookTabChanged>> event that ttk.Notebook can be bound to. Say I have:
def tabChanged(self, event):
print "tab changed"
And say I want to manually trigger this method. What I actually mean by this is, say I have a basic, tabbed GUI and there's a start button which makes plots when you click it. There are plots on each tab and when you change tabs, <<NotebookTabChanged>> is triggered, which is an automatically created event by ttk.Notebook. I already have a self.tabChanged method for this case. What I wanna do is, I wanna make my start button trigger this event so I don't have to create a new method just for the button which will do the exact same thing as self.tabChanged. So I need a way of triggering the event through a button click, but remember, that event is ttk.Notebook's own event and apparently it was designed to be used with tabs, not buttons. Is there a way to trigger <<NotebookTabChanged>> manually with a button click?
You can generate virtual events (eg: events that begin and end with << and >>) with event_generate:
self.the_notebook.event_generate("<<NotebookTabChanged>>")
In the app I'm building, I've implemented a global undo/redo system that's accessible via the normal shortcut keys Ctrl-Z and Ctrl-Shift-Z.
I'm also using QLineEdit fields which have an undo/redo function of their own. Whenever an editingFinished event is triggered (enter is pressed or focus is lost) a global undo event is created. However, if you just type a few letters and then hit Ctrl-Z the field captures the keypress, uses its own undo system to undo your last edit and then does not pass the keypress on.
What I'd like to implement is this:
When the QLineEdit has focus and Ctrl-Z is pressed but there are no edits in the QLineEdit to be undone (when undoAvailable() is False) I'd like the widget to ignore the keypress and pass it on to its parents.
When undo is available and the user calls the global undo/redo actions while the widget has focus (IE pressed the button on the toolbar), I'd like them to be passed on to this widget.
Any ideas?