magicgui
magicgui copied to clipboard
feat: support textual [WIP]
WIP support for textual (#534 ... cc @davidbrochart). Proof of principle working for a few widgets, now need to flesh it out with all of the other widgets... and think a bit more about how the global layout/styling of the app will work
from magicgui import use_app, widgets
app = use_app("textual")
l1 = widgets.Label(value="I'm a label")
l2 = widgets.LineEdit(value="I'm a line edit")
btn = widgets.PushButton(text="I'm a button")
chx = widgets.CheckBox(text="I'm a checkbox")
@l2.changed.connect
def _on_click(newval) -> None:
print("line edit changed", newval)
@btn.clicked.connect
def _on_click() -> None:
print("Button clicked!")
@chx.changed.connect
def _on_click(newval) -> None:
print("Checkbox changed", newval)
btn.enabled = not newval
app.run()

(need to run with TEXTUAL=devtools in order to actually see the output of the callbacks)
Thanks so much for starting this @tlambert03, that looks very promising!
Now I'm thinking about using the pyapp-kit stack for jpterm. Currently the plugin system is based on asphalt, but it may be overkill and I have the feeling that I could just use in-n-out to require resources. The only missing piece that I can see is configuration. I need to be able to pass configuration on the CLI or through files to plugins. But maybe this is something I could implement separately.
Codecov Report
Attention: 151 lines in your changes are missing coverage. Please review.
Comparison is base (
3e10552) 87.69% compared to head (40c89ab) 84.98%.
Additional details and impacted files
@@ Coverage Diff @@
## main #537 +/- ##
==========================================
- Coverage 87.69% 84.98% -2.72%
==========================================
Files 40 43 +3
Lines 4723 4874 +151
==========================================
Hits 4142 4142
- Misses 581 732 +151
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
I've just been looking for a fallback option for magicgui when no graphics are available (e.g. ssh connection to a remote machine), and this PR looks promising 🙂
We're currently using questionary for some simple user input to generate config files, but I'd love to be able to implement a dataclass/guiclass/Pydantic model for the config and use magicgui as a simple user interface.
What's the status of this implementation? Can I help somehow? What's missing? (Also, I assume that textual has had some improvements since this PR was first drafted.)
hey @imagejan, thanks for commenting. I'll need to have another look, but I think much of the bones were in place here, and the primary thing missing was to go through the textual API and see what widgets were available that could be used to back one of the magicgui widgets. And yes, I suspect more widgets have been added to textual in the meantime (at the time, it was a bit minimal). That bit is all pretty straightforward.
The other major decision is mostly how we want to shoehorn the textual app into the context of a magicgui app. You'll note, for example, that I'm currently just creating a global textual app, and basically just appending every widget that gets created to that app. I'm not entirely sure that's the best pattern. It might be fine to begin with, as long as we can change it later without breaking any public-facing API that we expose.
In any case, I'd love some help! (just knowing that someone out there is interested in using it helps... I have so many things going on that it helps to focus on things I know people will use). That help could take many forms: you could
- checkout this PR and play with the example above, trying individual widgets to see how they're doing
- go through the textual API to see if there are any new widgets that I haven't implemented yet in
src/magicgui/backends/_textual/application.py - read up a bit more on the textual App class and help decide if we're adapting it well here.
This pull request has been mentioned on Image.sc Forum. There might be relevant details there:
https://forum.image.sc/t/using-magicgui-to-create-pydantic-class-instances/92520/1