wxPython: switching text control focus on tab press - python

I made a frame that asks the user to put in a bunch of information in several text control fields. How can I make it so that when you hit the 'tab' key your cursor moves to the next text control?

If you put a wx.Panel as the only child of the ScrolledWindow and put the other widgets on the panel, then it should work automatically. You could also use ScrolledPanel instead.

Related

How can I create a read-only text widget with TkInter and still be able to modify the widget's content programmatically?

I want to use Tk's text widget to display part of the state of my program. (A label widget will not do, because the tag feature of the text widget will save a lot of work. A canvas widget will not do, because I don't want to have to lay out a lot of text manually.)
I do not want the user to be able to directly modify the contents of the text widget. They can change the state of the program by interacting with it in other ways, but the text widget is for display only.
If I set the state of the text widget to disabled, then not only is the user unable to interact with it, but I also cannot modify its contents programmatically (specifically, I cannot insert text).
The obvious workaround is decorate any code that updates the contents of the text widget with code the enables and disables the widget. But this is kludgy: I should be able to modify the contents without offering the user an opportunity to interfere, however brief that opportunity may be.
Is there a way to do this?
The "kludgy workaround" isn't kludgy at all -- that's exactly how you do it, and how it was designed to work.
However, there is another solution. You can remove all of the built-in key and mouse bindings from the widget, and then re-implement only the ones you care about (for example, you might want the user to highlight and copy a block of text). This is simple and effective, but if you want to restore some of the bindings it starts to become very tedious to re-implement the bindings you care about (cut, copy, paste, page up, page down, moving the cursor, etc).
To remove all of the default bindings you can remove the class bind tag like this:
t.bindtags((t, root, "all"))
For more information about bind tags, see these answers:
https://stackoverflow.com/a/11542200/7432
https://stackoverflow.com/a/3513906/7432
https://stackoverflow.com/a/11459001/7432
you could constantly delete then insert the text like so:
import tkinter
root = tkinter.Tk()
text = tkinter.Text(root, width=40)
text.grid(row=0, column=0, stciky=tkinter.W)
while True:
text.delete(0.0, tkinter.END)
text.insert(tkinter.END, your_text)
where your_text is the text you want to insert

Detect whether or not cursor is in Text widget

I am writing a text editor in Python 3 with tkinter, and I'm trying to add an undo function, but in order to log the user's edits I need to log the edit when they type a letter. However, I don't want to log the typed letter if they have clicked out of the text widget. My question is this:
Can I detect whether or not the Text widget's cursor is in the widget? Is there an attribute on the text widget, or a bind I can put on the master window to detect if the cursor is in the text widget?
If your bindings are on the text widget, and if the focus is not on the text widget, your text widget will never see the keypress. Focus management is built in to Tkinter, so you shouldn't have to do anything.
To answer your specific question, you can use the method focus_get to retrieve the widget that currently has keyboard focus. You can also bind to <FocusIn> and <FocusOut> to be notified when the widget gains or loses focus.
Also, are you aware that the text widget has a built-in undo facility? The New Mexico Tech website has a nice brief overview: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/text-undo-stack.html

How to keep a wxpython frame always on screen?

I made a music player, Once the main frame is iconized another frame appears and once that frame is iconized a smaller frame appears. Is there a way to get the last, small frame, to always be on the screen? now if I click outside of the frame it disappears until I click on it in the taskbar. I want it to always be on screen until the user clicks a button to open up the frame before the final, small frame.
To make the dialog stay in the foreground until the user interacts with it use the ShowModal() method:
There are two types of dialogs. Modal and modeless. Modal dialog does
not allow a user to work with the rest of the application until it is
destroyed. Modal dialogs are created with the ShowModal() method.
Dialogs are modeless when called with Show().
http://wiki.wxpython.org/AnotherTutorial/
If you just want the window to stay in the foreground, you can use the setFocus() method on the dialog because it is a child of the Window class:
SetFocus(self)
Set's the focus to this window, allowing it to receive keyboard input.
http://wxpython.org/docs/api/wx.Window-class.html#SetFocus

Selecting Widgets

In Tkinter I'm trying to make it so when a command is run a widget is automatically selected, so that a one may bind events to the newly selected widget.
Basically I want it so when I press a button a text widget appears. When it appears normally one would have to click the text widget to facilitate the running of events bound to the text widget. I want that behavior to automatically happen when the user clicks the button. So that one does not have to click the button and then the text widget, but simply the button.
I'd also like it so if one started typing after the button was pressed it would automatically start filling the text widget. Again to cut out having to click on the text widget.
What bit of code does the above?
The terminology which describes what you want is "focus" -- you want to set the keyboard focus to your text widget. To do that you need to use the focus_set() and/or focus_force() methods on the text widget.

How do I prevent Qt buttons from appearing in a separate frame?

I'm working on a PyQt application. Currently, there's a status panel (defined as a QWidget) which contains a QHBoxLayout. This layout is frequently updated with QPushButtons created by another portion of the application.
Whenever the buttons which appear need to change (which is rather frequently) an update effect gets called. The existing buttons are deleted from the layout (by calling layout.removeWidget(button) and then button.setParent(None)) and the new buttons are added to the layout.
Generally, this works. But occasionally, when I call button.setParent(None) on the button to delete, it causes it to pop out of the application and start floating in its own stand-alone frame.
How can I remove a button from the layout and ensure it doesn't start floating?
You should call the button's close() method. If you want it to be deleted when you close it, you can set the Qt.WA_DeleteOnClose attribute:
button.setAttribute(Qt.WA_DeleteOnClose)
Try calling QWidget::hide() on the button before removing from the layout if you don't want to delete your button.

Categories

Resources