Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
GUI toolkit for creating beautiful applications for mobile, web, and desktop from a single python3 codebase
This is a (basic) UI toolkit for htag apps. Contrario to htbulma, this one is a minimal toolkit, providing only useful and solid widgets, and will be maintained (you can use it ;-)).
roadmap
INSTALL
python3 -m pip install -U htagui
note: it will install htag and htagui, and provide the ui
in the htag namespace (htag.ui
)
A hello world could be :
from htag import Tag, Runner, ui
class MyApp(ui.App):
def init(self):
self <= ui.Button("test", _onclick=lambda ev: self.ui.alert( "hello world" ) )
if __name__ == "__main__":
Runner(MyApp).run()
It provides some (ready-to-use) Htag Objects, and some utilities methods.
This is a surcharge of Tag.body( ... ) which auto provide an ui
property on the instance, to interact with Dialog
features
In place of:
class MyApp(Tag.body):
def init(self):
self.ui = ui.Dialog(self) # <- it will do that, automatically
self <= ui.Button("test", _onclick=lambda ev: self.ui.alert( "hello" ) )
you can do :
class MyApp(ui.App):
def init(self):
self <= ui.Button("test", _onclick=lambda ev: self.ui.alert( "hello" ) )
A simple surcharge of Tag.button(...), to define a css class
import htagui as ui
self <= ui.Button("my button",_class="myclass", _onclick = myevent )
A simple surcharge of Tag.input(...), to define a css class
import htagui as ui
self <= ui.Input(_value="my value", _name="myfield", _class="myclass", _required=True )
Availables managed type
s (setted with _type
) params:
text
: the default one (if omitted): an input textcheckbox
: a checkboxradio
: a radio button (non sense : use ui.Radios or uiIRadios !)range
: a slider/rangeFor text
: a special field "_label" will set the html "placeholder" attribut.
A simple surcharge of Tag.textarea(...), to define a css class
import htagui as ui
self <= ui.Textarea("my value", _name="myfield", _class="myclass", _required=True )
A special field "_label" will set the html "placeholder" attribut.
A spinner object.
import htagui as ui
self <= ui.Spinner()
Theses are interactive/reactive fields, which are automatically synced between client and server side, thru a 'value' property
An htag class to help to create "select/option" html tags, using a dict of {value:title, ...}.
import htagui as ui
self <= ui.Select( dict(a="A",b="B"), _value="a", _name="myfield" )
An htag class to help to create "radio button choices" html tags, using a dict of {value:title, ...}.
import htagui as ui
self <= ui.Radios( dict(a="A",b="B"), _value="a", _name="myfield" )
An htag class to help to create a (first-level) menu and menu items, using a dict of {title:callback,...}
import htagui as ui
ux = ui.Dialog(self)
entries={
"menu1": lambda: ux.notify("menu1"),
"menu2": lambda: ux.notify("menu2"),
"menu3": lambda: ux.notify("menu3"),
}
self <= ui.Menu( entries )
A simple surcharge of Tag.form(...) where you can define a callback to call a method wich will receive a python "dict" of all named inputs defined in the form.
import htagui as ui
ux = ui.Dialog( self )
form = ui.Form( onsubmit=lambda dico: ux.notify(str(dico)) )
form <= ui.Input(_name="mystring",_placeholder="input something")
form <= ui.Button("ok")
self <= form
A simple surcharge of Tag.input( _type='file'...) which call a method to upload the selected file.
import htagui as ui
def uploaded(name:str, content:bytes):
print(name,content)
self <= ui.FileUpload( uploaded , _multiple=True)
An htag class to easily create tabs structure. And provides somes attributs/methods to interact with it.
import htagui as ui
tab1 = Tag.div("content1",name="tab1") # tab object needs a `name` property !
tab2 = Tag.div("content2",name="tab2")
t = ui.Tabs( tab1, tab2 )
self += t
A method to add dynamically a tab instance, which is automatically selected.
(note that the tab object needs a name
property !)
Dynamic property to retrieve or select the current selected tab.
Event which is called when selected index changes.
Expose "Dialog boxes" with methods on the instance. Note that, there can be only one dialog at a time (except toast notification)
import htagui as ui
dialog = ui.Dialog( self )
(like js window.alert(...)) Display a modal dialog box containing the object 'obj' (obj must be str'able)
size is a float to force the percent of width on the dialog box. If None, it will use the default from the ui used.
(like js window.confirm(...)) Display a modal dialog box containing the object 'obj' (obj must be str'able), and let the user click on Yes|No buttons, which will call the cbresponse callback with True or False ...
(like js window.prompt(...)) Display a modal dialog letting the user edit the value
in an Input box, with a title
(title must be str'able). When the user click the OK button the value is sent in the callback cbresponse. (clicking the cancel button does nothing, except close the dialog)
Display a toast message (notification), in the right-bottom ... during 2000 ms. (currently toast messages are not stacked)
Display an object, at coords (x,y).
ex "create a popmenu", using "Menu object"
import htagui as ui
dialog = ui.Dialog(self)
entries={
"menu1": lambda: dialog.notify("menu1"),
"menu2": lambda: dialog.notify("menu2"),
"menu3": lambda: dialog.notify("menu3"),
}
self <= ui.Button("pop menu", _onclick=lambda ev: dialog.pop( ui.Menu(entries) ,(ev.clientX,ev.clientY)) )
note: it ensures that the object is fully visible in the inner window.
Display a drawer, in the left-side. mode can be left,right,top,bottom.
Display a full page 'obj', or remove page if obj is None. (note that ui.close() does not close the page)
Display a modal dialog box containing the object 'obj'. But the dialog is not closable, so be sure to provide a way to close it.
Close programatically, the current ui dialog.
Copy the txt in the clipboard
Call the callback with the text content from the clipboard. (user may need to authorize the interaction from the navigator)
Force the navigator to download a file named 'name', with the content bytes 'content' into the browser.
A Tag object to use "SplitJS"
import htagui as ui
split = ui.HSplit( Tag.div(1), Tag.div(2), sizes=[60,40], minSize=100, _style="border:2px solid red;height:100px" )
self <= split
methods: split.setSizes( [50,50] ) split.onchange = lambda object: print( object.sizes ) # event
A component to let the user reorder items using drag'n'drop.
ll=[Tag.div(f"Item {i} (drag me)",value=i) for i in range(10)]
def onchange(o:ui.Sortable):
print( str([i.value for i in o.values]) )
self <= ui.Sortable(ll,onchange=onchange)
A component to help you to create an infinite scroller.
def feed():
yield [Tag.div(i) for i in range(20) ]
self <= Tag.div(_style="height:200px; border:1px solid red;" ) <= ui.VScroll( feed )
This component should be embbeded in an element which have a constraint on its height. The given callback should yield Tag(s) (or None
to finnish the endless scroll)
A component (which inherit from VScroll) to present a finnished list of items in an "on-demand" way (create items on-demand), can contain a big amount of data.
ll=[lambda i=i: MyObject(i) for i in range(1,200_000_000)]
self <= Tag.div(_style="height:200px; border:1px solid red;" ) <= ui.VScrollPager(ll,preload=50,moreload=10,endzone=50)
This component should be embbeded in an element which have a constraint on its height. preload
is the number of items which will be created (it should overflow on height). moreload
is the number of items which will be loaded when scrolling is in the endzone
pixels at the end.
Note that the list is a list of lambda (List[Callable[[], Tag]]
) to create the rendering on-demand.
A view component which handle the browser navigation mechanism (go back)
IMPORTANT:
TODO: make a better good example !
default_view=Tag.div("Default view")
v = ui.View( default_view, _style="border:1px solid red;width:100%;height:400px" )
self <= ui.Button("p1", _onclick = lambda ev: v.go( Tag.div("p1") ))
self <= ui.Button("p2", _onclick = lambda ev: v.go( Tag.div("p2") ))
self <= v
signature : Grid(format,vformat="auto",gap="1px",**a)
A simple grid container
example:
g = Grid("1fr 1fr 2fr")
g <= Tag.div( "2colums",_style="grid-column:1 / 3")
g <= Tag.div( "1column")
Methods to create an HBox or VBox htag class (flexbox horizontal or vertical, with nowrap mode)
import htagui as ui
HBox = ui.hflex(50, 50) # create a hbox of 2 elements of 50% each
self <= HBox( Tag.div(1), Tag.div(2) )
FAQs
GUI toolkit for creating beautiful applications for mobile, web, and desktop from a single python3 codebase
We found that htagui demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.