Dynamic content#
Static text can be boring, so let's add some dynamic elements!
import datetime
from ignis.widgets import Widget
from ignis.utils import Utils
def update_label(clock_label: Widget.Label) -> None:
text = datetime.datetime.now().strftime("%H:%M:%S")
clock_label.set_label(text)
def bar(monitor: int) -> Widget.Window:
clock_label = Widget.Label()
Utils.Poll(1000, lambda x: update_label(clock_label))
return Widget.Window(
namespace=f"some-window-{monitor}",
monitor=monitor,
child=Widget.Box(
vertical=True,
spacing=10,
child=[clock_label],
),
)
This code updates label every second with the current time (using built-in Python module datetime
).
Signals#
Polling data every second isn't always ideal, as it can negatively impact performance.
This is where signals are useful.
Signals let us call a callback only when an event occurs (like on_click
in Widget.Button
).
Let's consider services, which often have both signals and properties.
Here's an example using the MprisService
:
from ignis.services.mpris import MprisService
mpris = MprisService.get_default()
mpris.connect("player_added", lambda x, player: print(player.desktop_entry, player.title))
# ^ ^
# Signals always pass the GObject they belong to as the first argument to the callback.
# In this case, MprisPlayer is the second argument of the signal.
Now, open any media player (like a video on YouTube or music on Spotify). Magic! The player name and title will be printed.
Hint
To manually emit (trigger) a signal, use the .emit()
method and pass the signal name to it.
Binding#
Next, let's bind a property.
Use the .bind()
method, passing the property name as the first argument, and optionally a transform function.
from ignis.services.audio import AudioService
from ignis.widgets import Widget
audio = AudioService.get_default()
def bar(monitor: int) -> Widget.Window:
return Widget.Window(
namespace=f"some-window-{monitor}",
monitor=monitor,
child=Widget.Box(
child=[
Widget.Label(label="Current volume: "),
Widget.Label(
label=audio.speaker.bind("volume", lambda value: str(value)) # this function converts the value to a string
)
]
),
)
Try changing the speaker volume using a tool like pavucontrol
.
When the property changes, the transform function (if provided) will be called with the new value, and it should return the processed result.
notify
signal#
The notify
is a special signal that emits when a property changes.
To connect to it, use the following syntax: "notify::PROPERTY-NAME"
.
Danger
Make sure to use -
instead of _
in the property name.
Otherwise, the signal will not be triggered.
mpris.connect("notify::players", lambda x, y: print(x.players))