[python-mtTkinter/el5] Initial Epel release.
Paulo Roma Cavalcanti
roma at fedoraproject.org
Wed Aug 31 14:32:55 UTC 2011
commit c6090699ab6ba5e63147361fa633750e176e8677
Author: Paulo Roma Cavalcanti <promac at gmail.com>
Date: Wed Aug 31 11:32:01 2011 -0300
Initial Epel 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