{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Timer ipywidget using threads\n", "\n", "based on https://github.com/sclamons/murraylab_tools/blob/c633ed08abc189b5f18cfbc5288359f267a2487a/murraylab_tools/protocol/protocol.py\n", "and\n", "https://github.com/sclamons/murraylab_tools/blob/c633ed08abc189b5f18cfbc5288359f267a2487a/examples/protocols.ipynb\n", "found by searching 'import ipywidgets as widgets threading .stop' at github.\n", "And then when I found `protocol.py` I searched `Timer` in that repo to find the notebook\n", "\n", "\n", "\n", "This notebook works in Binder sessions launched from [this jupyter-jsmol repo](https://github.com/fekad/jupyter-jsmol).\n", "launch url: https://mybinder.org/v2/gh/fekad/jupyter-jsmol/master?filepath=examples\n", "\n", "--------\n", "\n", "Code to illustrate concepts from [here](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Asynchronous.html#Updating-a-widget-in-the-background) in relation to a Jupyter discourse question [here](https://discourse.jupyter.org/t/keyboardinterrupt-button-in-voila/7405).\n", "\n", "Also considered:\n", "https://github.com/kjoelovelife/Jetson_nano/blob/e7d2fb6a6db02ba041197768996d066268f22b0a/jetson-dlinano/NVIDIA%20Course/5.%20Thumbs%20Project.md" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import ipywidgets as widgets\n", "from IPython.display import display, Javascript\n", "from traitlets import Unicode, validate\n", "import time\n", "import threading\n", "\n", "class Timer():\n", "\n", " def __init__(self,limit=180):\n", " #self.value = Unicode('00:00:00').tag(sync=True)\n", " self.labwidg = widgets.Button(description=\"00:00:00\",layout=lay(120,50))\n", " self.labwidg.on_click(self.threadTimer)\n", " #self.labwidg.style.button_color = \"gree\"\n", " #widgets.Label('00:00:00')\n", " #display(self.labwidg)\n", " self.limit = limit\n", " self.stopTimer = False\n", " self.thread = None\n", " self.buttonState = \"Start\"\n", " def timeit(self, limit=180):\n", " #display(self)\n", " hours = 0\n", " mins = 0\n", " secs = 0\n", " for i in range(1,(limit*60+1)):\n", " if(self.buttonState == \"Start\"):\n", " self.labwidg.button_style=\"primary\"\n", " #self.labwidg.style.font_weight = \"50px\"\n", " elif(self.buttonState == \"Stop\"):\n", " self.labwidg.button_style=\"success\"\n", " #self.labwidg.style.font_weight = \"50px\"\n", " elif(self.buttonState == \"Reset\"):\n", " self.labwidg.button_style=\"warning\"\n", " #self.labwidg.style.font_weight = \"50px\"\n", " if(self.stopTimer):\n", " self.stopTimer = False\n", " self.thread = None\n", " break\n", " if i%60 == 0:\n", " if i%3600 == 0:\n", " secs = 0\n", " mins = 0\n", " hours += 1\n", " else:\n", " secs = 0\n", " mins += 1\n", " else:\n", " secs += 1\n", " time.sleep(.0167)\n", " self.labwidg.description = '{hour:02}:{minute:02}:{second:02}'.\\\n", " format(hour=hours,minute=mins,second=secs)\n", " #def twrap(self,b,limit=180):\n", " # self.timeit(limit=limit)\n", " def threadTimer(self,b):\n", " #b.description = self.buttonState\n", " if(self.buttonState == \"Start\"):\n", " if(self.thread == None):\n", " self.thread = threading.Thread(target=self.timeit,args=(self.limit,))\n", " self.thread.start()\n", " self.buttonState = \"Stop\"\n", " elif(self.buttonState == \"Stop\"):\n", " if(self.thread != None):\n", " self.stopTimer=True\n", " self.buttonState = \"Reset\"\n", " else:\n", " self.labwidg.description = '00:00:00'\n", " self.Thread = None\n", " self.stopTimer=False\n", " self.buttonState = \"Start\"\n", " def stopTime(self,b):\n", " self.stopTimer=True\n", "\n", "#def startTimer(b,timer):\n", " #, args=(,))\n", "def lay(width,height):\n", " return widgets.Layout(width=str(width)+\"px\",height=str(height)+\"px\")\n", "def display_timer():\n", " timer = Timer()\n", " display(timer.labwidg)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "488413e913ee4afca43c256cc51621d4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Button(description='00:00:00', layout=Layout(height='50px', width='120px'), style=ButtonStyle())" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display_timer()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.8" } }, "nbformat": 4, "nbformat_minor": 4 }