import tkinter from tkinter import Event, Frame, Label, Tk from typing import Any, Tuple import reactivex from reactivex import Observable from reactivex import operators as ops from reactivex.scheduler.mainloop import TkinterScheduler from reactivex.subject import Subject def main() -> None: root = Tk() root.title("Rx for Python rocks") scheduler = TkinterScheduler(root) mousemoves: Subject[Event[Any]] = Subject() frame = Frame(root, width=600, height=600) frame.bind("", mousemoves.on_next) text = "TIME FLIES LIKE AN ARROW" def on_next(info: Tuple[tkinter.Label, "Event[Frame]", int]) -> None: label, ev, i = info label.place(x=ev.x + i * 12 + 15, y=ev.y) def label2stream( label: tkinter.Label, index: int ) -> Observable[Tuple[tkinter.Label, "Event[Frame]", int]]: return mousemoves.pipe( ops.map(lambda ev: (label, ev, index)), ops.delay(index * 0.1), ) def char2label(char: str) -> Label: return Label(frame, text=char, borderwidth=0, padx=0, pady=0) reactivex.from_(text).pipe( ops.map(char2label), ops.flat_map_indexed(label2stream), ).subscribe(on_next, on_error=print, scheduler=scheduler) frame.pack() root.mainloop() if __name__ == "__main__": main()