Skip to content

Commit 3877e1a

Browse files
committed
tutorial
1 parent 38dc8f3 commit 3877e1a

5 files changed

Lines changed: 94 additions & 75 deletions

File tree

_sources/developer_tools.rst.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Developer Tools
33

44
The Edifice Runner provides some useful tools for developing Edifice applications.
55

6+
To use the Edifice Runner, you must install the :code:`watchdog` package.
7+
8+
.. code-block:: shell
9+
10+
pip install watchdog
11+
612
Dynamic hot-reload
713
------------------
814

@@ -77,8 +83,8 @@ To launch the Element Inspector, use the :code:`--inspect` flag for the Edifice
7783

7884
python -m edifice --inspect path/to/your/app.py RootElement
7985

80-
The Element Inspector, like the Inspect Elements tool of web browsers
81-
or the React inspector tool,
82-
allows you to inspect the internal state of your components.
86+
The Element Inspector allows you to inspect the running state of the application.
8387
It displays the entire Element Tree, as well as the props and state of
8488
every component.
89+
It is like the Inspect Elements tool of web browsers
90+
or the React inspector tool.

_sources/tutorial.rst.txt

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ First, install Qt and Edifice.
3535

3636

3737
Let’s create the basic skeleton of our UI.
38-
Copy this code into a new file, for example tutorial.py::
38+
Copy this code into a new file, :code:`tutorial.py`
39+
40+
.. code-block:: python
3941
4042
from edifice import App, Label, TextInput, HBoxView, Window, component
4143
@@ -50,6 +52,12 @@ Copy this code into a new file, for example tutorial.py::
5052
if __name__ == "__main__":
5153
App(MyApp()).start()
5254
55+
Run this code with
56+
57+
.. code-block:: shell
58+
59+
python tutorial.py
60+
5361
What does this code do?
5462
First we define a function :code:`MyApp` which is decorated by
5563
:func:`@component<component>`.
@@ -62,7 +70,7 @@ then declare its children, we use a
6270
`with statement <https://docs.python.org/3/reference/compound_stmts.html#with>`_
6371
context. Elements inside the :code:`with` context are children.
6472

65-
In HTML or XML, we might have written it as:
73+
In HTML or XML or React JSX, we might have written it as:
6674

6775
.. code-block:: xml
6876
@@ -81,25 +89,13 @@ It takes the description of each Element, and it decides when and how to render
8189
It does so by monitoring the **state** of each Element, and it will re-render
8290
when the Element **state** changes.
8391

84-
As you might expect, you can run this application with :code:`python tutorial.py`.
85-
However, let us take advantage of Edifice's :doc:`dynamic loading capability<developer_tools>`,
86-
so that we do not have to continually close the app and re-issue the command every time we change something.
87-
To run the app with dynamic loading, first install watchdog::
88-
89-
pip install watchdog
90-
91-
then do::
92-
93-
python -m edifice tutorial.py MyApp
94-
95-
You should see a basic form emerge. However, it's not pretty, and it doesn't really do anything.
96-
9792
We can change the formatting of the :class:`Label<Label>`, :class:`TextInput<edifice.TextInput>`, and
9893
:class:`HBoxView<edifice.HBoxView>` using Qt :doc:`styling<styling>`,
9994
which is similar to CSS styling.
10095
Here, we want to add padding between the HBoxView and Window boundary,
10196
make the Labels shorter, and add a margin between the Label and TextInput.
102-
For example::
97+
98+
.. code-block:: python
10399
104100
from edifice import App, Label, TextInput, HBoxView, Window, component
105101
@@ -119,14 +115,12 @@ For example::
119115
if __name__ == "__main__":
120116
App(MyApp()).start()
121117
122-
When we are running :code:`MyApp` with dynamic loading, Edifice will detect the change
123-
to the source file and reload :code:`MyApp` at runtime so that we can see the styling
124-
changes immediately.
125-
126118
Our application still doesn't do anything, however. Let's add an :code:`on_change`
127119
event handler **prop** for the :class:`TextInput<edifice.TextInput>`.
128120
the :code:`on_change` **prop** function will be called whenever the contents in the
129-
text input changes due to user action::
121+
text input changes due to user action.
122+
123+
.. code-block:: python
130124
131125
from edifice import App, Label, TextInput, HBoxView, Window, component, use_state
132126
@@ -146,7 +140,7 @@ text input changes due to user action::
146140
Label("Measurement in meters:", style=meters_label_style)
147141
TextInput(meters, style=input_style, on_change=meters_set)
148142
try:
149-
feet = "%.3f" % (float(meters) * METERS_TO_FEET)
143+
feet = f"{float(meters) * METERS_TO_FEET :.3f}"
150144
Label(f"Measurement in feet: {feet}", style=feet_label_style)
151145
except ValueError: # Could not convert string to float
152146
pass # So don't render the Label
@@ -168,19 +162,13 @@ the :code:`on_change` **prop** for the :class:`TextInput<edifice.TextInput>`.
168162
Whenever the user types in the text input, the state will be set and
169163
the UI will re-render.
170164

