| Name | wxcompose JSON |
| Version |
1.1.0
JSON |
| download |
| home_page | None |
| Summary | Declarative UI style and view model binding for wxPython |
| upload_time | 2025-09-14 14:47:16 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.9 |
| license | None |
| keywords |
binding
wxpython
mvvm
view model
wx
compose
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# wxcompose
[](https://github.com/eumis/wxcompose/actions/workflows/ci.yml)
Declarative UI style and view model binding for wxPython
## Installation
```bash
pip install wxcompose
```
## Usage
See [demo](demo)
### Using components
Here is comparison between wxpython and wxcompose
```python
import wx
app = wx.App()
frame = wx.Frame(None, title="Test", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN)
sizer = wx.BoxSizer(wx.VERTICAL)
txt = wx.StaticText(frame)
txt.SetLabel("Some text")
sizer.Add(txt, flag=wx.EXPAND | wx.ALL)
frame.Show()
app.MainLoop()
```
```python
import wx
from wxcompose import core as wxc
from wxcompose.component import sizer_add
with wxc.App() as app:
with wxc.Frame(title="Test", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN) as frame:
with wxc.BoxSizer(orient=wx.VERTICAL):
with wxc.StaticText() as _:
_.Label = "Some text"
sizer_add(flag=wx.EXPAND | wx.ALL)
frame.Show()
app.MainLoop()
```
---
`wxcompose.core` contains components for core wxpython controls, such as `wx.Frame`, `wx.BoxSizer`, `wx.StaticText`, etc.
Examples of using generic component for controls
```python
import wx
from wx.lib.agw import pygauge
from wxcompose import core as wxc
from wxcompose.component import Component, cmp, parent
with wxc.Frame(title="Test", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN) as frame:
with Component(pygauge.PyGauge(frame)) as gauge:
pass
with Component(pygauge.PyGauge(parent())):
pass
with cmp(pygauge.PyGauge(parent())):
pass
with cmp(pygauge.PyGauge):
pass
```
### Binding
`bind()` can be used to bind control property to view model
```python
from wxcompose import core as wxc
from wxcompose.binding import bind, to
from wxcompose.viewmodel import ViewModel
class TestViewModel(ViewModel):
def __init__(self):
super().__init__()
self.name = "label"
self.label = "label"
view_model = TestViewModel()
with wxc.StaticText() as _:
bind(_).Label = to(lambda: f"{view_model.name}: {view_model.label}")
```
---
if control property should be updated only when some specific view model field is changed, 'when' expression can be passed as second argument
```python
from wxcompose import core as wxc
from wxcompose.binding import bind, to
from wxcompose.viewmodel import ViewModel
class TestViewModel(ViewModel):
def __init__(self):
super().__init__()
self.name = "label"
self.label = "label"
view_model = TestViewModel()
with wxc.StaticText() as _:
bind(_).Label = to(lambda: f"{view_model.name}: {view_model.label}", lambda: (view_model.name, view_model.label))
```
---
method call can be bind to view model changes. True can be passed as third argument to call passed method initially
```python
from wxcompose import core as wxc
from wxcompose.binding import bind, to
from wxcompose.viewmodel import ViewModel
class TestViewModel(ViewModel):
def __init__(self):
super().__init__()
self.ui_updated = self.custom_event("ui_updated")
view_model = TestViewModel()
with wxc.BoxSizer() as _:
bind(_).call(lambda _: _.Layout(), lambda: view_model.ui_updated, True)
```
---
two way binding
```python
import wx
from wxcompose import core as wxc
from wxcompose.binding import sync, to
from wxcompose.viewmodel import ViewModel
class TestViewModel(ViewModel):
def __init__(self):
super().__init__()
self.value = 0
view_model = TestViewModel()
with wxc.TextCtrl() as _:
sync(_, wx.EVT_TEXT, lambda v: int(v)).Value = to(view_model).value.map_(lambda v: str(v))
```
## License
[MIT](LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "wxcompose",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "binding, wxpython, mvvm, view model, wx, compose",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/1b/80/10b13eb0abbe0ac4e1b5ce3396e0a21cc7e3718cc94d0b47d32bda2c1bc7/wxcompose-1.1.0.tar.gz",
"platform": null,
"description": "# wxcompose\n\n[](https://github.com/eumis/wxcompose/actions/workflows/ci.yml)\n\nDeclarative UI style and view model binding for wxPython\n\n## Installation\n\n```bash\npip install wxcompose\n```\n\n## Usage\n\nSee [demo](demo)\n\n### Using components\n\nHere is comparison between wxpython and wxcompose\n\n```python\nimport wx\n\napp = wx.App()\nframe = wx.Frame(None, title=\"Test\", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN)\nsizer = wx.BoxSizer(wx.VERTICAL)\ntxt = wx.StaticText(frame)\ntxt.SetLabel(\"Some text\")\nsizer.Add(txt, flag=wx.EXPAND | wx.ALL)\n\nframe.Show()\napp.MainLoop()\n```\n\n```python\nimport wx\n\nfrom wxcompose import core as wxc\nfrom wxcompose.component import sizer_add\n\nwith wxc.App() as app:\n with wxc.Frame(title=\"Test\", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN) as frame:\n with wxc.BoxSizer(orient=wx.VERTICAL):\n with wxc.StaticText() as _:\n _.Label = \"Some text\"\n sizer_add(flag=wx.EXPAND | wx.ALL)\n frame.Show()\n app.MainLoop()\n```\n\n---\n\n`wxcompose.core` contains components for core wxpython controls, such as `wx.Frame`, `wx.BoxSizer`, `wx.StaticText`, etc.\nExamples of using generic component for controls\n\n```python\nimport wx\nfrom wx.lib.agw import pygauge\n\nfrom wxcompose import core as wxc\nfrom wxcompose.component import Component, cmp, parent\n\nwith wxc.Frame(title=\"Test\", style=wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN) as frame:\n with Component(pygauge.PyGauge(frame)) as gauge:\n pass\n\n with Component(pygauge.PyGauge(parent())):\n pass\n\n with cmp(pygauge.PyGauge(parent())):\n pass\n\n with cmp(pygauge.PyGauge):\n pass\n```\n\n### Binding\n\n`bind()` can be used to bind control property to view model\n\n```python\nfrom wxcompose import core as wxc\nfrom wxcompose.binding import bind, to\nfrom wxcompose.viewmodel import ViewModel\n\n\nclass TestViewModel(ViewModel):\n def __init__(self):\n super().__init__()\n self.name = \"label\"\n self.label = \"label\"\n\n\nview_model = TestViewModel()\n\nwith wxc.StaticText() as _:\n bind(_).Label = to(lambda: f\"{view_model.name}: {view_model.label}\")\n```\n\n---\n\nif control property should be updated only when some specific view model field is changed, 'when' expression can be passed as second argument\n\n```python\nfrom wxcompose import core as wxc\nfrom wxcompose.binding import bind, to\nfrom wxcompose.viewmodel import ViewModel\n\n\nclass TestViewModel(ViewModel):\n def __init__(self):\n super().__init__()\n self.name = \"label\"\n self.label = \"label\"\n\n\nview_model = TestViewModel()\n\nwith wxc.StaticText() as _:\n bind(_).Label = to(lambda: f\"{view_model.name}: {view_model.label}\", lambda: (view_model.name, view_model.label))\n```\n\n---\n\nmethod call can be bind to view model changes. True can be passed as third argument to call passed method initially\n\n```python\nfrom wxcompose import core as wxc\nfrom wxcompose.binding import bind, to\nfrom wxcompose.viewmodel import ViewModel\n\n\nclass TestViewModel(ViewModel):\n def __init__(self):\n super().__init__()\n self.ui_updated = self.custom_event(\"ui_updated\")\n\n\nview_model = TestViewModel()\n\nwith wxc.BoxSizer() as _:\n bind(_).call(lambda _: _.Layout(), lambda: view_model.ui_updated, True)\n```\n\n---\n\ntwo way binding\n\n```python\nimport wx\n\nfrom wxcompose import core as wxc\nfrom wxcompose.binding import sync, to\nfrom wxcompose.viewmodel import ViewModel\n\n\nclass TestViewModel(ViewModel):\n def __init__(self):\n super().__init__()\n self.value = 0\n\n\nview_model = TestViewModel()\n\nwith wxc.TextCtrl() as _:\n sync(_, wx.EVT_TEXT, lambda v: int(v)).Value = to(view_model).value.map_(lambda v: str(v))\n```\n\n## License\n\n[MIT](LICENSE)\n",
"bugtrack_url": null,
"license": null,
"summary": "Declarative UI style and view model binding for wxPython",
"version": "1.1.0",
"project_urls": {
"Homepage": "https://github.com/eumis/wxcompose"
},
"split_keywords": [
"binding",
" wxpython",
" mvvm",
" view model",
" wx",
" compose"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "78863cfdea47a5c1995a651ad19d61b078fae4df5ffa9236f8cd0205a30b8cd5",
"md5": "333bb2a41db9671e7a98517eade6a235",
"sha256": "c82cd7efb9be592dedaf3a5e9205555799bc34d983a8964066a0d91eddf7bf3a"
},
"downloads": -1,
"filename": "wxcompose-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "333bb2a41db9671e7a98517eade6a235",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 12373,
"upload_time": "2025-09-14T14:47:15",
"upload_time_iso_8601": "2025-09-14T14:47:15.064866Z",
"url": "https://files.pythonhosted.org/packages/78/86/3cfdea47a5c1995a651ad19d61b078fae4df5ffa9236f8cd0205a30b8cd5/wxcompose-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1b8010b13eb0abbe0ac4e1b5ce3396e0a21cc7e3718cc94d0b47d32bda2c1bc7",
"md5": "e1ed286da7f81f3326bae4478fe55bbe",
"sha256": "4844f398d37baccea841459adf1903b5de5536e43050404a6db8dd4abbc590a5"
},
"downloads": -1,
"filename": "wxcompose-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "e1ed286da7f81f3326bae4478fe55bbe",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 12992,
"upload_time": "2025-09-14T14:47:16",
"upload_time_iso_8601": "2025-09-14T14:47:16.303533Z",
"url": "https://files.pythonhosted.org/packages/1b/80/10b13eb0abbe0ac4e1b5ce3396e0a21cc7e3718cc94d0b47d32bda2c1bc7/wxcompose-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-14 14:47:16",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "eumis",
"github_project": "wxcompose",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "wxcompose"
}