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?
Related
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'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>>")
I'm writing a Python GTK app that uses a gtk.Entry widget to forward keypresses to multiple other widgets. Unfortunately, it seems like GTK has a default binding that switches widget focus on the up and down arrow keys out of the Entry widget.
I want to disconnect this key-based focus switching, but leave mouse based focus switching in place. I can't seem to find where in the API I'd do this.
Any suggestions?
Return True from a handler for the key-press-event signal to prevent the default handling: http://www.pygtk.org/docs/pygtk/class-gtkwidget.html#signal-gtkwidget--key-press-event
I use Qt4 Designer and I want that when I click on the "yes" button, some code will execute. And when I click on the "no", some other code will be execute. How can I do it?
Click on the Edit Signal/Slots tool.
Create a connection for your button. For this, select your button in the designer by pressing on it with the left button of the mouse. Move the mouse to some place in the main window to create a connection with the main window (it is like a red line with a earth connection).
When you release the mouse button, the Configure Connection dialog appears.
In this dialog select a signal in the left text control (the sender), for example, pressed().
Then press edit in the right text control (the receiver). A dialog for the Signals/Slots of MainWindow appears.
In the slot panel add a new slot (green cross). The text slot1() appears. Double click on it to edit the line and write instead the name of your function doit_when_yes_ispressed(). Accept.
Now in the Configure Connection dialog you will see your function in the right text control. Select and Accept.
In the designer now you can see the signal and your function in the widget.
Right-click on your widget
Select "Go to slot..."
Select a signal and click OK
Your custom slot declaration and definition for that signal will be added to *.cpp and *.h files. Its name will be generated automatically.
upd:
Sorry, I didn't notice that the question is about Python & QtDesigner itself, I was thinking of the designer mode in QtCreator IDE. However, this still may be useful for someone who is looking for Qt/C++ info, so I leave the answer.
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