171-
Think of the component function as a map from the
165+
Think of the :func:`@component <component>` function as a map from the
172166
:code:`meters` **state** to an Element tree.
173167

174-
In the component function, we read the value of :code:`meters` and convert it to feet,
168+
In the :func:`@component <component>` function, we read the value of :code:`meters`
169+
and convert it to feet,
175170
and we render the text input and label Elements.
176171

177-
If we want to see the **state** changes in action, we can open the Element Inspector::
178-
179-
python -m edifice --inspect tutorial.py MyApp
180-
181-
The Element Inspector allows us to see the current **state** and **props** for all Elements in a UI.
182-
Play around with the application and see how the **state** changes.
183-
184172
Now we want to add conversion from feet to meters. Instead of copying our code and repeating
185173
it for each measurement pair, we can factor out the conversion logic into its own component.
186174
We pass the conversion parameters into the component as **props** arguments::
@@ -190,7 +178,7 @@ We pass the conversion parameters into the component as **props** arguments::
190178
METERS_TO_FEET = 3.28084
191179

192180
@component
193-
def ConversionWidget(self, from_unit, to_unit, factor):
181+
def ConversionWidget(self, from_unit:str, to_unit:str, factor:float):
194182

195183
current_text, current_text_set = use_state("0.0")
196184

@@ -202,7 +190,7 @@ We pass the conversion parameters into the component as **props** arguments::
202190
Label(f"Measurement in {from_unit}:", style=from_label_style)
203191
TextInput(current_text, style=input_style, on_change=current_text_set)
204192
try:
205-
to_text = "%.3f" % (float(current_text) * factor)
193+
to_text = f"{float(current_text) * factor :.3f}"
206194
Label(f"Measurement in {to_unit}: {to_text}", style=to_label_style)
207195
except ValueError: # Could not convert string to float
208196
pass # So don't render the Label
@@ -216,3 +204,26 @@ We pass the conversion parameters into the component as **props** arguments::
216204

217205
if __name__ == "__main__":
218206
App(MyApp()).start()
207+
208+
209+
We can use the :doc:`Edifice Runner <developer_tools>` to run our application.
210+
211+
First install :code:`watchdog`.
212+
213+
.. code-block:: shell
214+
215+
pip install watchdog
216+
217+
Then run the application with the :doc:`Edifice Runner <developer_tools>`.
218+
This will run our application with **Element Inspector** and **Hot-Reload**.
219+
220+
.. code-block:: shell
221+
222+
python -m edifice --inspect tutorial.py MyApp
223+
224+
The Element Inspector allows us to see the current **state** and **props** for all Elements in a UI.
225+
Type in the :class:`TextInput` widget and see how the **state** changes.
226+
227+
Editing and saving the :code:`ConversionWidget` component source code will automatically
228+
reload the component and update the UI. (Editing the :code:`MyApp` component will
229+
not reload the UI, because Hot-Reload does not work for the root component.)

developer_tools.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,10 @@
385385
<section id="developer-tools">
386386
<h1>Developer Tools<a class="headerlink" href="#developer-tools" title="Link to this heading">#</a></h1>
387387
<p>The Edifice Runner provides some useful tools for developing Edifice applications.</p>
388+
<p>To use the Edifice Runner, you must install the <code class="code docutils literal notranslate"><span class="pre">watchdog</span></code> package.</p>
389+
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>pip<span class="w"> </span>install<span class="w"> </span>watchdog
390+
</pre></div>
391+
</div>
388392
<section id="dynamic-hot-reload">
389393
<h2>Dynamic hot-reload<a class="headerlink" href="#dynamic-hot-reload" title="Link to this heading">#</a></h2>
390394
<figure class="align-default">
@@ -455,11 +459,11 @@ <h2>Element Inspector<a class="headerlink" href="#element-inspector" title="Link
455459
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">edifice</span> <span class="o">--</span><span class="n">inspect</span> <span class="n">path</span><span class="o">/</span><span class="n">to</span><span class="o">/</span><span class="n">your</span><span class="o">/</span><span class="n">app</span><span class="o">.</span><span class="n">py</span> <span class="n">RootElement</span>
456460
</pre></div>
457461
</div>
458-
<p>The Element Inspector, like the Inspect Elements tool of web browsers
459-
or the React inspector tool,
460-
allows you to inspect the internal state of your components.
462+
<p>The Element Inspector allows you to inspect the running state of the application.
461463
It displays the entire Element Tree, as well as the props and state of
462-
every component.</p>
464+
every component.
465+
It is like the Inspect Elements tool of web browsers
466+
or the React inspector tool.</p>
463467
</section>
464468
</section>
465469

searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)