[python-mtTkinter/f16] Initial Fedora release.

Paulo Roma Cavalcanti roma at fedoraproject.org
Wed Aug 31 15:47:06 UTC 2011


commit 319dea6da1e6b982ef9b810577ea7f2474c26fa2
Author: Paulo Roma Cavalcanti <promac at gmail.com>
Date:   Wed Aug 31 12:46:30 2011 -0300

    Initial Fedora release.

 .gitignore            |    1 +
 08-clock-bezier.py    |  223 +++++++++++++++++++++++++++++++++++++++++++++++++
 python-mtTkinter.spec |   75 +++++++++++++++++
 sources               |    1 +
 4 files changed, 300 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..c058fa3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/mtTkinter-0.4.tar.gz
diff --git a/08-clock-bezier.py b/08-clock-bezier.py
new file mode 100644
index 0000000..d806015
--- /dev/null
+++ b/08-clock-bezier.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+# coding: UTF-8
+#
+# This most entertaining program was written in Tcl/Tk by Scott Hess
+# (shess at winternet.com).  It's a clock that uses a bezier curve anchored
+# at four points - the hour position, the minute position, the second
+# position and the center of the clock - to show the time.
+#
+# Mouse <Button-1> switches between display modes, and mouse <Button-2> 
+# switches between line thicknesses.
+#
+# http://www.tcl.tk/software/plugin/bclock.html
+#
+# This program needs a tcl compiled with threads enabled,
+# or alternatively, to replace Tkinter for mtTkinter. 
+#
+# Python version by Paulo Roma, 2009/08/06.
+
+import sys
+try:
+    from mtTkinter import *
+except Exception, msg:
+    print msg
+    sys.exit ( "mtTkinter not found: http://tkinter.unpythonic.net/wiki/mtTkinter" )
+import time
+import thread
+from math import pi, sin, cos
+
+# hand types
+types = ["normal", "curve", "angle", "bezier"]
+
+class _hand:
+    def __init__ ( self, zero = 0.0, h = 0.40, m = 0.75, s = 0.85 ):
+        """Constructor."""
+
+        self.__hour    = h
+        self.__minute  = m
+        self.__second  = s
+        self.___0      = zero
+
+        self.__intick  = 0.95
+        self.__outtick = 1.00
+        self.__width   = 0.05
+        self.__scale   = 100
+        self.__type    = "bezier"
+        self.__tindx   = 3
+    
+    def getWidth(self):
+        return self.__width
+
+    def getScale(self):
+        return self.__scale
+
+    def getTindx(self):
+        return self.__tindx
+
+    def getType(self):
+        return self.__type
+
+    def setType(self, t):
+        self.__type = t
+
+    def setTindx(self, t):
+        self.__tindx = t
+
+    def setWidth(self, w):
+        self.__width = w
+
+    def setScale(self, s):
+        self.__scale = s
+
+    def setInTick(self, i):
+        self.__intick = i
+
+    def setOutTick(self, o):
+        self.__outtick = o
+
+    def getCurveData (self, type):
+        """Returns the data for each type of clock."""
+
+        if ( type == "normal" ):
+             return [self.__minute, self.___0, self.___0, self.__second, self.___0, 
+                     self.___0, self.__hour, self.___0, self.___0, self.__minute]
+        elif ( type == "curve" ):
+             return [self.__minute, self.___0, self.__second, self.___0, self.__hour, 
+                     self.___0, self.__minute]
+        elif ( type == "angle" ):
+             return [self.__minute, self.__second, self.__second, self.__hour]
+        elif ( type == "bezier" ):
+             return [self.__minute, self.__second, self.___0, self.__hour]
+        elif ( type == "tick" ):
+             return [self.__intick, self.__outtick]
+        else: return []
+
+pi180  = pi / 180.0   
+resize = True
+mw     = Tk()
+mw.title ("Clock Bezier")
+clock  = Canvas()
+hand   = _hand()
+
+def buildClock(e):
+    """Build the clock. Puts tickmarks every 30 degrees, tagged
+       "ticks", and prefills the "hands" line.
+    """
+
+    global resize
+
+    clock.delete("marks")
+    clock.update()
+    if ( resize and e ):
+         if ( e.width > e.height ):
+              w = str(e.height)
+         else:
+              w = str(e.width)
+    else:
+         w = clock.cget("width")
+    mw.geometry(w+"x"+w)    # ensure clock is square
+    hand.setScale ( int(w) / 2.0 )
+    
+    # This is a horrid hack. Use the hands( ) procedure to
+    # calculate the tickmark positions by temporarily changing
+    # the clock type.
+    
+    type = hand.getType()
+    hand.setType ( 'tick' )
+    angles = _hand()
+    for i in range (0, 12):
+        j = i * 30 * pi180
+        angles.setInTick ( j )
+        angles.setOutTick ( j )
+        clock.create_line(hands(angles), tags = ("ticks", "marks"))
+    hand.setType ( type )
+    
+    clock.create_line(0, 0, 0, 0, smooth=True, tags = ("hands", "marks"))
+    clock.itemconfigure("marks", capstyle="round", width = hand.getWidth() * hand.getScale())
+
+def hands(aa):
+    """Calculate the set of points for the current hand type and
+       the angles in the passed array.
+    """
+
+    global hand
+    ss = hand.getScale()
+    points = []
+    la = aa.getCurveData (hand.getType())
+    lh = hand.getCurveData (hand.getType())
+
+    for desc in range (0,len(lh)):
+        points.append ( sin(la[desc]) * lh[desc] * ss + ss )
+        points.append ( ss - cos(la[desc]) * lh[desc] * ss )
+    return points
+
+def incrType(e):
+    """Goes to the next clock type."""
+
+    global hand
+    hand.setTindx ( hand.getTindx()+1 )
+    hand.setType ( types [ hand.getTindx() % len(types) ] )
+
+def incrWidth(e):
+    """Goes to the next clock width."""
+
+    global hand
+    w = hand.getWidth() + 0.05
+    if w > 0.25:
+       hand.setWidth (0)
+    else:
+       hand.setWidth (w)
+    clock.itemconfigure("marks", width = hand.getWidth() * hand.getScale())
+
+def setClock (hour, minute, second):
+    """Calculate the angles for the second, minute, and hour hands,
+       and then update the clock hands to match.
+    """
+
+    k = 6 * pi180
+    second *= k
+    minute *= k
+    angles=_hand (0.0, hour*5*k + minute/12, minute, second)
+
+    sector = int (second + 0.5)
+    colors = ["cyan", "green", "blue", "purple", "red", "yellow", "orange"]
+    clock.itemconfigure("hands", fill=colors[sector])
+
+    clock.coords("hands", *hands(angles))
+
+def getTime(): 
+    """Returns the current time: hours, minutes and seconds."""
+
+    t = list(time.localtime(time.time()))
+    return (t[3], t[4], t[5])   
+    
+def updateClock():
+    """Updates the hands of the clock each second."""
+
+    while True:
+          h,m,s = getTime()
+          setClock (h,m,s)
+          time.sleep(1.0)
+
+def trigger ():
+    """Creates a thread for the clock."""
+
+    thread.start_new_thread ( updateClock, () )
+
+def main():
+    """Main program."""
+
+    clock.config (width=200,height=200)
+    clock.pack (expand=YES, fill=BOTH)
+    clock.bind ("<Configure>", buildClock)
+    clock.bind ("<Button-1>",  incrType)     # mouse left button
+    clock.bind ("<Button-2>",  incrWidth)    # mouse middle button
+    clock.pack()
+    buildClock(None)
+  
+    trigger ()
+
+    clock.mainloop()
+
+if __name__=="__main__":
+   sys.exit(main())
diff --git a/python-mtTkinter.spec b/python-mtTkinter.spec
new file mode 100644
index 0000000..a77e497
--- /dev/null
+++ b/python-mtTkinter.spec
@@ -0,0 +1,75 @@
+%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+
+Summary:   A thread-safe version of Tkinter
+Name:      python-mtTkinter
+Version:   0.4
+Release:   3%{?dist}
+License:   LGPLv3+
+Source0:   http://tkinter.unpythonic.net/attach/mtTkinter/attachments/mtTkinter-%{version}.tar.gz
+Source1:   08-clock-bezier.py
+Group:     Development/Languages
+URL:       http://tkinter.unpythonic.net/wiki/mtTkinter
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: python-devel >= 2.4
+Requires:  tkinter
+BuildArch: noarch
+
+%description
+Although Tkinter is technically thread-safe 
+(assuming Tk is built with --enable-threads), 
+practically speaking there are still problems when used in multithreaded 
+Python applications.  The problems stem from the fact that the _tkinter 
+module attempts to gain control of the main thread via a polling technique 
+when processing calls from other threads.  If it succeeds, all is well. 
+If it fails (i.e., after a timeout), the application receives an exception 
+with the message: "RuntimeError: main thread is not in main loop". 
+There is no way to tell when this might happen, so calling Tk routines 
+from multiple threads seems to be problematic at best.
+
+The mtTkinter module solves this problem by modifying some Tkinter 
+module definitions (in memory). The modified code intercepts 
+out-of-thread Tkinter calls and marshals them through a queue which 
+is read by an 'after' event running periodically in the main loop. 
+This is similar to the technique used in many other platforms 
+(e.g., .NET's InvokeRequired/Invoke mechanism). 
+The technique used in mtTkinter is exception-safe as well, 
+marshaling exceptions through a response queue back to the caller's thread. 
+
+%prep
+%setup -q -n mtTkinter-%{version}
+
+%build
+
+%install
+rm -rf %{buildroot}
+
+mkdir -p %{buildroot}%{python_sitelib}
+install -pm 0644 %{_builddir}/mtTkinter-%{version}/mtTkinter.py %{buildroot}%{python_sitelib}/
+install -pm 0644 %{SOURCE1} %{_builddir}/mtTkinter-%{version}/clock-bezier.py
+
+%clean
+rm -rf %{buildroot}
+
+%files 
+%defattr(-,root,root,-)
+%doc clock-bezier.py lgpl.txt gpl.txt
+%{python_sitelib}/mtTkinter.py*
+
+%changelog
+
+* Sun Aug 28 2011 Paulo Roma <roma at lcg.ufrj.br> 0.4-3
+- Chmod mtTkinter.py to 0644
+
+* Sun Aug 14 2011 Paulo Roma <roma at lcg.ufrj.br> 0.4-2
+- Changed license to LGPLv3+
+
+* Fri Jan 13 2011 Paulo Roma <roma at lcg.ufrj.br> 0.4-1
+- Updated to 0.4
+- Changed license.
+
+* Sat Oct 23 2010 Paulo Roma <roma at lcg.ufrj.br> 0.3-2
+- Added BR python-devel.
+
+* Mon Feb 01 2010 Paulo Roma <roma at lcg.ufrj.br> 0.3-1
+- Initial spec file.
+
diff --git a/sources b/sources
index e69de29..c04d082 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+56f2f556d29c67d4e35d87f734f09891  mtTkinter-0.4.tar.gz


More information about the scm-commits mailing list