Changed
- A
Signalseeded with nothing is now reported instead of built dead. A signal takes its type from the value you create it with, sobs.Signal(None)inferred the type ofNoneitself and could never hold anything else: every laterset()raisedExpected NoneType, got str, at an arbitrary write, with a message naming neither the mistake nor the fix. It now raises where the mistake was made. This reachesmap()too, which types the derived signal from the transform's first result: a transform that returnsNonefor the value it is first called with now raises there, instead of building the same dead signal and failing somewhere else later. Check this when you upgrade if you seed a signal from data that can be missing, ormap()a transform that can returnNone. Passallow_empty=Truewith the type named, as inbs.Signal(None, allow_empty=True, dtype=date), when the value can be empty; give the transform a value for every input, as indue.map(lambda d: d.strftime("%b %d") if d else ""), when it cannot. Signals seeded with a value, andmap()over a transform that returns one, are unaffected. (#481)
Fixed
TextArea.insert()andappend()no longer write alongside the placeholder. On aTextAreabuilt withplaceholder=and still showing it — a log or output pane you also write to from code is the ordinary case — text written through either method was added to the placeholder instead of replacing it: the screen readType something herewritten by code,valuewent on returning'', andon_inputandon_changestopped firing. The silence was permanent rather than momentary, so every later edit the user made went unannounced too andvaluestayed empty for the rest of the field's life. Both methods now drop the placeholder first, as assigning tovaluealways did. ATextAreawith no placeholder, or one whose placeholder is already gone, is unaffected, and so isCodeEditor, which has no placeholder to write onto. (#491)- A field's
valuenow follows a write to its boundSignal. Writing to a signal bound to aTextField,PasswordField,PathFieldorSpinnerFieldmoved what the field displayed but not whatvaluereported — the two disagreed about the same state, silently, until the user focused and left the field.valuenow follows a write your code made, includingclear()on a signal declaredallow_empty=True, while still reporting the last committed value while the user is typing, which is unchanged. A programmatic write made while that field currently has keyboard focus is indistinguishable from typing and still waits for the commit.TextArea,CodeEditor,NumberField,DateField,TimeFieldandSelectalready behaved this way and are untouched. Check this when you upgrade if you handleon_changeon a field your code writes through a bound signal. The change event that used to arrive a focus cycle late now moves withvalue: it no longer fires when the user changes nothing, and it now fires when the user types the field back to the text it held before your write. Writing a field throughfield.value, which is howForm.set()writes, is unaffected, and so is every change the user makes. (#482) TextAreaandCodeEditornow honor aSignal.clear(). Clearing a signal bound to either widget left the old text on screen, so the signal read empty and the widget did not; the other seven field widgets that take a signal all honored it. Whether it worked depended on something unrelated to the widget — the same clear was honored or ignored according to what else in your application happened to be bound to that signal. Since0.4.0wired these two in both directions, the next edit to a widget left stale this way also pushed its old text back and silently un-emptied the signal. Clearing the widget itself, withwidget.clear(), was always correct and is unchanged. (#490)- A
Signala text field made for you can now be cleared.TextField,PasswordField,PathFieldandSpinnerFieldhand you aSignalthrough.signalwhether or not you bound one, and clearing that signal raisedExpected str, got NoneType, telling you to passallow_empty=Trueto aSignal()call you never wrote — advice no edit of yours could follow. Those four now allow empty, sofield.signal.clear()empties the field and the signal reads'', the empty of a value that lives in the widget's own variable. A signal you built yourself is unchanged, and so isfield.clear(), which always worked.SliderandCheckboxstill refuse, and still should: a slider always has a position and a checkbox always has a state, so neither has an empty value its variable could hold. The refusal now names setting a value as the way out, rather than only a constructor you may not own. (#484)
What's Changed
- fix(core): signal no longer guards None when applying text value to field by @israel-dryer in #502
- fix(fields): a field's value follows a programmatic signal write (#482) by @israel-dryer in #503
- fix(signal): a signal seeded with None, no dtype and without allowing… by @israel-dryer in #504
- fix(textarea): drop the placeholder before insert() and append() write by @israel-dryer in #505
- Fix/widget owned signal clear 484 by @israel-dryer in #506
Full Changelog: v0.4.0...v0.4.1