Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
simplest possible textview example?
-
Using the gui builder I created a view with a single textView object. When I load it it complains that there is a class not defined. I can't find in the documentation why a textView needs a custom class and what I should put in it. Why does a textView need a class but a simple button does not? Where in the documentation does it describe what class I should be creating for a textView? Is there a simple example of using a textView to enter text that I can start from?
PS. Thanks for the new ui class. I can see that when I figure it out it will massively expand what apps I can write with Pythionista.
-
Did you enter anything in the "custom class" for the text view in the UI editor? If you leave it blank it will just use a standard TextView.
The main purpose of setting a custom subclass is to be able to extend the TextView's functionatity in various ways; there is no such option for buttons because they are a very simple UI element that can't be extended very well.
-
Setting a custom class for a
TextView
should actually not be possible (TextView
cannot be subclassed), but perhaps you accidentally set a class name for the root view? You can check this by selecting nothing in the UI editor (tap on the background), and then tapping the (i) button to bring up the inspector. The "Custom View Class" field should be empty (it shows "View" as a gray placeholder in this case). -
Thanks. I had given the root view a name. I'd still like to see an example so I know how to assign and use a delegate. It looks like there is a default name for a button action. Is there a similar default name for a delegate class or instance? Are these defaults documented?
-
The
ui
module documentation can be found in the Pythonista Modules section of the docs tab, along with all other custom iOS modules and a few third-party ones.Action functions and delegates are two separate things. An action function is a regular function with a single parameter named
sender
. Every element can only have a single action, if any, which is called when the element's main action is used, e. g. a button is pressed. Thesender
parameter will be the element that triggered the action, so it is possible to reuse the same action function for multiple elements.Delegates are classes rather than functions. (If you're familiar with other event-based toolkits, they are somewhat similar to listeners.) They are used to handle objects with multiple actions, or secondary/less important object actions. When one of these secondary actions occurs, the corresponding method of the element's delegate is called. For example, a TextView delegate can have the
textview_did_begin_editing
method, which is called when the user taps the TextView to edit the text. That method only has atextview
parameter (similar to thesender
of action functions). More complicated functions can have additional parameters, for example which row of a TableView was selected.Both action functions and delegate objects are not specific to one type of element. The action's
sender
can be of any type, so you can use one action function for all elements (the use of that is questionable though). More importantly, delegate methods are prefixed with the source element type, so there are no naming conflicts between e. g.textfield_did_begin_editing
andtextview_did_begin_editing
. Personally I find it useful to have one class as a delegate for all elements. -
Believe it or not I have read the builtin documentation extensively. I only post questions when the doc isn't helping, probably because I have developed blind spots and am missing the importance of key issues. As a result I am aware of almost everything that @dgelessus quotes from the doc but I still don't know how to connect a textView to the delegate class described in detail in the documentation. I think the problem may be that I am not a web programmer. I have written osx, windows and ios (Tcl/Tk perl/Tk etc. etc. etc) apps and programs (not to mention about a gazillion gui-less embedded control apps) but I am not much aware of web specific paradigms and toolkits. Should I be reading some external webkit doc before I attempt to use the Pythionista ui class?
I have been using the wonderful Pythonista for over a year and have had little difficulty (I never needed to join this forum before) until trying the ui class. I must be stupid but I haven't been able to go from the documentation to creating a simple view with a single textView, something that I thought would be simple and require fewer than 10 lines of code. That is why I have have repeatedly asked for a simple example. I am obviously missing basic things that are implied in the doc; things that seem to be obvious to everyone else.
Maybe I should stop using the gui builder. If I built everything directly in code I would be forced to learn how everything is connected. That is probably what I am missing. There seems to be a lot of implied behavior in what the gui builder builds that I am missing. Is the gui builder output a readable file in an obvious format? Is it in Python maybe? Maybe I should be reading that if I can figure out how to get it into a text editor.
-
I still don't know how to connect a textView to the delegate class described in detail in the documentation.
You basically just have to create an instance of your delegate class and then assign that to the
delegate
attribute of your text view. Here's an example without using the UI editor:import ui class MyDelegate (object): def textview_did_change(self, textview): print 'text changed' textview = ui.TextView() textview.delegate = MyDelegate() textview.present('sheet')
You cannot assign a delegate directly from the UI Editor, you have to do this programmatically.
-
Sorry, I didn't know how experienced you are with Python, so I explained everything in detail to be sure.
btw, Python has very little to do with web programming, WebKit is Apple's HTML rendering engine, and the UI toolkit is called UIKit and is accessible in Objective-C and Swift. The
ui
module in Pythonista is only a partial wrapper for UIKit, and since I haven't (successfully) used Objective-C yet I can't say how similar they are. My guess would be that the UIKit docs won't help you very much with how theui
module works, unless you're looking for specifics on certain internals. -
Thank you. That code fragment may be enough to get me there. I have almost as many questions as there are lines of code (delegates for multiple textViews?) but hopefully I'll be able to reverse engineer my way to understanding this.
Sigh... So I guess the short answer to my core question is NO. I will not find a simple working standalone example that I can download and run without change that contains a python file and a UI editor file that demonstrates how to build a view with a textView in it and responds to user actions in the textView.
This reaffirms my belief that I should not be using the UI Editor until I learn a lot more about using the UI class. The UI Editor simplifies implementation but first I need to understand more about what is being simplified.
Thanks again.
-
Is @omz's example not working? If this is what you're looking for, here's an example with empty delegate methods. They don't do anything, but you can add your own code.
import ui class MyTextViewDelegate(object): # Called when trying to focus the TextView to check whether it should get focus def textview_should_begin_editing(self, textview): return True # Called after the TextView successfully got focus def textview_did_begin_editing(self, textview): pass # Called after the TextView lost focus def textview_did_end_editing(self, textview): pass # Called when trying to edit text to check whether it should be changed # rng is a tuple containing (start, end) of thre replacement range # replacement is the new replacement text def textview_should_change(self, textview, rng, replacement): return True # Called after the TextView's text changed def textview_did_change(self, textview): pass # Called after the TextView's selection changed def textview_did_change_selection(self, textview): pass if __name__ == "__main__": global v v = ui.load_view() v["textview1"].delegate = MyTextViewDelegate() v.present("sheet")
The corresponding UI file only needs to contain a TextView named textview1 (the default name) at root level.
-
Thank you. That is exactly what I was looking for. Omz's example showed me key info delegate assignment that I lacked but it didn't call load_view() and didn't discuss the naming of the textView object and how to assign the delegate to the textView created in UI Editor. You completed that part. I kept stumbling on the relationship between what was in the UI Editor and what was in the python file and how they connected and the order to do things in. I have several examples cluttering my directory that are close to your example but each has a different minor error.
The reason I need the delegate is I am trying to filter the input so the user must enter a number and gets immediate feedback when they try to type anything else. I didn't want to wait for the enter key. I'm guessing that textview_should_change is where I need to put that. It should return False if the proposed edit doesn't make a number or an empty string? That takes care of the filter. Then I have to figure out how to do an alert popup from the event context. Now that you have given me a working example to start from I should be able to stumble through the rest.
Sorry to be such a bother. It is hard to ask the right focused question and avoid this roundaboutation.
-
On the other hand I could just use the ui.KEYBOARD_NUMBER_PAD and skip delegates. But then I would have missed all this fun. ;-)