mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
More cleanup: Move some demos into a dedicated Tools/demo dir, move 2to3 demo to Tools, and remove all the other Demo content.
This commit is contained in:
parent
6f17e2df29
commit
7fafbc95c0
164 changed files with 25 additions and 12436 deletions
62
Demo/README
62
Demo/README
|
@ -1,62 +0,0 @@
|
|||
This directory contains various demonstrations of what you can do with
|
||||
Python. They were all written by me except where explicitly stated
|
||||
otherwise -- in general, demos contributed by others ends up in the
|
||||
../Contrib directory, unless I think they're of utmost general
|
||||
importance (like Matt Conway's Tk demos).
|
||||
|
||||
A fair number of utilities that are useful when while developing
|
||||
Python code can be found in the ../Tools directory -- some of these
|
||||
can also be considered good examples of how to write Python code.
|
||||
|
||||
Finally, in order to save disk space and net bandwidth, not all
|
||||
subdirectories listed here are distributed. They are listed just
|
||||
in case I change my mind about them.
|
||||
|
||||
|
||||
cgi CGI examples.
|
||||
|
||||
classes Some examples of how to use classes.
|
||||
|
||||
comparisons A set of responses to a really old language-comparison
|
||||
challenge.
|
||||
|
||||
curses A set of curses demos.
|
||||
|
||||
distutils Test for using transparent 2to3 conversion in distutils.
|
||||
|
||||
embed An example of embedding Python in another application
|
||||
(see also pysvr).
|
||||
|
||||
imputil Demonstration subclasses of imputil.Importer.
|
||||
|
||||
md5test Test program for the optional md5 module.
|
||||
|
||||
newmetaclasses Demonstration of metaclasses.
|
||||
|
||||
parser Example using the parser module.
|
||||
|
||||
pysvr An example of embedding Python in a threaded
|
||||
application.
|
||||
|
||||
rpc A set of classes for building clients and servers for
|
||||
Sun RPC.
|
||||
|
||||
scripts Some useful Python scripts that I put in my bin
|
||||
directory. No optional built-in modules needed.
|
||||
|
||||
sockets Examples for the new built-in module 'socket'.
|
||||
|
||||
threads Demos that use the 'thread' module. (Currently these
|
||||
only run on SGIs, but this may change in the future.)
|
||||
|
||||
tix Demos using the Tix widget set addition to Tkinter.
|
||||
|
||||
tkinter Demos using the Tk interface (including Matt Conway's
|
||||
excellent set of demos).
|
||||
|
||||
turtle Demos for the "turtle" module.
|
||||
|
||||
xml Some XML demos.
|
||||
|
||||
zlib Some demos for the zlib module (see also the standard
|
||||
library module gzip.py).
|
|
@ -1,304 +0,0 @@
|
|||
# Complex numbers
|
||||
# ---------------
|
||||
|
||||
# [Now that Python has a complex data type built-in, this is not very
|
||||
# useful, but it's still a nice example class]
|
||||
|
||||
# This module represents complex numbers as instances of the class Complex.
|
||||
# A Complex instance z has two data attribues, z.re (the real part) and z.im
|
||||
# (the imaginary part). In fact, z.re and z.im can have any value -- all
|
||||
# arithmetic operators work regardless of the type of z.re and z.im (as long
|
||||
# as they support numerical operations).
|
||||
#
|
||||
# The following functions exist (Complex is actually a class):
|
||||
# Complex([re [,im]) -> creates a complex number from a real and an imaginary part
|
||||
# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes)
|
||||
# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true
|
||||
# if z is a tuple(re, im) it will also be converted
|
||||
# PolarToComplex([r [,phi [,fullcircle]]]) ->
|
||||
# the complex number z for which r == z.radius() and phi == z.angle(fullcircle)
|
||||
# (r and phi default to 0)
|
||||
# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z).
|
||||
#
|
||||
# Complex numbers have the following methods:
|
||||
# z.abs() -> absolute value of z
|
||||
# z.radius() == z.abs()
|
||||
# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units
|
||||
# z.phi([fullcircle]) == z.angle(fullcircle)
|
||||
#
|
||||
# These standard functions and unary operators accept complex arguments:
|
||||
# abs(z)
|
||||
# -z
|
||||
# +z
|
||||
# not z
|
||||
# repr(z) == `z`
|
||||
# str(z)
|
||||
# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero
|
||||
# the result equals hash(z.re)
|
||||
# Note that hex(z) and oct(z) are not defined.
|
||||
#
|
||||
# These conversions accept complex arguments only if their imaginary part is zero:
|
||||
# int(z)
|
||||
# float(z)
|
||||
#
|
||||
# The following operators accept two complex numbers, or one complex number
|
||||
# and one real number (int, long or float):
|
||||
# z1 + z2
|
||||
# z1 - z2
|
||||
# z1 * z2
|
||||
# z1 / z2
|
||||
# pow(z1, z2)
|
||||
# cmp(z1, z2)
|
||||
# Note that z1 % z2 and divmod(z1, z2) are not defined,
|
||||
# nor are shift and mask operations.
|
||||
#
|
||||
# The standard module math does not support complex numbers.
|
||||
# The cmath modules should be used instead.
|
||||
#
|
||||
# Idea:
|
||||
# add a class Polar(r, phi) and mixed-mode arithmetic which
|
||||
# chooses the most appropriate type for the result:
|
||||
# Complex for +,-,cmp
|
||||
# Polar for *,/,pow
|
||||
|
||||
import math
|
||||
import sys
|
||||
|
||||
twopi = math.pi*2.0
|
||||
halfpi = math.pi/2.0
|
||||
|
||||
def IsComplex(obj):
|
||||
return hasattr(obj, 're') and hasattr(obj, 'im')
|
||||
|
||||
def ToComplex(obj):
|
||||
if IsComplex(obj):
|
||||
return obj
|
||||
elif isinstance(obj, tuple):
|
||||
return Complex(*obj)
|
||||
else:
|
||||
return Complex(obj)
|
||||
|
||||
def PolarToComplex(r = 0, phi = 0, fullcircle = twopi):
|
||||
phi = phi * (twopi / fullcircle)
|
||||
return Complex(math.cos(phi)*r, math.sin(phi)*r)
|
||||
|
||||
def Re(obj):
|
||||
if IsComplex(obj):
|
||||
return obj.re
|
||||
return obj
|
||||
|
||||
def Im(obj):
|
||||
if IsComplex(obj):
|
||||
return obj.im
|
||||
return 0
|
||||
|
||||
class Complex:
|
||||
|
||||
def __init__(self, re=0, im=0):
|
||||
_re = 0
|
||||
_im = 0
|
||||
if IsComplex(re):
|
||||
_re = re.re
|
||||
_im = re.im
|
||||
else:
|
||||
_re = re
|
||||
if IsComplex(im):
|
||||
_re = _re - im.im
|
||||
_im = _im + im.re
|
||||
else:
|
||||
_im = _im + im
|
||||
# this class is immutable, so setting self.re directly is
|
||||
# not possible.
|
||||
self.__dict__['re'] = _re
|
||||
self.__dict__['im'] = _im
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
raise TypeError('Complex numbers are immutable')
|
||||
|
||||
def __hash__(self):
|
||||
if not self.im:
|
||||
return hash(self.re)
|
||||
return hash((self.re, self.im))
|
||||
|
||||
def __repr__(self):
|
||||
if not self.im:
|
||||
return 'Complex(%r)' % (self.re,)
|
||||
else:
|
||||
return 'Complex(%r, %r)' % (self.re, self.im)
|
||||
|
||||
def __str__(self):
|
||||
if not self.im:
|
||||
return repr(self.re)
|
||||
else:
|
||||
return 'Complex(%r, %r)' % (self.re, self.im)
|
||||
|
||||
def __neg__(self):
|
||||
return Complex(-self.re, -self.im)
|
||||
|
||||
def __pos__(self):
|
||||
return self
|
||||
|
||||
def __abs__(self):
|
||||
return math.hypot(self.re, self.im)
|
||||
|
||||
def __int__(self):
|
||||
if self.im:
|
||||
raise ValueError("can't convert Complex with nonzero im to int")
|
||||
return int(self.re)
|
||||
|
||||
def __float__(self):
|
||||
if self.im:
|
||||
raise ValueError("can't convert Complex with nonzero im to float")
|
||||
return float(self.re)
|
||||
|
||||
def __eq__(self, other):
|
||||
other = ToComplex(other)
|
||||
return (self.re, self.im) == (other.re, other.im)
|
||||
|
||||
def __bool__(self):
|
||||
return not (self.re == self.im == 0)
|
||||
|
||||
abs = radius = __abs__
|
||||
|
||||
def angle(self, fullcircle = twopi):
|
||||
return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi)
|
||||
|
||||
phi = angle
|
||||
|
||||
def __add__(self, other):
|
||||
other = ToComplex(other)
|
||||
return Complex(self.re + other.re, self.im + other.im)
|
||||
|
||||
__radd__ = __add__
|
||||
|
||||
def __sub__(self, other):
|
||||
other = ToComplex(other)
|
||||
return Complex(self.re - other.re, self.im - other.im)
|
||||
|
||||
def __rsub__(self, other):
|
||||
other = ToComplex(other)
|
||||
return other - self
|
||||
|
||||
def __mul__(self, other):
|
||||
other = ToComplex(other)
|
||||
return Complex(self.re*other.re - self.im*other.im,
|
||||
self.re*other.im + self.im*other.re)
|
||||
|
||||
__rmul__ = __mul__
|
||||
|
||||
def __truediv__(self, other):
|
||||
other = ToComplex(other)
|
||||
d = float(other.re*other.re + other.im*other.im)
|
||||
if not d: raise ZeroDivisionError('Complex division')
|
||||
return Complex((self.re*other.re + self.im*other.im) / d,
|
||||
(self.im*other.re - self.re*other.im) / d)
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
other = ToComplex(other)
|
||||
return other / self
|
||||
|
||||
def __pow__(self, n, z=None):
|
||||
if z is not None:
|
||||
raise TypeError('Complex does not support ternary pow()')
|
||||
if IsComplex(n):
|
||||
if n.im:
|
||||
if self.im: raise TypeError('Complex to the Complex power')
|
||||
else: return exp(math.log(self.re)*n)
|
||||
n = n.re
|
||||
r = pow(self.abs(), n)
|
||||
phi = n*self.angle()
|
||||
return Complex(math.cos(phi)*r, math.sin(phi)*r)
|
||||
|
||||
def __rpow__(self, base):
|
||||
base = ToComplex(base)
|
||||
return pow(base, self)
|
||||
|
||||
def exp(z):
|
||||
r = math.exp(z.re)
|
||||
return Complex(math.cos(z.im)*r,math.sin(z.im)*r)
|
||||
|
||||
|
||||
def checkop(expr, a, b, value, fuzz = 1e-6):
|
||||
print(' ', a, 'and', b, end=' ')
|
||||
try:
|
||||
result = eval(expr)
|
||||
except Exception as e:
|
||||
print('!!\t!!\t!! error: {}'.format(e))
|
||||
return
|
||||
print('->', result)
|
||||
if isinstance(result, str) or isinstance(value, str):
|
||||
ok = (result == value)
|
||||
else:
|
||||
ok = abs(result - value) <= fuzz
|
||||
if not ok:
|
||||
print('!!\t!!\t!! should be', value, 'diff', abs(result - value))
|
||||
|
||||
def test():
|
||||
print('test constructors')
|
||||
constructor_test = (
|
||||
# "expect" is an array [re,im] "got" the Complex.
|
||||
( (0,0), Complex() ),
|
||||
( (0,0), Complex() ),
|
||||
( (1,0), Complex(1) ),
|
||||
( (0,1), Complex(0,1) ),
|
||||
( (1,2), Complex(Complex(1,2)) ),
|
||||
( (1,3), Complex(Complex(1,2),1) ),
|
||||
( (0,0), Complex(0,Complex(0,0)) ),
|
||||
( (3,4), Complex(3,Complex(4)) ),
|
||||
( (-1,3), Complex(1,Complex(3,2)) ),
|
||||
( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) )
|
||||
cnt = [0,0]
|
||||
for t in constructor_test:
|
||||
cnt[0] += 1
|
||||
if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)):
|
||||
print(" expected", t[0], "got", t[1])
|
||||
cnt[1] += 1
|
||||
print(" ", cnt[1], "of", cnt[0], "tests failed")
|
||||
# test operators
|
||||
testsuite = {
|
||||
'a+b': [
|
||||
(1, 10, 11),
|
||||
(1, Complex(0,10), Complex(1,10)),
|
||||
(Complex(0,10), 1, Complex(1,10)),
|
||||
(Complex(0,10), Complex(1), Complex(1,10)),
|
||||
(Complex(1), Complex(0,10), Complex(1,10)),
|
||||
],
|
||||
'a-b': [
|
||||
(1, 10, -9),
|
||||
(1, Complex(0,10), Complex(1,-10)),
|
||||
(Complex(0,10), 1, Complex(-1,10)),
|
||||
(Complex(0,10), Complex(1), Complex(-1,10)),
|
||||
(Complex(1), Complex(0,10), Complex(1,-10)),
|
||||
],
|
||||
'a*b': [
|
||||
(1, 10, 10),
|
||||
(1, Complex(0,10), Complex(0, 10)),
|
||||
(Complex(0,10), 1, Complex(0,10)),
|
||||
(Complex(0,10), Complex(1), Complex(0,10)),
|
||||
(Complex(1), Complex(0,10), Complex(0,10)),
|
||||
],
|
||||
'a/b': [
|
||||
(1., 10, 0.1),
|
||||
(1, Complex(0,10), Complex(0, -0.1)),
|
||||
(Complex(0, 10), 1, Complex(0, 10)),
|
||||
(Complex(0, 10), Complex(1), Complex(0, 10)),
|
||||
(Complex(1), Complex(0,10), Complex(0, -0.1)),
|
||||
],
|
||||
'pow(a,b)': [
|
||||
(1, 10, 1),
|
||||
(1, Complex(0,10), 1),
|
||||
(Complex(0,10), 1, Complex(0,10)),
|
||||
(Complex(0,10), Complex(1), Complex(0,10)),
|
||||
(Complex(1), Complex(0,10), 1),
|
||||
(2, Complex(4,0), 16),
|
||||
],
|
||||
}
|
||||
for expr in sorted(testsuite):
|
||||
print(expr + ':')
|
||||
t = (expr,)
|
||||
for item in testsuite[expr]:
|
||||
checkop(*(t+item))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
|
@ -1,227 +0,0 @@
|
|||
"""
|
||||
Class Date supplies date objects that support date arithmetic.
|
||||
|
||||
Date(month,day,year) returns a Date object. An instance prints as,
|
||||
e.g., 'Mon 16 Aug 1993'.
|
||||
|
||||
Addition, subtraction, comparison operators, min, max, and sorting
|
||||
all work as expected for date objects: int+date or date+int returns
|
||||
the date `int' days from `date'; date+date raises an exception;
|
||||
date-int returns the date `int' days before `date'; date2-date1 returns
|
||||
an integer, the number of days from date1 to date2; int-date raises an
|
||||
exception; date1 < date2 is true iff date1 occurs before date2 (&
|
||||
similarly for other comparisons); min(date1,date2) is the earlier of
|
||||
the two dates and max(date1,date2) the later; and date objects can be
|
||||
used as dictionary keys.
|
||||
|
||||
Date objects support one visible method, date.weekday(). This returns
|
||||
the day of the week the date falls on, as a string.
|
||||
|
||||
Date objects also have 4 read-only data attributes:
|
||||
.month in 1..12
|
||||
.day in 1..31
|
||||
.year int or long int
|
||||
.ord the ordinal of the date relative to an arbitrary staring point
|
||||
|
||||
The Dates module also supplies function today(), which returns the
|
||||
current date as a date object.
|
||||
|
||||
Those entranced by calendar trivia will be disappointed, as no attempt
|
||||
has been made to accommodate the Julian (etc) system. On the other
|
||||
hand, at least this package knows that 2000 is a leap year but 2100
|
||||
isn't, and works fine for years with a hundred decimal digits <wink>.
|
||||
|
||||
Tim Peters tim@ksr.com
|
||||
not speaking for Kendall Square Research Corp
|
||||
|
||||
Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
|
||||
by Guido van Rossum
|
||||
|
||||
Note that as of Python 2.3, a datetime module is included in the stardard
|
||||
library.
|
||||
"""
|
||||
|
||||
import functools
|
||||
|
||||
_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May',
|
||||
'June', 'July', 'August', 'September', 'October',
|
||||
'November', 'December' ]
|
||||
|
||||
_DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday',
|
||||
'Tuesday', 'Wednesday', 'Thursday' ]
|
||||
|
||||
_DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
|
||||
|
||||
_DAYS_BEFORE_MONTH = []
|
||||
dbm = 0
|
||||
for dim in _DAYS_IN_MONTH:
|
||||
_DAYS_BEFORE_MONTH.append(dbm)
|
||||
dbm = dbm + dim
|
||||
del dbm, dim
|
||||
|
||||
def _is_leap(year): # 1 if leap year, else 0
|
||||
if year % 4 != 0: return 0
|
||||
if year % 400 == 0: return 1
|
||||
return year % 100 != 0
|
||||
|
||||
def _days_in_year(year): # number of days in year
|
||||
return 365 + _is_leap(year)
|
||||
|
||||
def _days_before_year(year): # number of days before year
|
||||
return year*365 + (year+3)//4 - (year+99)//100 + (year+399)//400
|
||||
|
||||
def _days_in_month(month, year): # number of days in month of year
|
||||
if month == 2 and _is_leap(year): return 29
|
||||
return _DAYS_IN_MONTH[month-1]
|
||||
|
||||
def _days_before_month(month, year): # number of days in year before month
|
||||
return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year))
|
||||
|
||||
def _date2num(date): # compute ordinal of date.month,day,year
|
||||
return _days_before_year(date.year) + \
|
||||
_days_before_month(date.month, date.year) + \
|
||||
date.day
|
||||
|
||||
_DI400Y = _days_before_year(400) # number of days in 400 years
|
||||
|
||||
def _num2date(n): # return date with ordinal n
|
||||
if not isinstance(n, int):
|
||||
raise TypeError('argument must be integer: %r' % type(n))
|
||||
|
||||
# Get uninitialized Date object. This is necesary because once
|
||||
# attributes are set, they cannot be changed.
|
||||
ans = Date.__new__(Date)
|
||||
ans.ord = n
|
||||
|
||||
n400 = (n-1)//_DI400Y # # of 400-year blocks preceding
|
||||
year, n = 400 * n400, n - _DI400Y * n400
|
||||
more = n // 365
|
||||
dby = _days_before_year(more)
|
||||
if dby >= n:
|
||||
more = more - 1
|
||||
dby = dby - _days_in_year(more)
|
||||
year, n = year + more, n - dby
|
||||
month = min(n//29 + 1, 12)
|
||||
dbm = _days_before_month(month, year)
|
||||
if dbm >= n:
|
||||
month = month - 1
|
||||
dbm = dbm - _days_in_month(month, year)
|
||||
|
||||
ans.month, ans.day, ans.year = month, n-dbm, year
|
||||
return ans
|
||||
|
||||
def _num2day(n): # return weekday name of day with ordinal n
|
||||
return _DAY_NAMES[n % 7]
|
||||
|
||||
@functools.total_ordering
|
||||
class Date:
|
||||
def __init__(self, month, day, year):
|
||||
if not 1 <= month <= 12:
|
||||
raise ValueError('month must be in 1..12: %r' % (month,))
|
||||
dim = _days_in_month(month, year)
|
||||
if not 1 <= day <= dim:
|
||||
raise ValueError('day must be in 1..%r: %r' % (dim, day))
|
||||
self.month, self.day, self.year = map(int, (month, day, year))
|
||||
self.ord = _date2num(self)
|
||||
|
||||
# don't allow setting existing attributes
|
||||
def __setattr__(self, name, value):
|
||||
if name in self.__dict__:
|
||||
raise AttributeError('read-only attribute ' + name)
|
||||
self.__dict__[name] = value
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.ord == other.ord
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.ord < other.ord
|
||||
|
||||
# define a hash function so dates can be used as dictionary keys
|
||||
def __hash__(self):
|
||||
return hash(self.ord)
|
||||
|
||||
# print as, e.g., Mon 16 Aug 1993
|
||||
def __repr__(self):
|
||||
return '%.3s %2d %.3s %r' % (
|
||||
self.weekday(),
|
||||
self.day,
|
||||
_MONTH_NAMES[self.month-1],
|
||||
self.year)
|
||||
|
||||
# Python 1.1 coerces neither int+date nor date+int
|
||||
def __add__(self, n):
|
||||
if not isinstance(n, int):
|
||||
raise TypeError('can\'t add %r to date' % type(n))
|
||||
return _num2date(self.ord + n)
|
||||
__radd__ = __add__ # handle int+date
|
||||
|
||||
# Python 1.1 coerces neither date-int nor date-date
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, int): # date-int
|
||||
return _num2date(self.ord - other)
|
||||
else:
|
||||
return self.ord - other.ord # date-date
|
||||
|
||||
# complain about int-date
|
||||
def __rsub__(self, other):
|
||||
raise TypeError('Can\'t subtract date from integer')
|
||||
|
||||
def weekday(self):
|
||||
return _num2day(self.ord)
|
||||
|
||||
def today():
|
||||
import time
|
||||
local = time.localtime(time.time())
|
||||
return Date(local[1], local[2], local[0])
|
||||
|
||||
class DateTestError(Exception):
|
||||
pass
|
||||
|
||||
def test(firstyear, lastyear):
|
||||
a = Date(9,30,1913)
|
||||
b = Date(9,30,1914)
|
||||
if repr(a) != 'Tue 30 Sep 1913':
|
||||
raise DateTestError('__repr__ failure')
|
||||
if (not a < b) or a == b or a > b or b != b:
|
||||
raise DateTestError('__cmp__ failure')
|
||||
if a+365 != b or 365+a != b:
|
||||
raise DateTestError('__add__ failure')
|
||||
if b-a != 365 or b-365 != a:
|
||||
raise DateTestError('__sub__ failure')
|
||||
try:
|
||||
x = 1 - a
|
||||
raise DateTestError('int-date should have failed')
|
||||
except TypeError:
|
||||
pass
|
||||
try:
|
||||
x = a + b
|
||||
raise DateTestError('date+date should have failed')
|
||||
except TypeError:
|
||||
pass
|
||||
if a.weekday() != 'Tuesday':
|
||||
raise DateTestError('weekday() failure')
|
||||
if max(a,b) is not b or min(a,b) is not a:
|
||||
raise DateTestError('min/max failure')
|
||||
d = {a-1:b, b:a+1}
|
||||
if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913):
|
||||
raise DateTestError('dictionary failure')
|
||||
|
||||
# verify date<->number conversions for first and last days for
|
||||
# all years in firstyear .. lastyear
|
||||
|
||||
lord = _days_before_year(firstyear)
|
||||
y = firstyear
|
||||
while y <= lastyear:
|
||||
ford = lord + 1
|
||||
lord = ford + _days_in_year(y) - 1
|
||||
fd, ld = Date(1,1,y), Date(12,31,y)
|
||||
if (fd.ord,ld.ord) != (ford,lord):
|
||||
raise DateTestError('date->num failed', y)
|
||||
fd, ld = _num2date(ford), _num2date(lord)
|
||||
if (1,1,y,12,31,y) != \
|
||||
(fd.month,fd.day,fd.year,ld.month,ld.day,ld.year):
|
||||
raise DateTestError('num->date failed', y)
|
||||
y = y + 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
test(1850, 2150)
|
|
@ -1,11 +0,0 @@
|
|||
Examples of classes that implement special operators (see reference manual):
|
||||
|
||||
Complex.py Complex numbers
|
||||
Dates.py Date manipulation package by Tim Peters
|
||||
Range.py Example of a generator: re-implement built-in range()
|
||||
Rev.py Yield the reverse of a sequence
|
||||
Vec.py A simple vector class
|
||||
bitvec.py A bit-vector class by Jan-Hein B\"uhrman
|
||||
|
||||
(For straightforward examples of basic class features, such as use of
|
||||
methods and inheritance, see the library code.)
|
|
@ -1,93 +0,0 @@
|
|||
"""Example of a generator: re-implement the built-in range function
|
||||
without actually constructing the list of values.
|
||||
|
||||
OldStyleRange is coded in the way required to work in a 'for' loop before
|
||||
iterators were introduced into the language; using __getitem__ and __len__ .
|
||||
|
||||
"""
|
||||
def handleargs(arglist):
|
||||
"""Take list of arguments and extract/create proper start, stop, and step
|
||||
values and return in a tuple"""
|
||||
try:
|
||||
if len(arglist) == 1:
|
||||
return 0, int(arglist[0]), 1
|
||||
elif len(arglist) == 2:
|
||||
return int(arglist[0]), int(arglist[1]), 1
|
||||
elif len(arglist) == 3:
|
||||
if arglist[2] == 0:
|
||||
raise ValueError("step argument must not be zero")
|
||||
return tuple(int(x) for x in arglist)
|
||||
else:
|
||||
raise TypeError("range() accepts 1-3 arguments, given", len(arglist))
|
||||
except TypeError:
|
||||
raise TypeError("range() arguments must be numbers or strings "
|
||||
"representing numbers")
|
||||
|
||||
def genrange(*a):
|
||||
"""Function to implement 'range' as a generator"""
|
||||
start, stop, step = handleargs(a)
|
||||
value = start
|
||||
while value < stop:
|
||||
yield value
|
||||
value += step
|
||||
|
||||
class oldrange:
|
||||
"""Class implementing a range object.
|
||||
To the user the instances feel like immutable sequences
|
||||
(and you can't concatenate or slice them)
|
||||
|
||||
Done using the old way (pre-iterators; __len__ and __getitem__) to have an
|
||||
object be used by a 'for' loop.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *a):
|
||||
""" Initialize start, stop, and step values along with calculating the
|
||||
nubmer of values (what __len__ will return) in the range"""
|
||||
self.start, self.stop, self.step = handleargs(a)
|
||||
self.len = max(0, (self.stop - self.start) // self.step)
|
||||
|
||||
def __repr__(self):
|
||||
"""implement repr(x) which is also used by print"""
|
||||
return 'range(%r, %r, %r)' % (self.start, self.stop, self.step)
|
||||
|
||||
def __len__(self):
|
||||
"""implement len(x)"""
|
||||
return self.len
|
||||
|
||||
def __getitem__(self, i):
|
||||
"""implement x[i]"""
|
||||
if 0 <= i <= self.len:
|
||||
return self.start + self.step * i
|
||||
else:
|
||||
raise IndexError('range[i] index out of range')
|
||||
|
||||
|
||||
def test():
|
||||
import time, builtins
|
||||
#Just a quick sanity check
|
||||
correct_result = list(builtins.range(5, 100, 3))
|
||||
oldrange_result = list(oldrange(5, 100, 3))
|
||||
genrange_result = list(genrange(5, 100, 3))
|
||||
if genrange_result != correct_result or oldrange_result != correct_result:
|
||||
raise Exception("error in implementation:\ncorrect = %s"
|
||||
"\nold-style = %s\ngenerator = %s" %
|
||||
(correct_result, oldrange_result, genrange_result))
|
||||
print("Timings for range(1000):")
|
||||
t1 = time.time()
|
||||
for i in oldrange(1000):
|
||||
pass
|
||||
t2 = time.time()
|
||||
for i in genrange(1000):
|
||||
pass
|
||||
t3 = time.time()
|
||||
for i in builtins.range(1000):
|
||||
pass
|
||||
t4 = time.time()
|
||||
print(t2-t1, 'sec (old-style class)')
|
||||
print(t3-t2, 'sec (generator)')
|
||||
print(t4-t3, 'sec (built-in)')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
|
@ -1,93 +0,0 @@
|
|||
'''
|
||||
A class which presents the reverse of a sequence without duplicating it.
|
||||
From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>
|
||||
|
||||
It works on mutable or inmutable sequences.
|
||||
|
||||
>>> Rev('Hello World!')
|
||||
!dlroW olleH
|
||||
|
||||
The .forw is so you can use anonymous sequences in __init__, and still
|
||||
keep a reference the forward sequence. )
|
||||
If you give it a non-anonymous mutable sequence, the reverse sequence
|
||||
will track the updated values. ( but not reassignment! - another
|
||||
good reason to use anonymous values in creating the sequence to avoid
|
||||
confusion. Maybe it should be change to copy input sequence to break
|
||||
the connection completely ? )
|
||||
|
||||
>>> nnn = list(range(3))
|
||||
>>> rnn = Rev(nnn)
|
||||
>>> for n in rnn: n
|
||||
...
|
||||
2
|
||||
1
|
||||
0
|
||||
>>> for n in range(4, 6): nnn.append(n) # update nnn
|
||||
...
|
||||
>>> for n in rnn: n # prints reversed updated values
|
||||
...
|
||||
5
|
||||
4
|
||||
2
|
||||
1
|
||||
0
|
||||
>>> nnn = nnn[1:-1]
|
||||
>>> nnn
|
||||
[1, 2, 4]
|
||||
>>> for n in rnn: n # prints reversed values of old nnn
|
||||
...
|
||||
5
|
||||
4
|
||||
2
|
||||
1
|
||||
0
|
||||
|
||||
#
|
||||
>>> WH = Rev('Hello World!')
|
||||
>>> print(WH.forw, WH.back)
|
||||
Hello World! !dlroW olleH
|
||||
>>> nnn = Rev(list(range(1, 10)))
|
||||
>>> print(nnn.forw)
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> print(nnn.back)
|
||||
[9, 8, 7, 6, 5, 4, 3, 2, 1]
|
||||
|
||||
>>> Rev(nnn)
|
||||
<1, 2, 3, 4, 5, 6, 7, 8, 9>
|
||||
|
||||
'''
|
||||
|
||||
class Rev:
|
||||
def __init__(self, seq):
|
||||
self.forw = seq
|
||||
self.back = self
|
||||
|
||||
def __len__(self):
|
||||
return len(self.forw)
|
||||
|
||||
def __getitem__(self, j):
|
||||
return self.forw[-(j + 1)]
|
||||
|
||||
def __repr__(self):
|
||||
seq = self.forw
|
||||
if isinstance(seq, list):
|
||||
wrap = '[]'
|
||||
sep = ', '
|
||||
elif isinstance(seq, tuple):
|
||||
wrap = '()'
|
||||
sep = ', '
|
||||
elif isinstance(seq, str):
|
||||
wrap = ''
|
||||
sep = ''
|
||||
else:
|
||||
wrap = '<>'
|
||||
sep = ', '
|
||||
outstrs = [str(item) for item in self.back]
|
||||
return wrap[:1] + sep.join(outstrs) + wrap[-1:]
|
||||
|
||||
def _test():
|
||||
import doctest, Rev
|
||||
return doctest.testmod(Rev)
|
||||
|
||||
if __name__ == "__main__":
|
||||
_test()
|
|
@ -1,322 +0,0 @@
|
|||
#
|
||||
# this is a rather strict implementation of a bit vector class
|
||||
# it is accessed the same way as an array of python-ints, except
|
||||
# the value must be 0 or 1
|
||||
#
|
||||
|
||||
import sys; rprt = sys.stderr.write #for debugging
|
||||
|
||||
class error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def _check_value(value):
|
||||
if type(value) != type(0) or not 0 <= value < 2:
|
||||
raise error('bitvec() items must have int value 0 or 1')
|
||||
|
||||
|
||||
import math
|
||||
|
||||
def _compute_len(param):
|
||||
mant, l = math.frexp(float(param))
|
||||
bitmask = 1 << l
|
||||
if bitmask <= param:
|
||||
raise ValueError('(param, l) = %r' % ((param, l),))
|
||||
while l:
|
||||
bitmask = bitmask >> 1
|
||||
if param & bitmask:
|
||||
break
|
||||
l = l - 1
|
||||
return l
|
||||
|
||||
|
||||
def _check_key(len, key):
|
||||
if type(key) != type(0):
|
||||
raise TypeError('sequence subscript not int')
|
||||
if key < 0:
|
||||
key = key + len
|
||||
if not 0 <= key < len:
|
||||
raise IndexError('list index out of range')
|
||||
return key
|
||||
|
||||
def _check_slice(len, i, j):
|
||||
#the type is ok, Python already checked that
|
||||
i, j = max(i, 0), min(len, j)
|
||||
if i > j:
|
||||
i = j
|
||||
return i, j
|
||||
|
||||
|
||||
class BitVec:
|
||||
|
||||
def __init__(self, *params):
|
||||
self._data = 0
|
||||
self._len = 0
|
||||
if not len(params):
|
||||
pass
|
||||
elif len(params) == 1:
|
||||
param, = params
|
||||
if type(param) == type([]):
|
||||
value = 0
|
||||
bit_mask = 1
|
||||
for item in param:
|
||||
# strict check
|
||||
#_check_value(item)
|
||||
if item:
|
||||
value = value | bit_mask
|
||||
bit_mask = bit_mask << 1
|
||||
self._data = value
|
||||
self._len = len(param)
|
||||
elif type(param) == type(0):
|
||||
if param < 0:
|
||||
raise error('bitvec() can\'t handle negative longs')
|
||||
self._data = param
|
||||
self._len = _compute_len(param)
|
||||
else:
|
||||
raise error('bitvec() requires array or long parameter')
|
||||
elif len(params) == 2:
|
||||
param, length = params
|
||||
if type(param) == type(0):
|
||||
if param < 0:
|
||||
raise error('can\'t handle negative longs')
|
||||
self._data = param
|
||||
if type(length) != type(0):
|
||||
raise error('bitvec()\'s 2nd parameter must be int')
|
||||
computed_length = _compute_len(param)
|
||||
if computed_length > length:
|
||||
print('warning: bitvec() value is longer than the length indicates, truncating value')
|
||||
self._data = self._data & \
|
||||
((1 << length) - 1)
|
||||
self._len = length
|
||||
else:
|
||||
raise error('bitvec() requires array or long parameter')
|
||||
else:
|
||||
raise error('bitvec() requires 0 -- 2 parameter(s)')
|
||||
|
||||
|
||||
def append(self, item):
|
||||
#_check_value(item)
|
||||
#self[self._len:self._len] = [item]
|
||||
self[self._len:self._len] = \
|
||||
BitVec(int(not not item), 1)
|
||||
|
||||
|
||||
def count(self, value):
|
||||
#_check_value(value)
|
||||
if value:
|
||||
data = self._data
|
||||
else:
|
||||
data = (~self)._data
|
||||
count = 0
|
||||
while data:
|
||||
data, count = data >> 1, count + (data & 1 != 0)
|
||||
return count
|
||||
|
||||
|
||||
def index(self, value):
|
||||
#_check_value(value):
|
||||
if value:
|
||||
data = self._data
|
||||
else:
|
||||
data = (~self)._data
|
||||
index = 0
|
||||
if not data:
|
||||
raise ValueError('list.index(x): x not in list')
|
||||
while not (data & 1):
|
||||
data, index = data >> 1, index + 1
|
||||
return index
|
||||
|
||||
|
||||
def insert(self, index, item):
|
||||
#_check_value(item)
|
||||
#self[index:index] = [item]
|
||||
self[index:index] = BitVec(int(not not item), 1)
|
||||
|
||||
|
||||
def remove(self, value):
|
||||
del self[self.index(value)]
|
||||
|
||||
|
||||
def reverse(self):
|
||||
#ouch, this one is expensive!
|
||||
#for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i]
|
||||
data, result = self._data, 0
|
||||
for i in range(self._len):
|
||||
if not data:
|
||||
result = result << (self._len - i)
|
||||
break
|
||||
result, data = (result << 1) | (data & 1), data >> 1
|
||||
self._data = result
|
||||
|
||||
|
||||
def sort(self):
|
||||
c = self.count(1)
|
||||
self._data = ((1 << c) - 1) << (self._len - c)
|
||||
|
||||
|
||||
def copy(self):
|
||||
return BitVec(self._data, self._len)
|
||||
|
||||
|
||||
def seq(self):
|
||||
result = []
|
||||
for i in self:
|
||||
result.append(i)
|
||||
return result
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
##rprt('<bitvec class instance object>.' + '__repr__()\n')
|
||||
return 'bitvec(%r, %r)' % (self._data, self._len)
|
||||
|
||||
def __cmp__(self, other, *rest):
|
||||
#rprt('%r.__cmp__%r\n' % (self, (other,) + rest))
|
||||
if type(other) != type(self):
|
||||
other = bitvec(other, *rest)
|
||||
#expensive solution... recursive binary, with slicing
|
||||
length = self._len
|
||||
if length == 0 or other._len == 0:
|
||||
return cmp(length, other._len)
|
||||
if length != other._len:
|
||||
min_length = min(length, other._len)
|
||||
return cmp(self[:min_length], other[:min_length]) or \
|
||||
cmp(self[min_length:], other[min_length:])
|
||||
#the lengths are the same now...
|
||||
if self._data == other._data:
|
||||
return 0
|
||||
if length == 1:
|
||||
return cmp(self[0], other[0])
|
||||
else:
|
||||
length = length >> 1
|
||||
return cmp(self[:length], other[:length]) or \
|
||||
cmp(self[length:], other[length:])
|
||||
|
||||
|
||||
def __len__(self):
|
||||
#rprt('%r.__len__()\n' % (self,))
|
||||
return self._len
|
||||
|
||||
def __getitem__(self, key):
|
||||
#rprt('%r.__getitem__(%r)\n' % (self, key))
|
||||
key = _check_key(self._len, key)
|
||||
return self._data & (1 << key) != 0
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
#rprt('%r.__setitem__(%r, %r)\n' % (self, key, value))
|
||||
key = _check_key(self._len, key)
|
||||
#_check_value(value)
|
||||
if value:
|
||||
self._data = self._data | (1 << key)
|
||||
else:
|
||||
self._data = self._data & ~(1 << key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
#rprt('%r.__delitem__(%r)\n' % (self, key))
|
||||
key = _check_key(self._len, key)
|
||||
#el cheapo solution...
|
||||
self._data = self[:key]._data | self[key+1:]._data >> key
|
||||
self._len = self._len - 1
|
||||
|
||||
def __getslice__(self, i, j):
|
||||
#rprt('%r.__getslice__(%r, %r)\n' % (self, i, j))
|
||||
i, j = _check_slice(self._len, i, j)
|
||||
if i >= j:
|
||||
return BitVec(0, 0)
|
||||
if i:
|
||||
ndata = self._data >> i
|
||||
else:
|
||||
ndata = self._data
|
||||
nlength = j - i
|
||||
if j != self._len:
|
||||
#we'll have to invent faster variants here
|
||||
#e.g. mod_2exp
|
||||
ndata = ndata & ((1 << nlength) - 1)
|
||||
return BitVec(ndata, nlength)
|
||||
|
||||
def __setslice__(self, i, j, sequence, *rest):
|
||||
#rprt('%s.__setslice__%r\n' % (self, (i, j, sequence) + rest))
|
||||
i, j = _check_slice(self._len, i, j)
|
||||
if type(sequence) != type(self):
|
||||
sequence = bitvec(sequence, *rest)
|
||||
#sequence is now of our own type
|
||||
ls_part = self[:i]
|
||||
ms_part = self[j:]
|
||||
self._data = ls_part._data | \
|
||||
((sequence._data | \
|
||||
(ms_part._data << sequence._len)) << ls_part._len)
|
||||
self._len = self._len - j + i + sequence._len
|
||||
|
||||
def __delslice__(self, i, j):
|
||||
#rprt('%r.__delslice__(%r, %r)\n' % (self, i, j))
|
||||
i, j = _check_slice(self._len, i, j)
|
||||
if i == 0 and j == self._len:
|
||||
self._data, self._len = 0, 0
|
||||
elif i < j:
|
||||
self._data = self[:i]._data | (self[j:]._data >> i)
|
||||
self._len = self._len - j + i
|
||||
|
||||
def __add__(self, other):
|
||||
#rprt('%r.__add__(%r)\n' % (self, other))
|
||||
retval = self.copy()
|
||||
retval[self._len:self._len] = other
|
||||
return retval
|
||||
|
||||
def __mul__(self, multiplier):
|
||||
#rprt('%r.__mul__(%r)\n' % (self, multiplier))
|
||||
if type(multiplier) != type(0):
|
||||
raise TypeError('sequence subscript not int')
|
||||
if multiplier <= 0:
|
||||
return BitVec(0, 0)
|
||||
elif multiplier == 1:
|
||||
return self.copy()
|
||||
#handle special cases all 0 or all 1...
|
||||
if self._data == 0:
|
||||
return BitVec(0, self._len * multiplier)
|
||||
elif (~self)._data == 0:
|
||||
return ~BitVec(0, self._len * multiplier)
|
||||
#otherwise el cheapo again...
|
||||
retval = BitVec(0, 0)
|
||||
while multiplier:
|
||||
retval, multiplier = retval + self, multiplier - 1
|
||||
return retval
|
||||
|
||||
def __and__(self, otherseq, *rest):
|
||||
#rprt('%r.__and__%r\n' % (self, (otherseq,) + rest))
|
||||
if type(otherseq) != type(self):
|
||||
otherseq = bitvec(otherseq, *rest)
|
||||
#sequence is now of our own type
|
||||
return BitVec(self._data & otherseq._data, \
|
||||
min(self._len, otherseq._len))
|
||||
|
||||
|
||||
def __xor__(self, otherseq, *rest):
|
||||
#rprt('%r.__xor__%r\n' % (self, (otherseq,) + rest))
|
||||
if type(otherseq) != type(self):
|
||||
otherseq = bitvec(otherseq, *rest)
|
||||
#sequence is now of our own type
|
||||
return BitVec(self._data ^ otherseq._data, \
|
||||
max(self._len, otherseq._len))
|
||||
|
||||
|
||||
def __or__(self, otherseq, *rest):
|
||||
#rprt('%r.__or__%r\n' % (self, (otherseq,) + rest))
|
||||
if type(otherseq) != type(self):
|
||||
otherseq = bitvec(otherseq, *rest)
|
||||
#sequence is now of our own type
|
||||
return BitVec(self._data | otherseq._data, \
|
||||
max(self._len, otherseq._len))
|
||||
|
||||
|
||||
def __invert__(self):
|
||||
#rprt('%r.__invert__()\n' % (self,))
|
||||
return BitVec(~self._data & ((1 << self._len) - 1), \
|
||||
self._len)
|
||||
|
||||
def __int__(self):
|
||||
return int(self._data)
|
||||
|
||||
def __float__(self):
|
||||
return float(self._data)
|
||||
|
||||
|
||||
bitvec = BitVec
|
|
@ -1,25 +0,0 @@
|
|||
This is a collection of demos and tests for the curses module.
|
||||
|
||||
ncurses demos
|
||||
=============
|
||||
|
||||
These demos are converted from the C versions in the ncurses
|
||||
distribution, and were contributed by Thomas Gellekum <tg@FreeBSD.org>
|
||||
I didn't strive for a `pythonic' style, but bluntly copied the
|
||||
originals. I won't attempt to `beautify' the program anytime soon, but
|
||||
I wouldn't mind someone else making an effort in that direction, of
|
||||
course.
|
||||
|
||||
ncurses.py -- currently only a panels demo
|
||||
rain.py -- raindrops keep falling on my desktop
|
||||
tclock.py -- ASCII clock, by Howard Jones
|
||||
xmas.py -- I'm dreaming of an ASCII christmas
|
||||
|
||||
Please submit bugfixes and new contributions to the Python bug tracker.
|
||||
|
||||
|
||||
Other demos
|
||||
===========
|
||||
|
||||
life.py -- Simple game of Life
|
||||
repeat.py -- Repeatedly execute a shell command (like watch(1))
|
|
@ -1,80 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
"""repeat [-i SECONDS] <shell-command>
|
||||
|
||||
This simple program repeatedly (at 1-second intervals) executes the
|
||||
shell command given on the command line and displays the output (or as
|
||||
much of it as fits on the screen). It uses curses to paint each new
|
||||
output on top of the old output, so that if nothing changes, the
|
||||
screen doesn't change. This is handy to watch for changes in e.g. a
|
||||
directory or process listing.
|
||||
|
||||
The -i option lets you override the sleep time between executions.
|
||||
|
||||
To end, hit Control-C.
|
||||
"""
|
||||
|
||||
# Author: Guido van Rossum
|
||||
|
||||
# Disclaimer: there's a Linux program named 'watch' that does the same
|
||||
# thing. Honestly, I didn't know of its existence when I wrote this!
|
||||
|
||||
# To do: add features until it has the same functionality as watch(1);
|
||||
# then compare code size and development time.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import curses
|
||||
import getopt
|
||||
|
||||
def main():
|
||||
interval = 1.0
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hi:")
|
||||
except getopt.error as err:
|
||||
print(err, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
if not args:
|
||||
print(__doc__)
|
||||
sys.exit(0)
|
||||
for opt, arg in opts:
|
||||
if opt == "-i":
|
||||
interval = float(arg)
|
||||
if opt == "-h":
|
||||
print(__doc__)
|
||||
sys.exit(0)
|
||||
cmd = " ".join(args)
|
||||
cmd_really = cmd + " 2>&1"
|
||||
p = os.popen(cmd_really, "r")
|
||||
text = p.read()
|
||||
sts = p.close()
|
||||
text = addsts(interval, cmd, text, sts)
|
||||
w = curses.initscr()
|
||||
try:
|
||||
while True:
|
||||
w.erase()
|
||||
try:
|
||||
w.addstr(text)
|
||||
except curses.error:
|
||||
pass
|
||||
w.refresh()
|
||||
time.sleep(interval)
|
||||
p = os.popen(cmd_really, "r")
|
||||
text = p.read()
|
||||
sts = p.close()
|
||||
text = addsts(interval, cmd, text, sts)
|
||||
finally:
|
||||
curses.endwin()
|
||||
|
||||
def addsts(interval, cmd, text, sts):
|
||||
now = time.strftime("%H:%M:%S")
|
||||
text = "%s, every %g sec: %s\n%s" % (now, interval, cmd, text)
|
||||
if sts:
|
||||
msg = "Exit status: %d; signal: %d" % (sts>>8, sts&0xFF)
|
||||
if text and not text.endswith("\n"):
|
||||
msg = "\n" + msg
|
||||
text += msg
|
||||
return text
|
||||
|
||||
main()
|
|
@ -1,57 +0,0 @@
|
|||
# Makefile for embedded Python use demo.
|
||||
# (This version originally written on Red Hat Linux 6.1;
|
||||
# edit lines marked with XXX.)
|
||||
|
||||
# XXX The compiler you are using
|
||||
CC= gcc
|
||||
|
||||
# XXX Top of the build tree and source tree
|
||||
blddir= ../..
|
||||
srcdir= ../..
|
||||
|
||||
# Python version
|
||||
VERSION= 3.2
|
||||
|
||||
# Compiler flags
|
||||
OPT= -g
|
||||
INCLUDES= -I$(srcdir)/Include -I$(blddir)
|
||||
CFLAGS= $(OPT)
|
||||
CPPFLAGS= $(INCLUDES)
|
||||
|
||||
# The Python library
|
||||
LIBPYTHON= $(blddir)/libpython$(VERSION).a
|
||||
|
||||
# XXX edit LIBS (in particular) to match $(blddir)/Makefile
|
||||
LIBS= -lnsl -ldl -lreadline -lieee -lpthread -lutil
|
||||
LDFLAGS= -Xlinker -export-dynamic
|
||||
SYSLIBS= -lm
|
||||
MODLIBS=
|
||||
ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS)
|
||||
|
||||
# Build the demo applications
|
||||
all: demo loop importexc
|
||||
demo: demo.o
|
||||
$(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo
|
||||
|
||||
loop: loop.o
|
||||
$(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop
|
||||
|
||||
importexc: importexc.o
|
||||
$(CC) $(LDFLAGS) importexc.o $(ALLLIBS) -o importexc
|
||||
|
||||
# Administrative targets
|
||||
|
||||
test: demo
|
||||
./demo
|
||||
|
||||
COMMAND="print 'hello world'"
|
||||
looptest: loop
|
||||
./loop $(COMMAND)
|
||||
|
||||
clean:
|
||||
-rm -f *.o core
|
||||
|
||||
clobber: clean
|
||||
-rm -f *~ @* '#'* demo loop importexc
|
||||
|
||||
realclean: clobber
|
|
@ -1,19 +0,0 @@
|
|||
This directory show how to embed the Python interpreter in your own
|
||||
application. The file demo.c shows you all that is needed in your C
|
||||
code.
|
||||
|
||||
To build it, you may have to edit the Makefile:
|
||||
|
||||
1) set blddir to the directory where you built Python, if it isn't in
|
||||
the source directory (../..)
|
||||
|
||||
2) change the variables that together define the list of libraries
|
||||
(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in
|
||||
$(blddir)/Modules/Makefile
|
||||
|
||||
An additional test program, loop.c, is used to experiment with memory
|
||||
leakage caused by repeated initialization and finalization of the
|
||||
interpreter. It can be build by saying "make loop" and tested with
|
||||
"make looptest". Command line usage is "./loop <python-command>",
|
||||
e.g. "./loop 'print 2+2'" should spit out an endless number of lines
|
||||
containing the number 4.
|
|
@ -1,89 +0,0 @@
|
|||
/* Example of embedding Python in another program */
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
PyObject* PyInit_xyzzy(void); /* Forward */
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
/* Ignore passed-in argc/argv. If desired, conversion
|
||||
should use mbstowcs to convert them. */
|
||||
wchar_t *args[] = {L"embed", L"hello", 0};
|
||||
|
||||
/* Pass argv[0] to the Python interpreter */
|
||||
Py_SetProgramName(args[0]);
|
||||
|
||||
/* Add a static module */
|
||||
PyImport_AppendInittab("xyzzy", PyInit_xyzzy);
|
||||
|
||||
/* Initialize the Python interpreter. Required. */
|
||||
Py_Initialize();
|
||||
|
||||
/* Define sys.argv. It is up to the application if you
|
||||
want this; you can also leave it undefined (since the Python
|
||||
code is generally not a main program it has no business
|
||||
touching sys.argv...)
|
||||
|
||||
If the third argument is true, sys.path is modified to include
|
||||
either the directory containing the script named by argv[0], or
|
||||
the current working directory. This can be risky; if you run
|
||||
an application embedding Python in a directory controlled by
|
||||
someone else, attackers could put a Trojan-horse module in the
|
||||
directory (say, a file named os.py) that your application would
|
||||
then import and run.
|
||||
*/
|
||||
PySys_SetArgvEx(2, args, 0);
|
||||
|
||||
/* Do some application specific code */
|
||||
printf("Hello, brave new world\n\n");
|
||||
|
||||
/* Execute some Python statements (in module __main__) */
|
||||
PyRun_SimpleString("import sys\n");
|
||||
PyRun_SimpleString("print(sys.builtin_module_names)\n");
|
||||
PyRun_SimpleString("print(sys.modules.keys())\n");
|
||||
PyRun_SimpleString("print(sys.executable)\n");
|
||||
PyRun_SimpleString("print(sys.argv)\n");
|
||||
|
||||
/* Note that you can call any public function of the Python
|
||||
interpreter here, e.g. call_object(). */
|
||||
|
||||
/* Some more application specific code */
|
||||
printf("\nGoodbye, cruel world\n");
|
||||
|
||||
/* Exit, cleaning up the interpreter */
|
||||
Py_Exit(0);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* A static module */
|
||||
|
||||
/* 'self' is not used */
|
||||
static PyObject *
|
||||
xyzzy_foo(PyObject *self, PyObject* args)
|
||||
{
|
||||
return PyLong_FromLong(42L);
|
||||
}
|
||||
|
||||
static PyMethodDef xyzzy_methods[] = {
|
||||
{"foo", xyzzy_foo, METH_NOARGS,
|
||||
"Return the meaning of everything."},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static struct PyModuleDef xyzzymodule = {
|
||||
{}, /* m_base */
|
||||
"xyzzy", /* m_name */
|
||||
0, /* m_doc */
|
||||
0, /* m_size */
|
||||
xyzzy_methods, /* m_methods */
|
||||
0, /* m_reload */
|
||||
0, /* m_traverse */
|
||||
0, /* m_clear */
|
||||
0, /* m_free */
|
||||
};
|
||||
|
||||
PyObject*
|
||||
PyInit_xyzzy(void)
|
||||
{
|
||||
return PyModule_Create(&xyzzymodule);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#include <Python.h>
|
||||
|
||||
#if 0
|
||||
char* cmd = "import codecs, encodings.utf_8, types; print(types)";
|
||||
#else
|
||||
char* cmd = "import types; print(types)";
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Initialize interpreter\n");
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
PyRun_SimpleString(cmd);
|
||||
Py_EndInterpreter(PyThreadState_Get());
|
||||
|
||||
printf("\nInitialize subinterpreter\n");
|
||||
Py_NewInterpreter();
|
||||
PyRun_SimpleString(cmd);
|
||||
Py_Finalize();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* Simple program that repeatedly calls Py_Initialize(), does something, and
|
||||
then calls Py_Finalize(). This should help finding leaks related to
|
||||
initialization. */
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int count = -1;
|
||||
char *command;
|
||||
|
||||
if (argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "usage: loop <python-command> [count]\n");
|
||||
exit(2);
|
||||
}
|
||||
command = argv[1];
|
||||
|
||||
if (argc == 3) {
|
||||
count = atoi(argv[2]);
|
||||
}
|
||||
|
||||
Py_SetProgramName(L"loop");
|
||||
|
||||
/* uncomment this if you don't want to load site.py */
|
||||
/* Py_NoSiteFlag = 1; */
|
||||
|
||||
while (count == -1 || --count >= 0 ) {
|
||||
Py_Initialize();
|
||||
PyRun_SimpleString(command);
|
||||
Py_Finalize();
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
"""Enumeration metaclass."""
|
||||
|
||||
class EnumMetaclass(type):
|
||||
"""Metaclass for enumeration.
|
||||
|
||||
To define your own enumeration, do something like
|
||||
|
||||
class Color(Enum):
|
||||
red = 1
|
||||
green = 2
|
||||
blue = 3
|
||||
|
||||
Now, Color.red, Color.green and Color.blue behave totally
|
||||
different: they are enumerated values, not integers.
|
||||
|
||||
Enumerations cannot be instantiated; however they can be
|
||||
subclassed.
|
||||
"""
|
||||
|
||||
def __init__(cls, name, bases, dict):
|
||||
super(EnumMetaclass, cls).__init__(name, bases, dict)
|
||||
cls._members = []
|
||||
for attr in dict.keys():
|
||||
if not (attr.startswith('__') and attr.endswith('__')):
|
||||
enumval = EnumInstance(name, attr, dict[attr])
|
||||
setattr(cls, attr, enumval)
|
||||
cls._members.append(attr)
|
||||
|
||||
def __getattr__(cls, name):
|
||||
if name == "__members__":
|
||||
return cls._members
|
||||
raise AttributeError(name)
|
||||
|
||||
def __repr__(cls):
|
||||
s1 = s2 = ""
|
||||
enumbases = [base.__name__ for base in cls.__bases__
|
||||
if isinstance(base, EnumMetaclass) and not base is Enum]
|
||||
if enumbases:
|
||||
s1 = "(%s)" % ", ".join(enumbases)
|
||||
enumvalues = ["%s: %d" % (val, getattr(cls, val))
|
||||
for val in cls._members]
|
||||
if enumvalues:
|
||||
s2 = ": {%s}" % ", ".join(enumvalues)
|
||||
return "%s%s%s" % (cls.__name__, s1, s2)
|
||||
|
||||
class FullEnumMetaclass(EnumMetaclass):
|
||||
"""Metaclass for full enumerations.
|
||||
|
||||
A full enumeration displays all the values defined in base classes.
|
||||
"""
|
||||
|
||||
def __init__(cls, name, bases, dict):
|
||||
super(FullEnumMetaclass, cls).__init__(name, bases, dict)
|
||||
for obj in cls.__mro__:
|
||||
if isinstance(obj, EnumMetaclass):
|
||||
for attr in obj._members:
|
||||
# XXX inefficient
|
||||
if not attr in cls._members:
|
||||
cls._members.append(attr)
|
||||
|
||||
class EnumInstance(int):
|
||||
"""Class to represent an enumeration value.
|
||||
|
||||
EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
|
||||
like the integer 12 when compared, but doesn't support arithmetic.
|
||||
|
||||
XXX Should it record the actual enumeration rather than just its
|
||||
name?
|
||||
"""
|
||||
|
||||
def __new__(cls, classname, enumname, value):
|
||||
return int.__new__(cls, value)
|
||||
|
||||
def __init__(self, classname, enumname, value):
|
||||
self.__classname = classname
|
||||
self.__enumname = enumname
|
||||
|
||||
def __repr__(self):
|
||||
return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname,
|
||||
self)
|
||||
|
||||
def __str__(self):
|
||||
return "%s.%s" % (self.__classname, self.__enumname)
|
||||
|
||||
class Enum(metaclass=EnumMetaclass):
|
||||
pass
|
||||
|
||||
class FullEnum(metaclass=FullEnumMetaclass):
|
||||
pass
|
||||
|
||||
def _test():
|
||||
|
||||
class Color(Enum):
|
||||
red = 1
|
||||
green = 2
|
||||
blue = 3
|
||||
|
||||
print(Color.red)
|
||||
|
||||
print(repr(Color.red))
|
||||
print(Color.red == Color.red)
|
||||
print(Color.red == Color.blue)
|
||||
print(Color.red == 1)
|
||||
print(Color.red == 2)
|
||||
|
||||
class ExtendedColor(Color):
|
||||
white = 0
|
||||
orange = 4
|
||||
yellow = 5
|
||||
purple = 6
|
||||
black = 7
|
||||
|
||||
print(ExtendedColor.orange)
|
||||
print(ExtendedColor.red)
|
||||
|
||||
print(Color.red == ExtendedColor.red)
|
||||
|
||||
class OtherColor(Enum):
|
||||
white = 4
|
||||
blue = 5
|
||||
|
||||
class MergedColor(Color, OtherColor):
|
||||
pass
|
||||
|
||||
print(MergedColor.red)
|
||||
print(MergedColor.white)
|
||||
|
||||
print(Color)
|
||||
print(ExtendedColor)
|
||||
print(OtherColor)
|
||||
print(MergedColor)
|
||||
|
||||
def _test2():
|
||||
|
||||
class Color(FullEnum):
|
||||
red = 1
|
||||
green = 2
|
||||
blue = 3
|
||||
|
||||
print(Color.red)
|
||||
|
||||
print(repr(Color.red))
|
||||
print(Color.red == Color.red)
|
||||
print(Color.red == Color.blue)
|
||||
print(Color.red == 1)
|
||||
print(Color.red == 2)
|
||||
|
||||
class ExtendedColor(Color):
|
||||
white = 0
|
||||
orange = 4
|
||||
yellow = 5
|
||||
purple = 6
|
||||
black = 7
|
||||
|
||||
print(ExtendedColor.orange)
|
||||
print(ExtendedColor.red)
|
||||
|
||||
print(Color.red == ExtendedColor.red)
|
||||
|
||||
class OtherColor(FullEnum):
|
||||
white = 4
|
||||
blue = 5
|
||||
|
||||
class MergedColor(Color, OtherColor):
|
||||
pass
|
||||
|
||||
print(MergedColor.red)
|
||||
print(MergedColor.white)
|
||||
|
||||
print(Color)
|
||||
print(ExtendedColor)
|
||||
print(OtherColor)
|
||||
print(MergedColor)
|
||||
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
_test2()
|
|
@ -1,22 +0,0 @@
|
|||
This directory contains a collection of executable Python scripts.
|
||||
|
||||
See also the Tools/scripts directory!
|
||||
|
||||
beer.py Print the classic 'bottles of beer' list
|
||||
eqfix.py Fix .py files to use the correct equality test operator
|
||||
fact.py Factorize numbers
|
||||
find-uname.py Search for Unicode characters using regexps
|
||||
from.py Summarize mailbox
|
||||
lpwatch.py Watch BSD line printer queues
|
||||
makedir.py Like mkdir -p
|
||||
markov.py Markov chain simulation of words or characters
|
||||
mboxconvert.py Convert MH or MMDF mailboxes to unix mailbox format
|
||||
morse.py Produce morse code (as an AIFF file)
|
||||
newslist.py List all newsgroups on a NNTP server as HTML pages
|
||||
pi.py Print all digits of pi -- given enough time and memory
|
||||
pp.py Emulate some Perl command line options
|
||||
primes.py Print prime numbers
|
||||
queens.py Dijkstra's solution to Wirth's "N Queens problem"
|
||||
script.py Equivalent to BSD script(1) -- by Steen Lumholt
|
||||
unbirthday.py Print unbirthday count
|
||||
update.py Update a bunch of files according to a script
|
|
@ -1,49 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Factorize numbers.
|
||||
# The algorithm is not efficient, but easy to understand.
|
||||
# If there are large factors, it will take forever to find them,
|
||||
# because we try all odd numbers between 3 and sqrt(n)...
|
||||
|
||||
import sys
|
||||
from math import sqrt
|
||||
|
||||
def fact(n):
|
||||
if n < 1:
|
||||
raise ValueError('fact() argument should be >= 1')
|
||||
if n == 1:
|
||||
return [] # special case
|
||||
res = []
|
||||
# Treat even factors special, so we can use i += 2 later
|
||||
while n % 2 == 0:
|
||||
res.append(2)
|
||||
n //= 2
|
||||
# Try odd numbers up to sqrt(n)
|
||||
limit = sqrt(n+1)
|
||||
i = 3
|
||||
while i <= limit:
|
||||
if n % i == 0:
|
||||
res.append(i)
|
||||
n //= i
|
||||
limit = sqrt(n+1)
|
||||
else:
|
||||
i += 2
|
||||
if n != 1:
|
||||
res.append(n)
|
||||
return res
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
source = sys.argv[1:]
|
||||
else:
|
||||
source = iter(input, '')
|
||||
for arg in source:
|
||||
try:
|
||||
n = int(arg)
|
||||
except ValueError:
|
||||
print(arg, 'is not an integer')
|
||||
else:
|
||||
print(n, fact(n))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,106 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Calculate your unbirthday count (see Alice in Wonderland).
|
||||
# This is defined as the number of days from your birth until today
|
||||
# that weren't your birthday. (The day you were born is not counted).
|
||||
# Leap years make it interesting.
|
||||
|
||||
import sys
|
||||
import time
|
||||
import calendar
|
||||
|
||||
def main():
|
||||
if sys.argv[1:]:
|
||||
year = int(sys.argv[1])
|
||||
else:
|
||||
year = int(input('In which year were you born? '))
|
||||
if 0 <= year < 100:
|
||||
print("I'll assume that by", year, end=' ')
|
||||
year = year + 1900
|
||||
print('you mean', year, 'and not the early Christian era')
|
||||
elif not (1850 <= year <= time.localtime()[0]):
|
||||
print("It's hard to believe you were born in", year)
|
||||
return
|
||||
|
||||
if sys.argv[2:]:
|
||||
month = int(sys.argv[2])
|
||||
else:
|
||||
month = int(input('And in which month? (1-12) '))
|
||||
if not (1 <= month <= 12):
|
||||
print('There is no month numbered', month)
|
||||
return
|
||||
|
||||
if sys.argv[3:]:
|
||||
day = int(sys.argv[3])
|
||||
else:
|
||||
day = int(input('And on what day of that month? (1-31) '))
|
||||
if month == 2 and calendar.isleap(year):
|
||||
maxday = 29
|
||||
else:
|
||||
maxday = calendar.mdays[month]
|
||||
if not (1 <= day <= maxday):
|
||||
print('There are no', day, 'days in that month!')
|
||||
return
|
||||
|
||||
bdaytuple = (year, month, day)
|
||||
bdaydate = mkdate(bdaytuple)
|
||||
print('You were born on', format(bdaytuple))
|
||||
|
||||
todaytuple = time.localtime()[:3]
|
||||
todaydate = mkdate(todaytuple)
|
||||
print('Today is', format(todaytuple))
|
||||
|
||||
if bdaytuple > todaytuple:
|
||||
print('You are a time traveler. Go back to the future!')
|
||||
return
|
||||
|
||||
if bdaytuple == todaytuple:
|
||||
print('You were born today. Have a nice life!')
|
||||
return
|
||||
|
||||
days = todaydate - bdaydate
|
||||
print('You have lived', days, 'days')
|
||||
|
||||
age = 0
|
||||
for y in range(year, todaytuple[0] + 1):
|
||||
if bdaytuple < (y, month, day) <= todaytuple:
|
||||
age = age + 1
|
||||
|
||||
print('You are', age, 'years old')
|
||||
|
||||
if todaytuple[1:] == bdaytuple[1:]:
|
||||
print('Congratulations! Today is your', nth(age), 'birthday')
|
||||
print('Yesterday was your', end=' ')
|
||||
else:
|
||||
print('Today is your', end=' ')
|
||||
print(nth(days - age), 'unbirthday')
|
||||
|
||||
def format(date):
|
||||
(year, month, day) = date
|
||||
return '%d %s %d' % (day, calendar.month_name[month], year)
|
||||
|
||||
def nth(n):
|
||||
if n == 1: return '1st'
|
||||
if n == 2: return '2nd'
|
||||
if n == 3: return '3rd'
|
||||
return '%dth' % n
|
||||
|
||||
def mkdate(date):
|
||||
# January 1st, in 0 A.D. is arbitrarily defined to be day 1,
|
||||
# even though that day never actually existed and the calendar
|
||||
# was different then...
|
||||
(year, month, day) = date
|
||||
days = year*365 # years, roughly
|
||||
days = days + (year+3)//4 # plus leap years, roughly
|
||||
days = days - (year+99)//100 # minus non-leap years every century
|
||||
days = days + (year+399)//400 # plus leap years every 4 centirues
|
||||
for i in range(1, month):
|
||||
if i == 2 and calendar.isleap(year):
|
||||
days = days + 29
|
||||
else:
|
||||
days = days + calendar.mdays[i]
|
||||
days = days + day
|
||||
return days
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,14 +0,0 @@
|
|||
This directory contains some demonstrations of the socket module:
|
||||
|
||||
broadcast.py Broadcast the time to radio.py.
|
||||
echosvr.py About the simplest TCP server possible.
|
||||
finger.py Client for the 'finger' protocol.
|
||||
ftp.py A very simple ftp client.
|
||||
gopher.py A simple gopher client.
|
||||
mcast.py IPv4/v6 multicast example
|
||||
radio.py Receive time broadcasts from broadcast.py.
|
||||
telnet.py Client for the 'telnet' protocol.
|
||||
throughput.py Client and server to measure TCP throughput.
|
||||
unixclient.py Unix socket example, client side
|
||||
unixserver.py Unix socket example, server side
|
||||
udpecho.py Client and server for the UDP echo protocol.
|
|
@ -1,15 +0,0 @@
|
|||
# Send UDP broadcast packets
|
||||
|
||||
MYPORT = 50000
|
||||
|
||||
import sys, time
|
||||
from socket import *
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind(('', 0))
|
||||
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
|
||||
while 1:
|
||||
data = repr(time.time()) + '\n'
|
||||
s.sendto(data, ('<broadcast>', MYPORT))
|
||||
time.sleep(2)
|
|
@ -1,31 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Python implementation of an 'echo' tcp server: echo all data it receives.
|
||||
#
|
||||
# This is the simplest possible server, servicing a single request only.
|
||||
|
||||
import sys
|
||||
from socket import *
|
||||
|
||||
# The standard echo port isn't very useful, it requires root permissions!
|
||||
# ECHO_PORT = 7
|
||||
ECHO_PORT = 50000 + 7
|
||||
BUFSIZE = 1024
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
port = int(eval(sys.argv[1]))
|
||||
else:
|
||||
port = ECHO_PORT
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.bind(('', port))
|
||||
s.listen(1)
|
||||
conn, (remotehost, remoteport) = s.accept()
|
||||
print('connected by', remotehost, remoteport)
|
||||
while 1:
|
||||
data = conn.recv(BUFSIZE)
|
||||
if not data:
|
||||
break
|
||||
conn.send(data)
|
||||
|
||||
main()
|
|
@ -1,58 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Python interface to the Internet finger daemon.
|
||||
#
|
||||
# Usage: finger [options] [user][@host] ...
|
||||
#
|
||||
# If no host is given, the finger daemon on the local host is contacted.
|
||||
# Options are passed uninterpreted to the finger daemon!
|
||||
|
||||
|
||||
import sys, string
|
||||
from socket import *
|
||||
|
||||
|
||||
# Hardcode the number of the finger port here.
|
||||
# It's not likely to change soon...
|
||||
#
|
||||
FINGER_PORT = 79
|
||||
|
||||
|
||||
# Function to do one remote finger invocation.
|
||||
# Output goes directly to stdout (although this can be changed).
|
||||
#
|
||||
def finger(host, args):
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.connect((host, FINGER_PORT))
|
||||
s.send(args + '\n')
|
||||
while 1:
|
||||
buf = s.recv(1024)
|
||||
if not buf: break
|
||||
sys.stdout.write(buf)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
# Main function: argument parsing.
|
||||
#
|
||||
def main():
|
||||
options = ''
|
||||
i = 1
|
||||
while i < len(sys.argv) and sys.argv[i][:1] == '-':
|
||||
options = options + sys.argv[i] + ' '
|
||||
i = i+1
|
||||
args = sys.argv[i:]
|
||||
if not args:
|
||||
args = ['']
|
||||
for arg in args:
|
||||
if '@' in arg:
|
||||
at = string.index(arg, '@')
|
||||
host = arg[at+1:]
|
||||
arg = arg[:at]
|
||||
else:
|
||||
host = ''
|
||||
finger(host, options + arg)
|
||||
|
||||
|
||||
# Call the main function.
|
||||
#
|
||||
main()
|
|
@ -1,152 +0,0 @@
|
|||
# A simple FTP client.
|
||||
#
|
||||
# The information to write this program was gathered from RFC 959,
|
||||
# but this is not a complete implementation! Yet it shows how a simple
|
||||
# FTP client can be built, and you are welcome to extend it to suit
|
||||
# it to your needs...
|
||||
#
|
||||
# How it works (assuming you've read the RFC):
|
||||
#
|
||||
# User commands are passed uninterpreted to the server. However, the
|
||||
# user never needs to send a PORT command. Rather, the client opens a
|
||||
# port right away and sends the appropriate PORT command to the server.
|
||||
# When a response code 150 is received, this port is used to receive
|
||||
# the data (which is written to stdout in this version), and when the
|
||||
# data is exhausted, a new port is opened and a corresponding PORT
|
||||
# command sent. In order to avoid errors when reusing ports quickly
|
||||
# (and because there is no s.getsockname() method in Python yet) we
|
||||
# cycle through a number of ports in the 50000 range.
|
||||
|
||||
|
||||
import sys, posix, string
|
||||
from socket import *
|
||||
|
||||
|
||||
BUFSIZE = 1024
|
||||
|
||||
# Default port numbers used by the FTP protocol.
|
||||
#
|
||||
FTP_PORT = 21
|
||||
FTP_DATA_PORT = FTP_PORT - 1
|
||||
|
||||
# Change the data port to something not needing root permissions.
|
||||
#
|
||||
FTP_DATA_PORT = FTP_DATA_PORT + 50000
|
||||
|
||||
|
||||
# Main program (called at the end of this file).
|
||||
#
|
||||
def main():
|
||||
hostname = sys.argv[1]
|
||||
control(hostname)
|
||||
|
||||
|
||||
# Control process (user interface and user protocol interpreter).
|
||||
#
|
||||
def control(hostname):
|
||||
#
|
||||
# Create control connection
|
||||
#
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.connect((hostname, FTP_PORT))
|
||||
f = s.makefile('r') # Reading the replies is easier from a file...
|
||||
#
|
||||
# Control loop
|
||||
#
|
||||
r = None
|
||||
while 1:
|
||||
code = getreply(f)
|
||||
if code in ('221', 'EOF'): break
|
||||
if code == '150':
|
||||
getdata(r)
|
||||
code = getreply(f)
|
||||
r = None
|
||||
if not r:
|
||||
r = newdataport(s, f)
|
||||
cmd = getcommand()
|
||||
if not cmd: break
|
||||
s.send(cmd + '\r\n')
|
||||
|
||||
|
||||
# Create a new data port and send a PORT command to the server for it.
|
||||
# (Cycle through a number of ports to avoid problems with reusing
|
||||
# a port within a short time.)
|
||||
#
|
||||
nextport = 0
|
||||
#
|
||||
def newdataport(s, f):
|
||||
global nextport
|
||||
port = nextport + FTP_DATA_PORT
|
||||
nextport = (nextport+1) % 16
|
||||
r = socket(AF_INET, SOCK_STREAM)
|
||||
r.bind((gethostbyname(gethostname()), port))
|
||||
r.listen(1)
|
||||
sendportcmd(s, f, port)
|
||||
return r
|
||||
|
||||
|
||||
# Send an appropriate port command.
|
||||
#
|
||||
def sendportcmd(s, f, port):
|
||||
hostname = gethostname()
|
||||
hostaddr = gethostbyname(hostname)
|
||||
hbytes = string.splitfields(hostaddr, '.')
|
||||
pbytes = [repr(port//256), repr(port%256)]
|
||||
bytes = hbytes + pbytes
|
||||
cmd = 'PORT ' + string.joinfields(bytes, ',')
|
||||
s.send(cmd + '\r\n')
|
||||
code = getreply(f)
|
||||
|
||||
|
||||
# Process an ftp reply and return the 3-digit reply code (as a string).
|
||||
# The reply should be a line of text starting with a 3-digit number.
|
||||
# If the 4th char is '-', it is a multi-line reply and is
|
||||
# terminate by a line starting with the same 3-digit number.
|
||||
# Any text while receiving the reply is echoed to the file.
|
||||
#
|
||||
def getreply(f):
|
||||
line = f.readline()
|
||||
if not line: return 'EOF'
|
||||
print(line, end=' ')
|
||||
code = line[:3]
|
||||
if line[3:4] == '-':
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line: break # Really an error
|
||||
print(line, end=' ')
|
||||
if line[:3] == code and line[3:4] != '-': break
|
||||
return code
|
||||
|
||||
|
||||
# Get the data from the data connection.
|
||||
#
|
||||
def getdata(r):
|
||||
print('(accepting data connection)')
|
||||
conn, host = r.accept()
|
||||
print('(data connection accepted)')
|
||||
while 1:
|
||||
data = conn.recv(BUFSIZE)
|
||||
if not data: break
|
||||
sys.stdout.write(data)
|
||||
print('(end of data connection)')
|
||||
|
||||
def raw_input(prompt):
|
||||
sys.stdout.write(prompt)
|
||||
sys.stdout.flush()
|
||||
return sys.stdin.readline()
|
||||
|
||||
# Get a command from the user.
|
||||
#
|
||||
def getcommand():
|
||||
try:
|
||||
while 1:
|
||||
line = input('ftp.py> ')
|
||||
if line: return line
|
||||
except EOFError:
|
||||
return ''
|
||||
|
||||
|
||||
# Call the main program.
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,352 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# A simple gopher client.
|
||||
#
|
||||
# Usage: gopher [ [selector] host [port] ]
|
||||
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
|
||||
# Default selector, host and port
|
||||
DEF_SELECTOR = ''
|
||||
DEF_HOST = 'gopher.micro.umn.edu'
|
||||
DEF_PORT = 70
|
||||
|
||||
# Recognized file types
|
||||
T_TEXTFILE = '0'
|
||||
T_MENU = '1'
|
||||
T_CSO = '2'
|
||||
T_ERROR = '3'
|
||||
T_BINHEX = '4'
|
||||
T_DOS = '5'
|
||||
T_UUENCODE = '6'
|
||||
T_SEARCH = '7'
|
||||
T_TELNET = '8'
|
||||
T_BINARY = '9'
|
||||
T_REDUNDANT = '+'
|
||||
T_SOUND = 's'
|
||||
|
||||
# Dictionary mapping types to strings
|
||||
typename = {'0': '<TEXT>', '1': '<DIR>', '2': '<CSO>', '3': '<ERROR>', \
|
||||
'4': '<BINHEX>', '5': '<DOS>', '6': '<UUENCODE>', '7': '<SEARCH>', \
|
||||
'8': '<TELNET>', '9': '<BINARY>', '+': '<REDUNDANT>', 's': '<SOUND>'}
|
||||
|
||||
# Oft-used characters and strings
|
||||
CRLF = '\r\n'
|
||||
TAB = '\t'
|
||||
|
||||
# Open a TCP connection to a given host and port
|
||||
def open_socket(host, port):
|
||||
if not port:
|
||||
port = DEF_PORT
|
||||
elif type(port) == type(''):
|
||||
port = int(port)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((host, port))
|
||||
return s
|
||||
|
||||
# Send a selector to a given host and port, return a file with the reply
|
||||
def send_request(selector, host, port):
|
||||
s = open_socket(host, port)
|
||||
s.send(selector + CRLF)
|
||||
s.shutdown(1)
|
||||
return s.makefile('r')
|
||||
|
||||
# Get a menu in the form of a list of entries
|
||||
def get_menu(selector, host, port):
|
||||
f = send_request(selector, host, port)
|
||||
list = []
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
print('(Unexpected EOF from server)')
|
||||
break
|
||||
if line[-2:] == CRLF:
|
||||
line = line[:-2]
|
||||
elif line[-1:] in CRLF:
|
||||
line = line[:-1]
|
||||
if line == '.':
|
||||
break
|
||||
if not line:
|
||||
print('(Empty line from server)')
|
||||
continue
|
||||
typechar = line[0]
|
||||
parts = line[1:].split(TAB)
|
||||
if len(parts) < 4:
|
||||
print('(Bad line from server: %r)' % (line,))
|
||||
continue
|
||||
if len(parts) > 4:
|
||||
print('(Extra info from server: %r)' % (parts[4:],))
|
||||
parts.insert(0, typechar)
|
||||
list.append(parts)
|
||||
f.close()
|
||||
return list
|
||||
|
||||
# Get a text file as a list of lines, with trailing CRLF stripped
|
||||
def get_textfile(selector, host, port):
|
||||
list = []
|
||||
get_alt_textfile(selector, host, port, list.append)
|
||||
return list
|
||||
|
||||
# Get a text file and pass each line to a function, with trailing CRLF stripped
|
||||
def get_alt_textfile(selector, host, port, func):
|
||||
f = send_request(selector, host, port)
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
print('(Unexpected EOF from server)')
|
||||
break
|
||||
if line[-2:] == CRLF:
|
||||
line = line[:-2]
|
||||
elif line[-1:] in CRLF:
|
||||
line = line[:-1]
|
||||
if line == '.':
|
||||
break
|
||||
if line[:2] == '..':
|
||||
line = line[1:]
|
||||
func(line)
|
||||
f.close()
|
||||
|
||||
# Get a binary file as one solid data block
|
||||
def get_binary(selector, host, port):
|
||||
f = send_request(selector, host, port)
|
||||
data = f.read()
|
||||
f.close()
|
||||
return data
|
||||
|
||||
# Get a binary file and pass each block to a function
|
||||
def get_alt_binary(selector, host, port, func, blocksize):
|
||||
f = send_request(selector, host, port)
|
||||
while 1:
|
||||
data = f.read(blocksize)
|
||||
if not data:
|
||||
break
|
||||
func(data)
|
||||
|
||||
# A *very* simple interactive browser
|
||||
|
||||
# Browser main command, has default arguments
|
||||
def browser(*args):
|
||||
selector = DEF_SELECTOR
|
||||
host = DEF_HOST
|
||||
port = DEF_PORT
|
||||
n = len(args)
|
||||
if n > 0 and args[0]:
|
||||
selector = args[0]
|
||||
if n > 1 and args[1]:
|
||||
host = args[1]
|
||||
if n > 2 and args[2]:
|
||||
port = args[2]
|
||||
if n > 3:
|
||||
raise RuntimeError('too many args')
|
||||
try:
|
||||
browse_menu(selector, host, port)
|
||||
except socket.error as msg:
|
||||
print('Socket error:', msg)
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
print('\n[Goodbye]')
|
||||
|
||||
# Browse a menu
|
||||
def browse_menu(selector, host, port):
|
||||
list = get_menu(selector, host, port)
|
||||
while 1:
|
||||
print('----- MENU -----')
|
||||
print('Selector:', repr(selector))
|
||||
print('Host:', host, ' Port:', port)
|
||||
print()
|
||||
for i in range(len(list)):
|
||||
item = list[i]
|
||||
typechar, description = item[0], item[1]
|
||||
print(repr(i+1).rjust(3) + ':', description, end=' ')
|
||||
if typechar in typename:
|
||||
print(typename[typechar])
|
||||
else:
|
||||
print('<TYPE=' + repr(typechar) + '>')
|
||||
print()
|
||||
while 1:
|
||||
try:
|
||||
str = input('Choice [CR == up a level]: ')
|
||||
except EOFError:
|
||||
print()
|
||||
return
|
||||
if not str:
|
||||
return
|
||||
try:
|
||||
choice = int(str)
|
||||
except ValueError:
|
||||
print('Choice must be a number; try again:')
|
||||
continue
|
||||
if not 0 < choice <= len(list):
|
||||
print('Choice out of range; try again:')
|
||||
continue
|
||||
break
|
||||
item = list[choice-1]
|
||||
typechar = item[0]
|
||||
[i_selector, i_host, i_port] = item[2:5]
|
||||
if typechar in typebrowser:
|
||||
browserfunc = typebrowser[typechar]
|
||||
try:
|
||||
browserfunc(i_selector, i_host, i_port)
|
||||
except (IOError, socket.error):
|
||||
t, v, tb = sys.exc_info()
|
||||
print('***', t, ':', v)
|
||||
else:
|
||||
print('Unsupported object type')
|
||||
|
||||
# Browse a text file
|
||||
def browse_textfile(selector, host, port):
|
||||
x = None
|
||||
try:
|
||||
p = os.popen('${PAGER-more}', 'w')
|
||||
x = SaveLines(p)
|
||||
get_alt_textfile(selector, host, port, x.writeln)
|
||||
except IOError as msg:
|
||||
print('IOError:', msg)
|
||||
if x:
|
||||
x.close()
|
||||
f = open_savefile()
|
||||
if not f:
|
||||
return
|
||||
x = SaveLines(f)
|
||||
try:
|
||||
get_alt_textfile(selector, host, port, x.writeln)
|
||||
print('Done.')
|
||||
except IOError as msg:
|
||||
print('IOError:', msg)
|
||||
x.close()
|
||||
|
||||
def raw_input(prompt):
|
||||
sys.stdout.write(prompt)
|
||||
sys.stdout.flush()
|
||||
return sys.stdin.readline()
|
||||
|
||||
# Browse a search index
|
||||
def browse_search(selector, host, port):
|
||||
while 1:
|
||||
print('----- SEARCH -----')
|
||||
print('Selector:', repr(selector))
|
||||
print('Host:', host, ' Port:', port)
|
||||
print()
|
||||
try:
|
||||
query = input('Query [CR == up a level]: ')
|
||||
except EOFError:
|
||||
print()
|
||||
break
|
||||
query = query.strip()
|
||||
if not query:
|
||||
break
|
||||
if '\t' in query:
|
||||
print('Sorry, queries cannot contain tabs')
|
||||
continue
|
||||
browse_menu(selector + TAB + query, host, port)
|
||||
|
||||
# "Browse" telnet-based information, i.e. open a telnet session
|
||||
def browse_telnet(selector, host, port):
|
||||
if selector:
|
||||
print('Log in as', repr(selector))
|
||||
if type(port) != type(''):
|
||||
port = repr(port)
|
||||
sts = os.system('set -x; exec telnet ' + host + ' ' + port)
|
||||
if sts:
|
||||
print('Exit status:', sts)
|
||||
|
||||
# "Browse" a binary file, i.e. save it to a file
|
||||
def browse_binary(selector, host, port):
|
||||
f = open_savefile()
|
||||
if not f:
|
||||
return
|
||||
x = SaveWithProgress(f)
|
||||
get_alt_binary(selector, host, port, x.write, 8*1024)
|
||||
x.close()
|
||||
|
||||
# "Browse" a sound file, i.e. play it or save it
|
||||
def browse_sound(selector, host, port):
|
||||
browse_binary(selector, host, port)
|
||||
|
||||
# Dictionary mapping types to browser functions
|
||||
typebrowser = {'0': browse_textfile, '1': browse_menu, \
|
||||
'4': browse_binary, '5': browse_binary, '6': browse_textfile, \
|
||||
'7': browse_search, \
|
||||
'8': browse_telnet, '9': browse_binary, 's': browse_sound}
|
||||
|
||||
# Class used to save lines, appending a newline to each line
|
||||
class SaveLines:
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
def writeln(self, line):
|
||||
self.f.write(line + '\n')
|
||||
def close(self):
|
||||
sts = self.f.close()
|
||||
if sts:
|
||||
print('Exit status:', sts)
|
||||
|
||||
# Class used to save data while showing progress
|
||||
class SaveWithProgress:
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
def write(self, data):
|
||||
sys.stdout.write('#')
|
||||
sys.stdout.flush()
|
||||
self.f.write(data)
|
||||
def close(self):
|
||||
print()
|
||||
sts = self.f.close()
|
||||
if sts:
|
||||
print('Exit status:', sts)
|
||||
|
||||
# Ask for and open a save file, or return None if not to save
|
||||
def open_savefile():
|
||||
try:
|
||||
savefile = input( \
|
||||
'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ')
|
||||
except EOFError:
|
||||
print()
|
||||
return None
|
||||
savefile = savefile.strip()
|
||||
if not savefile:
|
||||
return None
|
||||
if savefile[0] == '|':
|
||||
cmd = savefile[1:].strip()
|
||||
try:
|
||||
p = os.popen(cmd, 'w')
|
||||
except IOError as msg:
|
||||
print(repr(cmd), ':', msg)
|
||||
return None
|
||||
print('Piping through', repr(cmd), '...')
|
||||
return p
|
||||
if savefile[0] == '~':
|
||||
savefile = os.path.expanduser(savefile)
|
||||
try:
|
||||
f = open(savefile, 'w')
|
||||
except IOError as msg:
|
||||
print(repr(savefile), ':', msg)
|
||||
return None
|
||||
print('Saving to', repr(savefile), '...')
|
||||
return f
|
||||
|
||||
# Test program
|
||||
def test():
|
||||
if sys.argv[4:]:
|
||||
print('usage: gopher [ [selector] host [port] ]')
|
||||
sys.exit(2)
|
||||
elif sys.argv[3:]:
|
||||
browser(sys.argv[1], sys.argv[2], sys.argv[3])
|
||||
elif sys.argv[2:]:
|
||||
try:
|
||||
port = int(sys.argv[2])
|
||||
selector = ''
|
||||
host = sys.argv[1]
|
||||
except ValueError:
|
||||
selector = sys.argv[1]
|
||||
host = sys.argv[2]
|
||||
port = ''
|
||||
browser(selector, host, port)
|
||||
elif sys.argv[1:]:
|
||||
browser('', sys.argv[1])
|
||||
else:
|
||||
browser()
|
||||
|
||||
# Call the test program as a main program
|
||||
test()
|
|
@ -1,14 +0,0 @@
|
|||
# Receive UDP packets transmitted by a broadcasting service
|
||||
|
||||
MYPORT = 50000
|
||||
|
||||
import sys
|
||||
from socket import *
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind(('', MYPORT))
|
||||
|
||||
while 1:
|
||||
data, wherefrom = s.recvfrom(1500, 0)
|
||||
sys.stderr.write(repr(wherefrom) + '\n')
|
||||
sys.stdout.write(data)
|
|
@ -1,109 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Minimal interface to the Internet telnet protocol.
|
||||
#
|
||||
# It refuses all telnet options and does not recognize any of the other
|
||||
# telnet commands, but can still be used to connect in line-by-line mode.
|
||||
# It's also useful to play with a number of other services,
|
||||
# like time, finger, smtp and even ftp.
|
||||
#
|
||||
# Usage: telnet host [port]
|
||||
#
|
||||
# The port may be a service name or a decimal port number;
|
||||
# it defaults to 'telnet'.
|
||||
|
||||
|
||||
import sys, posix, time
|
||||
from socket import *
|
||||
|
||||
BUFSIZE = 1024
|
||||
|
||||
# Telnet protocol characters
|
||||
|
||||
IAC = chr(255) # Interpret as command
|
||||
DONT = chr(254)
|
||||
DO = chr(253)
|
||||
WONT = chr(252)
|
||||
WILL = chr(251)
|
||||
|
||||
def main():
|
||||
host = sys.argv[1]
|
||||
try:
|
||||
hostaddr = gethostbyname(host)
|
||||
except error:
|
||||
sys.stderr.write(sys.argv[1] + ': bad host name\n')
|
||||
sys.exit(2)
|
||||
#
|
||||
if len(sys.argv) > 2:
|
||||
servname = sys.argv[2]
|
||||
else:
|
||||
servname = 'telnet'
|
||||
#
|
||||
if '0' <= servname[:1] <= '9':
|
||||
port = eval(servname)
|
||||
else:
|
||||
try:
|
||||
port = getservbyname(servname, 'tcp')
|
||||
except error:
|
||||
sys.stderr.write(servname + ': bad tcp service name\n')
|
||||
sys.exit(2)
|
||||
#
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
#
|
||||
try:
|
||||
s.connect((host, port))
|
||||
except error as msg:
|
||||
sys.stderr.write('connect failed: ' + repr(msg) + '\n')
|
||||
sys.exit(1)
|
||||
#
|
||||
pid = posix.fork()
|
||||
#
|
||||
if pid == 0:
|
||||
# child -- read stdin, write socket
|
||||
while 1:
|
||||
line = sys.stdin.readline()
|
||||
s.send(line)
|
||||
else:
|
||||
# parent -- read socket, write stdout
|
||||
iac = 0 # Interpret next char as command
|
||||
opt = '' # Interpret next char as option
|
||||
while 1:
|
||||
data = s.recv(BUFSIZE)
|
||||
if not data:
|
||||
# EOF; kill child and exit
|
||||
sys.stderr.write( '(Closed by remote host)\n')
|
||||
posix.kill(pid, 9)
|
||||
sys.exit(1)
|
||||
cleandata = ''
|
||||
for c in data:
|
||||
if opt:
|
||||
print(ord(c))
|
||||
s.send(opt + c)
|
||||
opt = ''
|
||||
elif iac:
|
||||
iac = 0
|
||||
if c == IAC:
|
||||
cleandata = cleandata + c
|
||||
elif c in (DO, DONT):
|
||||
if c == DO: print('(DO)', end=' ')
|
||||
else: print('(DONT)', end=' ')
|
||||
opt = IAC + WONT
|
||||
elif c in (WILL, WONT):
|
||||
if c == WILL: print('(WILL)', end=' ')
|
||||
else: print('(WONT)', end=' ')
|
||||
opt = IAC + DONT
|
||||
else:
|
||||
print('(command)', ord(c))
|
||||
elif c == IAC:
|
||||
iac = 1
|
||||
print('(IAC)', end=' ')
|
||||
else:
|
||||
cleandata = cleandata + c
|
||||
sys.stdout.write(cleandata)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
|
@ -1,93 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Test network throughput.
|
||||
#
|
||||
# Usage:
|
||||
# 1) on host_A: throughput -s [port] # start a server
|
||||
# 2) on host_B: throughput -c count host_A [port] # start a client
|
||||
#
|
||||
# The server will service multiple clients until it is killed.
|
||||
#
|
||||
# The client performs one transfer of count*BUFSIZE bytes and
|
||||
# measures the time it takes (roundtrip!).
|
||||
|
||||
|
||||
import sys, time
|
||||
from socket import *
|
||||
|
||||
MY_PORT = 50000 + 42
|
||||
|
||||
BUFSIZE = 1024
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
usage()
|
||||
if sys.argv[1] == '-s':
|
||||
server()
|
||||
elif sys.argv[1] == '-c':
|
||||
client()
|
||||
else:
|
||||
usage()
|
||||
|
||||
|
||||
def usage():
|
||||
sys.stdout = sys.stderr
|
||||
print('Usage: (on host_A) throughput -s [port]')
|
||||
print('and then: (on host_B) throughput -c count host_A [port]')
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def server():
|
||||
if len(sys.argv) > 2:
|
||||
port = eval(sys.argv[2])
|
||||
else:
|
||||
port = MY_PORT
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
s.bind(('', port))
|
||||
s.listen(1)
|
||||
print('Server ready...')
|
||||
while 1:
|
||||
conn, (host, remoteport) = s.accept()
|
||||
while 1:
|
||||
data = conn.recv(BUFSIZE)
|
||||
if not data:
|
||||
break
|
||||
del data
|
||||
conn.send('OK\n')
|
||||
conn.close()
|
||||
print('Done with', host, 'port', remoteport)
|
||||
|
||||
|
||||
def client():
|
||||
if len(sys.argv) < 4:
|
||||
usage()
|
||||
count = int(eval(sys.argv[2]))
|
||||
host = sys.argv[3]
|
||||
if len(sys.argv) > 4:
|
||||
port = eval(sys.argv[4])
|
||||
else:
|
||||
port = MY_PORT
|
||||
testdata = 'x' * (BUFSIZE-1) + '\n'
|
||||
t1 = time.time()
|
||||
s = socket(AF_INET, SOCK_STREAM)
|
||||
t2 = time.time()
|
||||
s.connect((host, port))
|
||||
t3 = time.time()
|
||||
i = 0
|
||||
while i < count:
|
||||
i = i+1
|
||||
s.send(testdata)
|
||||
s.shutdown(1) # Send EOF
|
||||
t4 = time.time()
|
||||
data = s.recv(BUFSIZE)
|
||||
t5 = time.time()
|
||||
print(data)
|
||||
print('Raw timers:', t1, t2, t3, t4, t5)
|
||||
print('Intervals:', t2-t1, t3-t2, t4-t3, t5-t4)
|
||||
print('Total:', t5-t1)
|
||||
print('Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3), end=' ')
|
||||
print('K/sec.')
|
||||
|
||||
|
||||
main()
|
|
@ -1,64 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Client and server for udp (datagram) echo.
|
||||
#
|
||||
# Usage: udpecho -s [port] (to start a server)
|
||||
# or: udpecho -c host [port] <file (client)
|
||||
|
||||
import sys
|
||||
from socket import *
|
||||
|
||||
ECHO_PORT = 50000 + 7
|
||||
BUFSIZE = 1024
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
usage()
|
||||
if sys.argv[1] == '-s':
|
||||
server()
|
||||
elif sys.argv[1] == '-c':
|
||||
client()
|
||||
else:
|
||||
usage()
|
||||
|
||||
def usage():
|
||||
sys.stdout = sys.stderr
|
||||
print('Usage: udpecho -s [port] (server)')
|
||||
print('or: udpecho -c host [port] <file (client)')
|
||||
sys.exit(2)
|
||||
|
||||
def server():
|
||||
if len(sys.argv) > 2:
|
||||
port = eval(sys.argv[2])
|
||||
else:
|
||||
port = ECHO_PORT
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind(('', port))
|
||||
print('udp echo server ready')
|
||||
while 1:
|
||||
data, addr = s.recvfrom(BUFSIZE)
|
||||
print('server received %r from %r' % (data, addr))
|
||||
s.sendto(data, addr)
|
||||
|
||||
def client():
|
||||
if len(sys.argv) < 3:
|
||||
usage()
|
||||
host = sys.argv[2]
|
||||
if len(sys.argv) > 3:
|
||||
port = eval(sys.argv[3])
|
||||
else:
|
||||
port = ECHO_PORT
|
||||
addr = host, port
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind(('', 0))
|
||||
print('udp echo client ready, reading stdin')
|
||||
while 1:
|
||||
line = sys.stdin.readline()
|
||||
if not line:
|
||||
break
|
||||
print('addr = ', addr)
|
||||
s.sendto(bytes(line, 'ascii'), addr)
|
||||
data, fromaddr = s.recvfrom(BUFSIZE)
|
||||
print('client received %r from %r' % (data, fromaddr))
|
||||
|
||||
main()
|
|
@ -1,14 +0,0 @@
|
|||
# Send UDP broadcast packets
|
||||
|
||||
MYPORT = 50000
|
||||
|
||||
import sys, time
|
||||
from socket import *
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM)
|
||||
s.bind(('', 0))
|
||||
|
||||
while 1:
|
||||
data = repr(time.time()) + '\n'
|
||||
s.sendto(data, ('', MYPORT))
|
||||
time.sleep(2)
|
|
@ -1,12 +0,0 @@
|
|||
# Echo client demo using Unix sockets
|
||||
# Piet van Oostrum
|
||||
|
||||
from socket import *
|
||||
|
||||
FILE = 'unix-socket'
|
||||
s = socket(AF_UNIX, SOCK_STREAM)
|
||||
s.connect(FILE)
|
||||
s.send(b'Hello, world')
|
||||
data = s.recv(1024)
|
||||
s.close()
|
||||
print('Received', repr(data))
|
|
@ -1,24 +0,0 @@
|
|||
# Echo server demo using Unix sockets (handles one connection only)
|
||||
# Piet van Oostrum
|
||||
|
||||
import os
|
||||
from socket import *
|
||||
|
||||
FILE = 'unix-socket'
|
||||
s = socket(AF_UNIX, SOCK_STREAM)
|
||||
s.bind(FILE)
|
||||
|
||||
print('Sock name is: ['+s.getsockname()+']')
|
||||
|
||||
# Wait for a connection
|
||||
s.listen(1)
|
||||
conn, addr = s.accept()
|
||||
|
||||
while True:
|
||||
data = conn.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
conn.send(data)
|
||||
|
||||
conn.close()
|
||||
os.unlink(FILE)
|
|
@ -1,89 +0,0 @@
|
|||
$Id$
|
||||
|
||||
Installing Tix.py
|
||||
----------------
|
||||
|
||||
0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1).
|
||||
Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2
|
||||
and Mandrake Linux 7.0 and Windows with the above mentioned packages.
|
||||
|
||||
Older versions, e.g. Tix 4.1 and Tk 8.0, might also work.
|
||||
|
||||
There is nothing OS-specific in Tix.py itself so it should work on
|
||||
any machine with Tix and Python installed. You can get Tcl and Tk
|
||||
from http://dev.scriptics.com and Tix from http://tix.sourceforge.net.
|
||||
|
||||
1) Build and install Tcl/Tk 8.3. Build and install Tix 8.1.
|
||||
Ensure that Tix is properly installed by running tixwish and executing
|
||||
the demo programs. Under Unix, use the --enable-shared configure option
|
||||
for all three. We recommend tcl8.3.3 for this release of Tix.py.
|
||||
|
||||
2a) If you have a distribution like ActiveState with a tcl subdirectory
|
||||
of $PYTHONHOME, which contains the directories tcl8.3 and tk8.3,
|
||||
make a directory tix8.1 as well. Recursively copy the files from
|
||||
<tix>/library to $PYTHONHOME/lib/tix8.1, and copy the dynamic library
|
||||
(tix8183.dll or libtix8.1.8.3.so) to the same place as the tcl dynamic
|
||||
libraries ($PYTHONHOME/Dlls or lib/python-2.1/lib-dynload). In this
|
||||
case you are all installed, and you can skip to the end.
|
||||
|
||||
2b) Modify Modules/Setup.dist and setup.py to change the version of the
|
||||
tix library from tix4.1.8.0 to tix8.1.8.3
|
||||
These modified files can be used for Tkinter with or without Tix.
|
||||
|
||||
3) The default is to build dynamically, and use the Tcl 'package require'.
|
||||
To build statically, modify the Modules/Setup file to link in the Tix
|
||||
library according to the comments in the file. On Linux this looks like:
|
||||
|
||||
# *** Always uncomment this (leave the leading underscore in!):
|
||||
_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
|
||||
# *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
|
||||
-L/usr/local/lib \
|
||||
# *** Uncomment and edit to reflect where your Tcl/Tk headers are:
|
||||
-I/usr/local/include \
|
||||
# *** Uncomment and edit to reflect where your X11 header files are:
|
||||
-I/usr/X11R6/include \
|
||||
# *** Or uncomment this for Solaris:
|
||||
# -I/usr/openwin/include \
|
||||
# *** Uncomment and edit for BLT extension only:
|
||||
# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
|
||||
# *** Uncomment and edit for PIL (TkImaging) extension only:
|
||||
# (See http://www.pythonware.com/products/pil/ for more info)
|
||||
# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
|
||||
# *** Uncomment and edit for TOGL extension only:
|
||||
# -DWITH_TOGL togl.c \
|
||||
# *** Uncomment and edit for Tix extension only:
|
||||
-DWITH_TIX -ltix8.1.8.3 \
|
||||
# *** Uncomment and edit to reflect your Tcl/Tk versions:
|
||||
-ltk8.3 -ltcl8.3 \
|
||||
# *** Uncomment and edit to reflect where your X11 libraries are:
|
||||
-L/usr/X11R6/lib \
|
||||
# *** Or uncomment this for Solaris:
|
||||
# -L/usr/openwin/lib \
|
||||
# *** Uncomment these for TOGL extension only:
|
||||
# -lGL -lGLU -lXext -lXmu \
|
||||
# *** Uncomment for AIX:
|
||||
# -lld \
|
||||
# *** Always uncomment this; X11 libraries to link with:
|
||||
-lX11
|
||||
|
||||
4) Rebuild Python and reinstall.
|
||||
|
||||
You should now have a working Tix implementation in Python. To see if all
|
||||
is as it should be, run the 'tixwidgets.py' script in the Demo/tix directory.
|
||||
Under X windows, do
|
||||
/usr/local/bin/python Demo/tix/tixwidgets.py
|
||||
|
||||
If this does not work, you may need to tell python where to find
|
||||
the Tcl, Tk and Tix library files. This is done by setting the
|
||||
TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. Try this:
|
||||
|
||||
env TCL_LIBRARY=/usr/local/lib/tcl8.3 \
|
||||
TK_LIBRARY=/usr/local/lib/tk8.3 \
|
||||
TIX_LIBRARY=/usr/local/lib/tix8.1 \
|
||||
/usr/local/bin/python Demo/tix/tixwidgets.py
|
||||
|
||||
|
||||
If you find any bugs or have suggestions for improvement, please report them
|
||||
via http://tix.sourceforge.net
|
||||
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
About Tix.py
|
||||
-----------
|
||||
|
||||
Tix.py is based on an idea of Jean-Marc Lugrin (lugrin@ms.com) who wrote
|
||||
pytix (another Python-Tix marriage). Tix widgets are an attractive and
|
||||
useful extension to Tk. See http://tix.sourceforge.net
|
||||
for more details about Tix and how to get it.
|
||||
|
||||
Features:
|
||||
1) It is almost complete.
|
||||
2) Tix widgets are represented by classes in Python. Sub-widgets
|
||||
are members of the mega-widget class. For example, if a
|
||||
particular TixWidget (e.g. ScrolledText) has an embedded widget
|
||||
(Text in this case), it is possible to call the methods of the
|
||||
child directly.
|
||||
3) The members of the class are created automatically. In the case
|
||||
of widgets like ButtonBox, the members are added dynamically.
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/* XPM */
|
||||
static char * about_xpm[] = {
|
||||
"50 40 7 1",
|
||||
" s None c None",
|
||||
". c black",
|
||||
"X c white",
|
||||
"o c gray70",
|
||||
"O c navy",
|
||||
"+ c red",
|
||||
"@ c yellow",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ................................. ",
|
||||
" ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo. ",
|
||||
" .XooooooooooooooooooooooooooooooXo. ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXooXo. ",
|
||||
" ..oooooooooooooooooooooooooooooooXo. ",
|
||||
" ...............................XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.++++ ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo+++ ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++++ ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo++++++ ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++ + ",
|
||||
" .OOOOO@@@@@OOOOOOOOOOOOOOOOOOO.Xo++. ",
|
||||
" .OOOOOOO@OOOOO@OOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOO@@OOO@OOO@OOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ",
|
||||
" .OOOOOOO@OOOO@@@OO@OOO@OOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo.. ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
|
||||
" OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.X. ",
|
||||
" ............................. ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,6 +0,0 @@
|
|||
#define bold_width 16
|
||||
#define bold_height 16
|
||||
static unsigned char bold_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x0f, 0x18, 0x1c, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x1c, 0xf8, 0x0f, 0xf8, 0x0f, 0x18, 0x18, 0x18, 0x30,
|
||||
0x18, 0x30, 0x18, 0x38, 0xfc, 0x3f, 0xfc, 0x1f};
|
|
@ -1,6 +0,0 @@
|
|||
#define capital_width 16
|
||||
#define capital_height 16
|
||||
static unsigned char capital_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x30, 0x0c, 0x30, 0x06,
|
||||
0x30, 0x03, 0xb0, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x03,
|
||||
0x30, 0x07, 0x30, 0x0e, 0x30, 0x1c, 0x00, 0x00};
|
|
@ -1,6 +0,0 @@
|
|||
#define centerj_width 16
|
||||
#define centerj_height 16
|
||||
static unsigned char centerj_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xc0, 0x0d,
|
||||
0x00, 0x00, 0x58, 0x77, 0x00, 0x00, 0xb0, 0x3b, 0x00, 0x00, 0xdc, 0xf7,
|
||||
0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xd8, 0x7e};
|
|
@ -1,14 +0,0 @@
|
|||
#define combobox_width 32
|
||||
#define combobox_height 32
|
||||
static unsigned char combobox_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfc, 0xff, 0xff, 0x3e, 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2a,
|
||||
0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2b, 0xfc, 0xff, 0xff, 0x3e,
|
||||
0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a,
|
||||
0x28, 0x49, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x22,
|
||||
0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x12, 0x22, 0x08, 0x00, 0x00, 0x22,
|
||||
0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x02, 0x22,
|
||||
0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x2a,
|
||||
0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
@ -1,49 +0,0 @@
|
|||
/* XPM */
|
||||
static char * combobox_xpm[] = {
|
||||
"50 40 6 1",
|
||||
" s None c None",
|
||||
". c black",
|
||||
"X c white",
|
||||
"o c #FFFF80808080",
|
||||
"O c gray70",
|
||||
"+ c #808000008080",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .................................... XXXXXXX ",
|
||||
" .ooooooooooooooooooooooooooooooooooX X . . ",
|
||||
" .ooooooooooooooooooooooooooooooooooX X . . ",
|
||||
" .oooo.oooooooooooooooooooooooooooooX X . . ",
|
||||
" .oo.o..oo.o.oo.o.ooooooooooooooooooX X . . ",
|
||||
" .o..o.o.o.oo.oo.oo.ooooooooooooooooX X ... . ",
|
||||
" .oo.oo.oo.o.oo.ooo.ooooooooooooooooX X . . ",
|
||||
" .ooooooooooooooooooooooooooooooooooX X . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X...... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ",
|
||||
" X............................................ ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
|
||||
" X.O+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OX OX. ",
|
||||
" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.X ..X. ",
|
||||
" X.O+O+O+OOO+O+OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
|
||||
" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.XXXXX. ",
|
||||
" X.O.....X..........................OOX.X .X. ",
|
||||
" X.OX...XXX.X.XX.XX.................OOX.X .X. ",
|
||||
" X.OX.X..X..X.XX..XX.X..............OOX.X .X. ",
|
||||
" X.O.X...X..X.X...X..X..............OOX.X .X. ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOOOOX.X .X. ",
|
||||
" X.OOOOOOOOO+OOO+OOOOO+OOOO+OOOOOOOOOOX.X .X. ",
|
||||
" X.O+++OO+OO+O+OO++O++OO+OO+OOOOOOOOOOX.X...X. ",
|
||||
" X.OO+OO++OO+O+OO+OOO+OO+O++OOOOOOOOOOX.OOOOX. ",
|
||||
" X.OOOOOOOO+OOOOO++OO+OOOOOOOOOOOOOOOOX.OOOOX. ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.X .X. ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.O .OX. ",
|
||||
" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ",
|
||||
" X.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXX. ",
|
||||
" X............................................ ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,47 +0,0 @@
|
|||
/* XPM */
|
||||
static char * combobox_xpm[] = {
|
||||
"50 40 4 1",
|
||||
" s None c None",
|
||||
". c black",
|
||||
"X c #FFFF80808080",
|
||||
"o c gray70",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .................................... ....... ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . ... . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . ",
|
||||
" .................................... ....... ",
|
||||
" ",
|
||||
" ............................................. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .o...................................o.ooooo. ",
|
||||
" .o...................................o.ooooo. ",
|
||||
" .o...................................o.ooooo. ",
|
||||
" .o...................................o.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" .ooooooooooooooooooooooooooooooooooooo.ooooo. ",
|
||||
" ............................................. ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,14 +0,0 @@
|
|||
#define drivea_width 32
|
||||
#define drivea_height 32
|
||||
static unsigned char drivea_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
|
||||
0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
|
||||
0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
|
||||
0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
|
||||
0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
@ -1,43 +0,0 @@
|
|||
/* XPM */
|
||||
static char * drivea_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"32 32 5 1",
|
||||
/* colors */
|
||||
" s None c None",
|
||||
". c #000000000000",
|
||||
"X c white",
|
||||
"o c #c000c000c000",
|
||||
"O c #800080008000",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .......................... ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXo. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .Xooooooooooooooooo..oooO. ",
|
||||
" .Xooooooooooooooooo..oooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .Xoooooooo.......oooooooO. ",
|
||||
" .Xoo...................oO. ",
|
||||
" .Xoooooooo.......oooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .oOOOOOOOOOOOOOOOOOOOOOOO. ",
|
||||
" .......................... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,48 +0,0 @@
|
|||
/* XPM */
|
||||
static char * exit_xpm[] = {
|
||||
"50 40 5 1",
|
||||
" s None c None",
|
||||
". c black",
|
||||
"X c white",
|
||||
"o c #000080800000",
|
||||
"O c yellow",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ....................................... ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ",
|
||||
" .XoooooooooooooooooooooooooooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooooooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOoooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOOooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOOOoooooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOOoooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ",
|
||||
" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOOOoooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOOooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooOoooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooooooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooooooooooooooX. ",
|
||||
" .XoooooooooooooooooooooooooooooooooooX. ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ",
|
||||
" ....................................... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,14 +0,0 @@
|
|||
#define filebox_width 32
|
||||
#define filebox_height 32
|
||||
static unsigned char filebox_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20,
|
||||
0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
|
||||
0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xe4, 0x7f, 0xfe, 0x27,
|
||||
0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25,
|
||||
0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24,
|
||||
0x24, 0x50, 0x02, 0x25, 0xe4, 0x7f, 0xfe, 0x27, 0x04, 0x00, 0x00, 0x20,
|
||||
0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24,
|
||||
0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
@ -1,49 +0,0 @@
|
|||
/* XPM */
|
||||
static char * filebox_xpm[] = {
|
||||
"50 40 6 1",
|
||||
" s None c None",
|
||||
". c white",
|
||||
"X c gray80",
|
||||
"o c black",
|
||||
"O c #FFFF80808080",
|
||||
"+ c gray70",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ............................................ ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXooooooooooooooooooooooooooooooooooooo.XXo ",
|
||||
" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ",
|
||||
" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ",
|
||||
" .XX......................................XXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXoooooooooooooooo.XXXXoooooooooooooooo.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ",
|
||||
" .XX.................XXXX.................XXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXooXooXoXooXoXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXooXooXoXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXoooooooooooooooooooooooooooooooooooooo.Xo ",
|
||||
" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
|
||||
" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ",
|
||||
" .XX.......................................Xo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .ooooooooooooooooooooooooooooooooooooooooooo ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,6 +0,0 @@
|
|||
#define italic_width 16
|
||||
#define italic_height 16
|
||||
static unsigned char italic_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x80, 0x3f, 0x00, 0x06, 0x00, 0x06,
|
||||
0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00,
|
||||
0x60, 0x00, 0x60, 0x00, 0xfc, 0x01, 0xfc, 0x01};
|
|
@ -1,6 +0,0 @@
|
|||
#define justify_width 16
|
||||
#define justify_height 16
|
||||
static unsigned char justify_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x00, 0x7c, 0xdb,
|
||||
0x00, 0x00, 0xbc, 0xf7, 0x00, 0x00, 0xdc, 0xde, 0x00, 0x00, 0x6c, 0xdf,
|
||||
0x00, 0x00, 0x6c, 0xef, 0x00, 0x00, 0xdc, 0xdf};
|
|
@ -1,6 +0,0 @@
|
|||
#define leftj_width 16
|
||||
#define leftj_height 16
|
||||
static unsigned char leftj_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x6d, 0x00, 0x00, 0xdc, 0x01,
|
||||
0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0xdc, 0x03,
|
||||
0x00, 0x00, 0x6c, 0x3b, 0x00, 0x00, 0x6c, 0x1f};
|
|
@ -1,14 +0,0 @@
|
|||
#define netw_width 32
|
||||
#define netw_height 32
|
||||
static unsigned char netw_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
|
||||
0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
|
||||
0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
|
||||
0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
|
||||
0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
|
||||
0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
|
||||
0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
|
||||
0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
|
||||
0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
|
||||
0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
|
||||
0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
@ -1,45 +0,0 @@
|
|||
/* XPM */
|
||||
static char * netw_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"32 32 7 1",
|
||||
/* colors */
|
||||
" s None c None",
|
||||
". c #000000000000",
|
||||
"X c white",
|
||||
"o c #c000c000c000",
|
||||
"O c #404040",
|
||||
"+ c blue",
|
||||
"@ c red",
|
||||
/* pixels */
|
||||
" ",
|
||||
" .............. ",
|
||||
" .XXXXXXXXXXXX. ",
|
||||
" .XooooooooooO. ",
|
||||
" .Xo.......XoO. ",
|
||||
" .Xo.++++o+XoO. ",
|
||||
" .Xo.++++o+XoO. ",
|
||||
" .Xo.++oo++XoO. ",
|
||||
" .Xo.++++++XoO. ",
|
||||
" .Xo.+o++++XoO. ",
|
||||
" .Xo.++++++XoO. ",
|
||||
" .Xo.XXXXXXXoO. ",
|
||||
" .XooooooooooO. ",
|
||||
" .Xo@ooo....oO. ",
|
||||
" .............. .XooooooooooO. ",
|
||||
" .XXXXXXXXXXXX. .XooooooooooO. ",
|
||||
" .XooooooooooO. .OOOOOOOOOOOO. ",
|
||||
" .Xo.......XoO. .............. ",
|
||||
" .Xo.++++o+XoO. @ ",
|
||||
" .Xo.++++o+XoO. @ ",
|
||||
" .Xo.++oo++XoO. @ ",
|
||||
" .Xo.++++++XoO. @ ",
|
||||
" .Xo.+o++++XoO. @ ",
|
||||
" .Xo.++++++XoO. ..... ",
|
||||
" .Xo.XXXXXXXoO. .XXX. ",
|
||||
" .XooooooooooO.@@@@@@.X O. ",
|
||||
" .Xo@ooo....oO. .OOO. ",
|
||||
" .XooooooooooO. ..... ",
|
||||
" .XooooooooooO. ",
|
||||
" .OOOOOOOOOOOO. ",
|
||||
" .............. ",
|
||||
" "};
|
|
@ -1,48 +0,0 @@
|
|||
/* XPM */
|
||||
static char * optmenu_xpm[] = {
|
||||
"50 40 5 1",
|
||||
" s None c None",
|
||||
". c white",
|
||||
"X c gray80",
|
||||
"o c gray50",
|
||||
"O c black",
|
||||
" ",
|
||||
" ",
|
||||
" .............................. ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXOXOXXOXXOXXXXOOXXXXXXXXXXo ",
|
||||
" .XXXOXOXXOXOXXXOXXOXXXXXXXXXXo ",
|
||||
" .XXXXOXXOXXOXXXOXXXOXXXXXXXXXo ",
|
||||
" .XXXXOXXXOXXOOXXOXOXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo.............o ",
|
||||
" .............................o o ",
|
||||
" ..XXXOXXXXXOXXXXXXXXOXXXXXXXOo o ",
|
||||
" ..XXOXOXOXXOXOXXXOXXOXXXXXXXOo ...... o ",
|
||||
" ..XXXOXXXOXXOXXXOXXXOXXXXXXXOo . o o ",
|
||||
" ..XXOXXXOXXXOXOXXOXXOXXXXXXXOo . o o ",
|
||||
" ..XXXXXXXXXXXXXXXXXXXXXXXXXXOo .ooooo o ",
|
||||
" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOo o ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo o ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXooooooooooooooo ",
|
||||
" .XXXXOXXXXXOXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXOXXXXXXXXXOXXXXXXXXXXXXXXo ",
|
||||
" .XXXXOXXOXXOXOXOXXXXXXXXXXXXXo ",
|
||||
" .XXXXXOXXOXOXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXOXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXOXOXXXXXXXOXOXXXXXOXXXXXXo ",
|
||||
" .XXXXXOXOXOXXOXXXXXOXXOXXXXXXo ",
|
||||
" .XXXXOXXOXOXOXXXOXOXOXXOXXXXXo ",
|
||||
" .XXXOXXXXOXXOXXXOXXOXXXXOXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ",
|
||||
" oooooooooooooooooooooooooooooo ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
|
@ -1,6 +0,0 @@
|
|||
#define rightj_width 16
|
||||
#define rightj_height 16
|
||||
static unsigned char rightj_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdb, 0x00, 0x00, 0x70, 0xdb,
|
||||
0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0xd8, 0xde, 0x00, 0x00, 0xc0, 0xdd,
|
||||
0x00, 0x00, 0xa0, 0xef, 0x00, 0x00, 0xd8, 0xde};
|
|
@ -1,52 +0,0 @@
|
|||
/* XPM */
|
||||
static char * select_xpm[] = {
|
||||
"50 40 9 1",
|
||||
" s None c None",
|
||||
". c black",
|
||||
"X c gray95",
|
||||
"o c gray50",
|
||||
"O c gray70",
|
||||
"+ c navy",
|
||||
"@ c #000080800000",
|
||||
"# c #808000000000",
|
||||
"$ c white",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .............................................. ",
|
||||
" .XXXXXXXXXXooooooooooooXXXXXXXXXXXoXXXXXXXXXX. ",
|
||||
" .X ooOOOOOOOOOOXX oX o. ",
|
||||
" .X ooOOOOOOOOOOXX oX o. ",
|
||||
" .X ++++ ooOOOOOOOOOOXX ... oX @ o. ",
|
||||
" .X +++++ ooOOOOOOOOOOXX . . oX @@@ o. ",
|
||||
" .X +++ + ooOOOOOOOOOOXX . . oX @ @ o. ",
|
||||
" .X + + ooOO#####OOOXX . . oX @ @ o. ",
|
||||
" .X + + ooOO#OOO##OOXX . oX @ @ o. ",
|
||||
" .X + + ooO##OOOO##OXX . oX @ @ o. ",
|
||||
" .X ++ ++ ooO###OOO#OOXX . oX @ @ o. ",
|
||||
" .X +++++++ ooO#######OOXX . oX @ @ o. ",
|
||||
" .X + + ooO##O#OO#OOXX . oX @ @ o. ",
|
||||
" .X + ++ ooO##OOOOO#OXX . . oX @ @ o. ",
|
||||
" .X + + ooOO#OOOOO#OXX . . oX @ @@ o. ",
|
||||
" .X + ++ ooOO#OOOOO#OXX .... oX @@@@@ o. ",
|
||||
" .X ooOO######OOXX oX o. ",
|
||||
" .X ooOOOOOOOOOOXX $oX o. ",
|
||||
" .XoooooooooooXXXXXXXXXXXoooooooooooXooooooooo. ",
|
||||
" .............................................. ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
|
@ -1,6 +0,0 @@
|
|||
#define underline_width 16
|
||||
#define underline_height 16
|
||||
static unsigned char underline_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x38, 0x1c,
|
||||
0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x70, 0x0e,
|
||||
0xf0, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f};
|
|
@ -1,28 +0,0 @@
|
|||
###
|
||||
import tkinter.tix as tk
|
||||
from pprint import pprint
|
||||
|
||||
r= tk.Tk()
|
||||
r.title("test")
|
||||
|
||||
l=tk.Label(r, name="a_label")
|
||||
l.pack()
|
||||
|
||||
class MyGrid(tk.Grid):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['editnotify']= self.editnotify
|
||||
tk.Grid.__init__(self, *args, **kwargs)
|
||||
def editnotify(self, x, y):
|
||||
return True
|
||||
|
||||
g = MyGrid(r, name="a_grid",
|
||||
selectunit="cell")
|
||||
g.pack(fill=tk.BOTH)
|
||||
for x in range(5):
|
||||
for y in range(5):
|
||||
g.set(x,y,text=str((x,y)))
|
||||
|
||||
c = tk.Button(r, text="Close", command=r.destroy)
|
||||
c.pack()
|
||||
|
||||
tk.mainloop()
|
|
@ -1,68 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixBalloon widget, which provides
|
||||
# a interesting way to give help tips about elements in your user interface.
|
||||
# Your can display the help message in a "balloon" and a status bar widget.
|
||||
#
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
balloon = DemoBalloon(root)
|
||||
balloon.mainloop()
|
||||
balloon.destroy()
|
||||
|
||||
class DemoBalloon:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
status = tkinter.tix.Label(w, width=40, relief=tkinter.tix.SUNKEN, bd=1)
|
||||
status.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.Y, padx=2, pady=1)
|
||||
|
||||
# Create two mysterious widgets that need balloon help
|
||||
button1 = tkinter.tix.Button(w, text='Something Unexpected',
|
||||
command=self.quitcmd)
|
||||
button2 = tkinter.tix.Button(w, text='Something Else Unexpected')
|
||||
button2['command'] = lambda w=button2: w.destroy()
|
||||
button1.pack(side=tkinter.tix.TOP, expand=1)
|
||||
button2.pack(side=tkinter.tix.TOP, expand=1)
|
||||
|
||||
# Create the balloon widget and associate it with the widgets that we want
|
||||
# to provide tips for:
|
||||
b = tkinter.tix.Balloon(w, statusbar=status)
|
||||
|
||||
b.bind_widget(button1, balloonmsg='Close Window',
|
||||
statusmsg='Press this button to close this window')
|
||||
b.bind_widget(button2, balloonmsg='Self-destruct button',
|
||||
statusmsg='Press this button and it will destroy itself')
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
foundEvent = 1
|
||||
while self.exit < 0 and foundEvent > 0:
|
||||
foundEvent = self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,44 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixButtonBox widget, which is a
|
||||
# group of TK buttons. You can use it to manage the buttons in a dialog box,
|
||||
# for example.
|
||||
#
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
def RunSample(w):
|
||||
# Create the label on the top of the dialog box
|
||||
#
|
||||
top = tkinter.tix.Label(w, padx=20, pady=10, bd=1, relief=tkinter.tix.RAISED,
|
||||
anchor=tkinter.tix.CENTER, text='This dialog box is\n a demonstration of the\n tixButtonBox widget')
|
||||
|
||||
# Create the button box and add a few buttons in it. Set the
|
||||
# -width of all the buttons to the same value so that they
|
||||
# appear in the same size.
|
||||
#
|
||||
# Note that the -text, -underline, -command and -width options are all
|
||||
# standard options of the button widgets.
|
||||
#
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='OK', underline=0, width=5,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.add('close', text='Cancel', underline=0, width=5,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,196 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the compound images: it uses compound
|
||||
# images to display a text string together with a pixmap inside
|
||||
# buttons
|
||||
#
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
network_pixmap = """/* XPM */
|
||||
static char * netw_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"32 32 7 1",
|
||||
/* colors */
|
||||
" s None c None",
|
||||
". c #000000000000",
|
||||
"X c white",
|
||||
"o c #c000c000c000",
|
||||
"O c #404040",
|
||||
"+ c blue",
|
||||
"@ c red",
|
||||
/* pixels */
|
||||
" ",
|
||||
" .............. ",
|
||||
" .XXXXXXXXXXXX. ",
|
||||
" .XooooooooooO. ",
|
||||
" .Xo.......XoO. ",
|
||||
" .Xo.++++o+XoO. ",
|
||||
" .Xo.++++o+XoO. ",
|
||||
" .Xo.++oo++XoO. ",
|
||||
" .Xo.++++++XoO. ",
|
||||
" .Xo.+o++++XoO. ",
|
||||
" .Xo.++++++XoO. ",
|
||||
" .Xo.XXXXXXXoO. ",
|
||||
" .XooooooooooO. ",
|
||||
" .Xo@ooo....oO. ",
|
||||
" .............. .XooooooooooO. ",
|
||||
" .XXXXXXXXXXXX. .XooooooooooO. ",
|
||||
" .XooooooooooO. .OOOOOOOOOOOO. ",
|
||||
" .Xo.......XoO. .............. ",
|
||||
" .Xo.++++o+XoO. @ ",
|
||||
" .Xo.++++o+XoO. @ ",
|
||||
" .Xo.++oo++XoO. @ ",
|
||||
" .Xo.++++++XoO. @ ",
|
||||
" .Xo.+o++++XoO. @ ",
|
||||
" .Xo.++++++XoO. ..... ",
|
||||
" .Xo.XXXXXXXoO. .XXX. ",
|
||||
" .XooooooooooO.@@@@@@.X O. ",
|
||||
" .Xo@ooo....oO. .OOO. ",
|
||||
" .XooooooooooO. ..... ",
|
||||
" .XooooooooooO. ",
|
||||
" .OOOOOOOOOOOO. ",
|
||||
" .............. ",
|
||||
" "};
|
||||
"""
|
||||
|
||||
hard_disk_pixmap = """/* XPM */
|
||||
static char * drivea_xpm[] = {
|
||||
/* width height ncolors chars_per_pixel */
|
||||
"32 32 5 1",
|
||||
/* colors */
|
||||
" s None c None",
|
||||
". c #000000000000",
|
||||
"X c white",
|
||||
"o c #c000c000c000",
|
||||
"O c #800080008000",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .......................... ",
|
||||
" .XXXXXXXXXXXXXXXXXXXXXXXo. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .Xooooooooooooooooo..oooO. ",
|
||||
" .Xooooooooooooooooo..oooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .Xoooooooo.......oooooooO. ",
|
||||
" .Xoo...................oO. ",
|
||||
" .Xoooooooo.......oooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .XooooooooooooooooooooooO. ",
|
||||
" .oOOOOOOOOOOOOOOOOOOOOOOO. ",
|
||||
" .......................... ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
"""
|
||||
|
||||
network_bitmap = """
|
||||
#define netw_width 32
|
||||
#define netw_height 32
|
||||
static unsigned char netw_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40,
|
||||
0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52,
|
||||
0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50,
|
||||
0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50,
|
||||
0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55,
|
||||
0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f,
|
||||
0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00,
|
||||
0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03,
|
||||
0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02,
|
||||
0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
|
||||
0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
"""
|
||||
|
||||
hard_disk_bitmap = """
|
||||
#define drivea_width 32
|
||||
#define drivea_height 32
|
||||
static unsigned char drivea_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a,
|
||||
0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d,
|
||||
0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a,
|
||||
0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d,
|
||||
0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
"""
|
||||
|
||||
def RunSample(w):
|
||||
w.img0 = tkinter.tix.Image('pixmap', data=network_pixmap)
|
||||
if not w.img0:
|
||||
w.img0 = tkinter.tix.Image('bitmap', data=network_bitmap)
|
||||
w.img1 = tkinter.tix.Image('pixmap', data=hard_disk_pixmap)
|
||||
if not w.img0:
|
||||
w.img1 = tkinter.tix.Image('bitmap', data=hard_disk_bitmap)
|
||||
|
||||
hdd = tkinter.tix.Button(w, padx=4, pady=1, width=120)
|
||||
net = tkinter.tix.Button(w, padx=4, pady=1, width=120)
|
||||
|
||||
# Create the first image: we create a line, then put a string,
|
||||
# a space and a image into this line, from left to right.
|
||||
# The result: we have a one-line image that consists of three
|
||||
# individual items
|
||||
#
|
||||
# The tk.calls should be methods in Tix ...
|
||||
w.hdd_img = tkinter.tix.Image('compound', window=hdd)
|
||||
w.hdd_img.tk.call(str(w.hdd_img), 'add', 'line')
|
||||
w.hdd_img.tk.call(str(w.hdd_img), 'add', 'text', '-text', 'Hard Disk',
|
||||
'-underline', '0')
|
||||
w.hdd_img.tk.call(str(w.hdd_img), 'add', 'space', '-width', '7')
|
||||
w.hdd_img.tk.call(str(w.hdd_img), 'add', 'image', '-image', w.img1)
|
||||
|
||||
# Put this image into the first button
|
||||
#
|
||||
hdd['image'] = w.hdd_img
|
||||
|
||||
# Next button
|
||||
w.net_img = tkinter.tix.Image('compound', window=net)
|
||||
w.net_img.tk.call(str(w.net_img), 'add', 'line')
|
||||
w.net_img.tk.call(str(w.net_img), 'add', 'text', '-text', 'Network',
|
||||
'-underline', '0')
|
||||
w.net_img.tk.call(str(w.net_img), 'add', 'space', '-width', '7')
|
||||
w.net_img.tk.call(str(w.net_img), 'add', 'image', '-image', w.img0)
|
||||
|
||||
# Put this image into the first button
|
||||
#
|
||||
net['image'] = w.net_img
|
||||
|
||||
close = tkinter.tix.Button(w, pady=1, text='Close',
|
||||
command=lambda w=w: w.destroy())
|
||||
|
||||
hdd.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
|
||||
net.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
|
||||
close.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,102 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixComboBox widget, which is close
|
||||
# to the MS Window Combo Box control.
|
||||
#
|
||||
import tkinter.tix
|
||||
|
||||
def RunSample(w):
|
||||
global demo_month, demo_year
|
||||
|
||||
top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED)
|
||||
|
||||
demo_month = tkinter.tix.StringVar()
|
||||
demo_year = tkinter.tix.StringVar()
|
||||
|
||||
# $w.top.a is a drop-down combo box. It is not editable -- who wants
|
||||
# to invent new months?
|
||||
#
|
||||
# [Hint] The -options switch sets the options of the subwidgets.
|
||||
# [Hint] We set the label.width subwidget option of both comboboxes to
|
||||
# be 10 so that their labels appear to be aligned.
|
||||
#
|
||||
a = tkinter.tix.ComboBox(top, label="Month: ", dropdown=1,
|
||||
command=select_month, editable=0, variable=demo_month,
|
||||
options='listbox.height 6 label.width 10 label.anchor e')
|
||||
|
||||
# $w.top.b is a non-drop-down combo box. It is not editable: we provide
|
||||
# four choices for the user, but he can enter an alternative year if he
|
||||
# wants to.
|
||||
#
|
||||
# [Hint] Use the padY and anchor options of the label subwidget to
|
||||
# align the label with the entry subwidget.
|
||||
# [Hint] Notice that you should use padY (the NAME of the option) and not
|
||||
# pady (the SWITCH of the option).
|
||||
#
|
||||
b = tkinter.tix.ComboBox(top, label="Year: ", dropdown=0,
|
||||
command=select_year, editable=1, variable=demo_year,
|
||||
options='listbox.height 4 label.padY 5 label.width 10 label.anchor ne')
|
||||
|
||||
a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
|
||||
b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
|
||||
|
||||
a.insert(tkinter.tix.END, 'January')
|
||||
a.insert(tkinter.tix.END, 'February')
|
||||
a.insert(tkinter.tix.END, 'March')
|
||||
a.insert(tkinter.tix.END, 'April')
|
||||
a.insert(tkinter.tix.END, 'May')
|
||||
a.insert(tkinter.tix.END, 'June')
|
||||
a.insert(tkinter.tix.END, 'July')
|
||||
a.insert(tkinter.tix.END, 'August')
|
||||
a.insert(tkinter.tix.END, 'September')
|
||||
a.insert(tkinter.tix.END, 'October')
|
||||
a.insert(tkinter.tix.END, 'November')
|
||||
a.insert(tkinter.tix.END, 'December')
|
||||
|
||||
b.insert(tkinter.tix.END, '1992')
|
||||
b.insert(tkinter.tix.END, '1993')
|
||||
b.insert(tkinter.tix.END, '1994')
|
||||
b.insert(tkinter.tix.END, '1995')
|
||||
b.insert(tkinter.tix.END, '1996')
|
||||
|
||||
# Use "tixSetSilent" to set the values of the combo box if you
|
||||
# don't want your -command procedures (cbx:select_month and
|
||||
# cbx:select_year) to be called.
|
||||
#
|
||||
a.set_silent('January')
|
||||
b.set_silent('1995')
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, width=6,
|
||||
command=lambda w=w: ok_command(w))
|
||||
box.add('cancel', text='Cancel', underline=0, width=6,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
def select_month(event=None):
|
||||
# tixDemo:Status "Month = %s" % demo_month.get()
|
||||
pass
|
||||
|
||||
def select_year(event=None):
|
||||
# tixDemo:Status "Year = %s" % demo_year.get()
|
||||
pass
|
||||
|
||||
def ok_command(w):
|
||||
# tixDemo:Status "Month = %s, Year= %s" % (demo_month.get(), demo_year.get())
|
||||
w.destroy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,122 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixControl widget -- it is an
|
||||
# entry widget with up/down arrow buttons. You can use the arrow buttons
|
||||
# to adjust the value inside the entry widget.
|
||||
#
|
||||
# This example program uses three Control widgets. One lets you select
|
||||
# integer values; one lets you select floating point values and the last
|
||||
# one lets you select a few names.
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
control = DemoControl(root)
|
||||
control.mainloop()
|
||||
control.destroy()
|
||||
|
||||
class DemoControl:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
global demo_maker, demo_thrust, demo_num_engines
|
||||
|
||||
demo_maker = tkinter.tix.StringVar()
|
||||
demo_thrust = tkinter.tix.DoubleVar()
|
||||
demo_num_engines = tkinter.tix.IntVar()
|
||||
demo_maker.set('P&W')
|
||||
demo_thrust.set(20000.0)
|
||||
demo_num_engines.set(2)
|
||||
|
||||
top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED)
|
||||
|
||||
# $w.top.a allows only integer values
|
||||
#
|
||||
# [Hint] The -options switch sets the options of the subwidgets.
|
||||
# [Hint] We set the label.width subwidget option of the Controls to
|
||||
# be 16 so that their labels appear to be aligned.
|
||||
#
|
||||
a = tkinter.tix.Control(top, label='Number of Engines: ', integer=1,
|
||||
variable=demo_num_engines, min=1, max=4,
|
||||
options='entry.width 10 label.width 20 label.anchor e')
|
||||
|
||||
b = tkinter.tix.Control(top, label='Thrust: ', integer=0,
|
||||
min='10000.0', max='60000.0', step=500,
|
||||
variable=demo_thrust,
|
||||
options='entry.width 10 label.width 20 label.anchor e')
|
||||
|
||||
c = tkinter.tix.Control(top, label='Engine Maker: ', value='P&W',
|
||||
variable=demo_maker,
|
||||
options='entry.width 10 label.width 20 label.anchor e')
|
||||
|
||||
# We can't define these in the init because the widget 'c' doesn't
|
||||
# exist yet and we need to reference it
|
||||
c['incrcmd'] = lambda w=c: adjust_maker(w, 1)
|
||||
c['decrcmd'] = lambda w=c: adjust_maker(w, -1)
|
||||
c['validatecmd'] = lambda w=c: validate_maker(w)
|
||||
|
||||
a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
|
||||
b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
|
||||
c.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W)
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, width=6,
|
||||
command=self.okcmd)
|
||||
box.add('cancel', text='Cancel', underline=0, width=6,
|
||||
command=self.quitcmd)
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
def okcmd (self):
|
||||
# tixDemo:Status "Selected %d of %s engines each of thrust %d", (demo_num_engines.get(), demo_maker.get(), demo_thrust.get())
|
||||
self.quitcmd()
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
maker_list = ['P&W', 'GE', 'Rolls Royce']
|
||||
|
||||
def adjust_maker(w, inc):
|
||||
i = maker_list.index(demo_maker.get())
|
||||
i = i + inc
|
||||
if i >= len(maker_list):
|
||||
i = 0
|
||||
elif i < 0:
|
||||
i = len(maker_list) - 1
|
||||
|
||||
# In Tcl/Tix we should return the string maker_list[i]. We can't
|
||||
# do that in Tkinter so we set the global variable. (This works).
|
||||
demo_maker.set(maker_list[i])
|
||||
|
||||
def validate_maker(w):
|
||||
try:
|
||||
i = maker_list.index(demo_maker.get())
|
||||
except ValueError:
|
||||
# Works here though. Why ? Beats me.
|
||||
return maker_list[0]
|
||||
# Works here though. Why ? Beats me.
|
||||
return maker_list[i]
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,131 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program using tixwish.
|
||||
|
||||
# This file demonstrates the use of the tixDirList widget -- you can
|
||||
# use it for the user to select a directory. For example, an installation
|
||||
# program can use the tixDirList widget to ask the user to select the
|
||||
# installation directory for an application.
|
||||
#
|
||||
|
||||
import tkinter.tix, os, copy
|
||||
from tkinter.constants import *
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
dirlist = DemoDirList(root)
|
||||
dirlist.mainloop()
|
||||
dirlist.destroy()
|
||||
|
||||
class DemoDirList:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
# Create the tixDirList and the tixLabelEntry widgets on the on the top
|
||||
# of the dialog box
|
||||
|
||||
# bg = root.tk.eval('tix option get bg')
|
||||
# adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
|
||||
|
||||
top = tkinter.tix.Frame( w, relief=RAISED, bd=1)
|
||||
|
||||
# Create the DirList widget. By default it will show the current
|
||||
# directory
|
||||
#
|
||||
#
|
||||
top.dir = tkinter.tix.DirList(top)
|
||||
top.dir.hlist['width'] = 40
|
||||
|
||||
# When the user presses the ".." button, the selected directory
|
||||
# is "transferred" into the entry widget
|
||||
#
|
||||
top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0)
|
||||
|
||||
# We use a LabelEntry to hold the installation directory. The user
|
||||
# can choose from the DirList widget, or he can type in the directory
|
||||
# manually
|
||||
#
|
||||
top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:",
|
||||
labelside = 'top',
|
||||
options = '''
|
||||
entry.width 40
|
||||
label.anchor w
|
||||
''')
|
||||
|
||||
font = self.root.tk.eval('tix option get fixed_font')
|
||||
# font = self.root.master.tix_option_get('fixed_font')
|
||||
top.ent.entry['font'] = font
|
||||
|
||||
self.dlist_dir = copy.copy(os.curdir)
|
||||
# This should work setting the entry's textvariable
|
||||
top.ent.entry['textvariable'] = self.dlist_dir
|
||||
top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
|
||||
self.copy_name(dir,ent)
|
||||
|
||||
# top.ent.entry.insert(0,'tix'+repr(self))
|
||||
top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
|
||||
|
||||
top.pack( expand='yes', fill='both', side=TOP)
|
||||
top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
|
||||
top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
|
||||
top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
|
||||
|
||||
# Use a ButtonBox to hold the buttons.
|
||||
#
|
||||
box = tkinter.tix.ButtonBox (w, orientation='horizontal')
|
||||
box.add ('ok', text='Ok', underline=0, width=6,
|
||||
command = lambda self=self: self.okcmd () )
|
||||
box.add ('cancel', text='Cancel', underline=0, width=6,
|
||||
command = lambda self=self: self.quitcmd () )
|
||||
|
||||
box.pack( anchor='s', fill='x', side=BOTTOM)
|
||||
|
||||
def copy_name (self, dir, ent):
|
||||
# This should work as it is the entry's textvariable
|
||||
self.dlist_dir = dir.cget('value')
|
||||
# but it isn't so I'll do it manually
|
||||
ent.entry.delete(0,'end')
|
||||
ent.entry.insert(0, self.dlist_dir)
|
||||
|
||||
def okcmd (self):
|
||||
# tixDemo:Status "You have selected the directory" + self.dlist_dir
|
||||
self.quitcmd()
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
# This "if" statement makes it possible to run this script file inside or
|
||||
# outside of the main demo program "tixwidgets.py".
|
||||
#
|
||||
if __name__== '__main__' :
|
||||
import tkinter.messagebox, traceback
|
||||
|
||||
try:
|
||||
root=tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
except:
|
||||
t, v, tb = sys.exc_info()
|
||||
text = "Error running the demo script:\n"
|
||||
for line in traceback.format_exception(t,v,tb):
|
||||
text = text + line + '\n'
|
||||
d = tkinter.messagebox.showerror ( 'Tix Demo Error', text)
|
|
@ -1,117 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program using tixwish.
|
||||
|
||||
# This file demonstrates the use of the tixDirTree widget -- you can
|
||||
# use it for the user to select a directory. For example, an installation
|
||||
# program can use the tixDirTree widget to ask the user to select the
|
||||
# installation directory for an application.
|
||||
#
|
||||
|
||||
import tkinter.tix, os, copy
|
||||
from tkinter.constants import *
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
dirtree = DemoDirTree(root)
|
||||
dirtree.mainloop()
|
||||
dirtree.destroy()
|
||||
|
||||
class DemoDirTree:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
# Create the tixDirTree and the tixLabelEntry widgets on the on the top
|
||||
# of the dialog box
|
||||
|
||||
# bg = root.tk.eval('tix option get bg')
|
||||
# adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0
|
||||
|
||||
top = tkinter.tix.Frame( w, relief=RAISED, bd=1)
|
||||
|
||||
# Create the DirTree widget. By default it will show the current
|
||||
# directory
|
||||
#
|
||||
#
|
||||
top.dir = tkinter.tix.DirTree(top)
|
||||
top.dir.hlist['width'] = 40
|
||||
|
||||
# When the user presses the ".." button, the selected directory
|
||||
# is "transferred" into the entry widget
|
||||
#
|
||||
top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0)
|
||||
|
||||
# We use a LabelEntry to hold the installation directory. The user
|
||||
# can choose from the DirTree widget, or he can type in the directory
|
||||
# manually
|
||||
#
|
||||
top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:",
|
||||
labelside = 'top',
|
||||
options = '''
|
||||
entry.width 40
|
||||
label.anchor w
|
||||
''')
|
||||
|
||||
self.dlist_dir = copy.copy(os.curdir)
|
||||
top.ent.entry['textvariable'] = self.dlist_dir
|
||||
top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \
|
||||
self.copy_name(dir,ent)
|
||||
|
||||
top.ent.entry.bind('<Return>', lambda self=self: self.okcmd () )
|
||||
|
||||
top.pack( expand='yes', fill='both', side=TOP)
|
||||
top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT)
|
||||
top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT)
|
||||
top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT)
|
||||
|
||||
# Use a ButtonBox to hold the buttons.
|
||||
#
|
||||
box = tkinter.tix.ButtonBox (w, orientation='horizontal')
|
||||
box.add ('ok', text='Ok', underline=0, width=6,
|
||||
command = lambda self=self: self.okcmd () )
|
||||
box.add ('cancel', text='Cancel', underline=0, width=6,
|
||||
command = lambda self=self: self.quitcmd () )
|
||||
|
||||
box.pack( anchor='s', fill='x', side=BOTTOM)
|
||||
|
||||
def copy_name (self, dir, ent):
|
||||
# This should work as it is the entry's textvariable
|
||||
self.dlist_dir = dir.cget('value')
|
||||
# but it isn't so I'll do it manually
|
||||
ent.entry.delete(0,'end')
|
||||
ent.entry.insert(0, self.dlist_dir)
|
||||
|
||||
def okcmd (self):
|
||||
# tixDemo:Status "You have selected the directory" + self.dlist_dir
|
||||
self.quitcmd()
|
||||
|
||||
def quitcmd (self):
|
||||
# tixDemo:Status "You have selected the directory" + self.dlist_dir
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
# This "if" statement makes it possible to run this script file inside or
|
||||
# outside of the main demo program "tixwidgets.py".
|
||||
#
|
||||
if __name__== '__main__' :
|
||||
root=tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,119 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixNoteBook widget, which allows
|
||||
# you to lay out your interface using a "notebook" metaphore
|
||||
#
|
||||
import tkinter.tix
|
||||
|
||||
def RunSample(w):
|
||||
global root
|
||||
root = w
|
||||
|
||||
# We use these options to set the sizes of the subwidgets inside the
|
||||
# notebook, so that they are well-aligned on the screen.
|
||||
prefix = tkinter.tix.OptionName(w)
|
||||
if prefix:
|
||||
prefix = '*'+prefix
|
||||
else:
|
||||
prefix = ''
|
||||
w.option_add(prefix+'*TixControl*entry.width', 10)
|
||||
w.option_add(prefix+'*TixControl*label.width', 18)
|
||||
w.option_add(prefix+'*TixControl*label.anchor', tkinter.tix.E)
|
||||
w.option_add(prefix+'*TixNoteBook*tagPadX', 8)
|
||||
|
||||
# Create the notebook widget and set its backpagecolor to gray.
|
||||
# Note that the -backpagecolor option belongs to the "nbframe"
|
||||
# subwidget.
|
||||
nb = tkinter.tix.NoteBook(w, name='nb', ipadx=6, ipady=6)
|
||||
nb['bg'] = 'gray'
|
||||
nb.nbframe['backpagecolor'] = 'gray'
|
||||
|
||||
# Create the two tabs on the notebook. The -underline option
|
||||
# puts a underline on the first character of the labels of the tabs.
|
||||
# Keyboard accelerators will be defined automatically according
|
||||
# to the underlined character.
|
||||
nb.add('hard_disk', label="Hard Disk", underline=0)
|
||||
nb.add('network', label="Network", underline=0)
|
||||
|
||||
nb.pack(expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5 ,side=tkinter.tix.TOP)
|
||||
|
||||
#----------------------------------------
|
||||
# Create the first page
|
||||
#----------------------------------------
|
||||
# Create two frames: one for the common buttons, one for the
|
||||
# other widgets
|
||||
#
|
||||
tab=nb.hard_disk
|
||||
f = tkinter.tix.Frame(tab)
|
||||
common = tkinter.tix.Frame(tab)
|
||||
|
||||
f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1)
|
||||
common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y)
|
||||
|
||||
a = tkinter.tix.Control(f, value=12, label='Access time: ')
|
||||
w = tkinter.tix.Control(f, value=400, label='Write Throughput: ')
|
||||
r = tkinter.tix.Control(f, value=400, label='Read Throughput: ')
|
||||
c = tkinter.tix.Control(f, value=1021, label='Capacity: ')
|
||||
|
||||
a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
|
||||
# Create the common buttons
|
||||
createCommonButtons(common)
|
||||
|
||||
#----------------------------------------
|
||||
# Create the second page
|
||||
#----------------------------------------
|
||||
|
||||
tab = nb.network
|
||||
|
||||
f = tkinter.tix.Frame(tab)
|
||||
common = tkinter.tix.Frame(tab)
|
||||
|
||||
f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1)
|
||||
common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y)
|
||||
|
||||
a = tkinter.tix.Control(f, value=12, label='Access time: ')
|
||||
w = tkinter.tix.Control(f, value=400, label='Write Throughput: ')
|
||||
r = tkinter.tix.Control(f, value=400, label='Read Throughput: ')
|
||||
c = tkinter.tix.Control(f, value=1021, label='Capacity: ')
|
||||
u = tkinter.tix.Control(f, value=10, label='Users: ')
|
||||
|
||||
a.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
w.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
r.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
c.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
u.pack(side=tkinter.tix.TOP, padx=20, pady=2)
|
||||
|
||||
createCommonButtons(common)
|
||||
|
||||
def doDestroy():
|
||||
global root
|
||||
root.destroy()
|
||||
|
||||
def createCommonButtons(master):
|
||||
ok = tkinter.tix.Button(master, name='ok', text='OK', width=6,
|
||||
command=doDestroy)
|
||||
cancel = tkinter.tix.Button(master, name='cancel',
|
||||
text='Cancel', width=6,
|
||||
command=doDestroy)
|
||||
|
||||
ok.pack(side=tkinter.tix.TOP, padx=2, pady=2)
|
||||
cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,68 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixOptionMenu widget -- you can
|
||||
# use it for the user to choose from a fixed set of options
|
||||
#
|
||||
import tkinter.tix
|
||||
|
||||
options = {'text':'Plain Text', 'post':'PostScript', 'html':'HTML',
|
||||
'tex':'LaTeX', 'rtf':'Rich Text Format'}
|
||||
|
||||
def RunSample(w):
|
||||
global demo_opt_from, demo_opt_to
|
||||
|
||||
demo_opt_from = tkinter.tix.StringVar()
|
||||
demo_opt_to = tkinter.tix.StringVar()
|
||||
|
||||
top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED)
|
||||
|
||||
from_file = tkinter.tix.OptionMenu(top, label="From File Format : ",
|
||||
variable=demo_opt_from,
|
||||
options = 'label.width 19 label.anchor e menubutton.width 15')
|
||||
|
||||
to_file = tkinter.tix.OptionMenu(top, label="To File Format : ",
|
||||
variable=demo_opt_to,
|
||||
options='label.width 19 label.anchor e menubutton.width 15')
|
||||
|
||||
# Add the available options to the two OptionMenu widgets
|
||||
#
|
||||
# [Hint] You have to add the options first before you set the
|
||||
# global variables "demo_opt_from" and "demo_opt_to". Otherwise
|
||||
# the OptionMenu widget will complain about "unknown options"!
|
||||
#
|
||||
for opt in options.keys():
|
||||
from_file.add_command(opt, label=options[opt])
|
||||
to_file.add_command(opt, label=options[opt])
|
||||
|
||||
demo_opt_from.set('html')
|
||||
demo_opt_to.set('post')
|
||||
|
||||
from_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6)
|
||||
to_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6)
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, width=6,
|
||||
command=lambda w=w: ok_command(w))
|
||||
box.add('cancel', text='Cancel', underline=0, width=6,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
def ok_command(w):
|
||||
# tixDemo:Status "Convert file from %s to %s" % ( demo_opt_from.get(), demo_opt_to.get())
|
||||
w.destroy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,98 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates the use of the tixPanedWindow widget. This program
|
||||
# is a dummy news reader: the user can adjust the sizes of the list
|
||||
# of artical names and the size of the text widget that shows the body
|
||||
# of the article.
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
panedwin = DemoPanedwin(root)
|
||||
panedwin.mainloop()
|
||||
panedwin.destroy()
|
||||
|
||||
class DemoPanedwin:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
group = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25')
|
||||
group.entry.insert(0,'comp.lang.python')
|
||||
pane = tkinter.tix.PanedWindow(w, orientation='vertical')
|
||||
|
||||
p1 = pane.add('list', min=70, size=100)
|
||||
p2 = pane.add('text', min=70)
|
||||
list = tkinter.tix.ScrolledListBox(p1)
|
||||
list.listbox['width'] = 80
|
||||
list.listbox['height'] = 5
|
||||
text = tkinter.tix.ScrolledText(p2)
|
||||
text.text['width'] = 80
|
||||
text.text['height'] = 20
|
||||
|
||||
list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health")
|
||||
list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health")
|
||||
list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)")
|
||||
list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)")
|
||||
list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)")
|
||||
list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)")
|
||||
list.listbox.insert(tkinter.tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)")
|
||||
|
||||
text.text['bg'] = list.listbox['bg']
|
||||
text.text['wrap'] = 'none'
|
||||
text.text.insert(tkinter.tix.END, """
|
||||
Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220
|
||||
Lines 353 A new way to put text and bitmaps together iNo responses
|
||||
ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania
|
||||
|
||||
Hi,
|
||||
|
||||
I have implemented a new image type called "compound". It allows you
|
||||
to glue together a bunch of bitmaps, images and text strings together
|
||||
to form a bigger image. Then you can use this image with widgets that
|
||||
support the -image option. For example, you can display a text string string
|
||||
together with a bitmap, at the same time, inside a TK button widget.
|
||||
""")
|
||||
text.text['state'] = 'disabled'
|
||||
|
||||
list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6)
|
||||
text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6)
|
||||
|
||||
group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH)
|
||||
pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, width=6,
|
||||
command=self.quitcmd)
|
||||
box.add('cancel', text='Cancel', underline=0, width=6,
|
||||
command=self.quitcmd)
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,57 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program using tixwish.
|
||||
|
||||
# This file demonstrates the use of the tixPopupMenu widget.
|
||||
#
|
||||
import tkinter.tix
|
||||
|
||||
def RunSample(w):
|
||||
# We create the frame and the button, then we'll bind the PopupMenu
|
||||
# to both widgets. The result is, when you press the right mouse
|
||||
# button over $w.top or $w.top.but, the PopupMenu will come up.
|
||||
#
|
||||
top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1)
|
||||
but = tkinter.tix.Button(top, text='Press the right mouse button over this button or its surrounding area')
|
||||
but.pack(expand=1, fill=tkinter.tix.BOTH, padx=50, pady=50)
|
||||
|
||||
p = tkinter.tix.PopupMenu(top, title='Popup Test')
|
||||
p.bind_widget(top)
|
||||
p.bind_widget(but)
|
||||
|
||||
# Set the entries inside the PopupMenu widget.
|
||||
# [Hint] You have to manipulate the "menu" subwidget.
|
||||
# $w.top.p itself is NOT a menu widget.
|
||||
# [Hint] Watch carefully how the sub-menu is created
|
||||
#
|
||||
p.menu.add_command(label='Desktop', underline=0)
|
||||
p.menu.add_command(label='Select', underline=0)
|
||||
p.menu.add_command(label='Find', underline=0)
|
||||
p.menu.add_command(label='System', underline=1)
|
||||
p.menu.add_command(label='Help', underline=0)
|
||||
m1 = tkinter.tix.Menu(p.menu)
|
||||
m1.add_command(label='Hello')
|
||||
p.menu.add_cascade(label='More', menu=m1)
|
||||
|
||||
but.pack(side=tkinter.tix.TOP, padx=40, pady=50)
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, width=6,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.add('cancel', text='Cancel', underline=0, width=6,
|
||||
command=lambda w=w: w.destroy())
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
|
@ -1,131 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program using tixwish.
|
||||
|
||||
# This file demonstrates the use of the tixScrolledHList widget.
|
||||
#
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
shlist = DemoSHList(root)
|
||||
shlist.mainloop()
|
||||
shlist.destroy()
|
||||
|
||||
class DemoSHList:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
# We create the frame and the ScrolledHList widget
|
||||
# at the top of the dialog box
|
||||
#
|
||||
top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1)
|
||||
|
||||
# Put a simple hierachy into the HList (two levels). Use colors and
|
||||
# separator widgets (frames) to make the list look fancy
|
||||
#
|
||||
top.a = tkinter.tix.ScrolledHList(top)
|
||||
top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP)
|
||||
|
||||
# This is our little relational database
|
||||
#
|
||||
bosses = [
|
||||
('jeff', 'Jeff Waxman'),
|
||||
('john', 'John Lee'),
|
||||
('peter', 'Peter Kenson')
|
||||
]
|
||||
|
||||
employees = [
|
||||
('alex', 'john', 'Alex Kellman'),
|
||||
('alan', 'john', 'Alan Adams'),
|
||||
('andy', 'peter', 'Andreas Crawford'),
|
||||
('doug', 'jeff', 'Douglas Bloom'),
|
||||
('jon', 'peter', 'Jon Baraki'),
|
||||
('chris', 'jeff', 'Chris Geoffrey'),
|
||||
('chuck', 'jeff', 'Chuck McLean')
|
||||
]
|
||||
|
||||
hlist=top.a.hlist
|
||||
|
||||
# Let configure the appearance of the HList subwidget
|
||||
#
|
||||
hlist.config( separator='.', width=25, drawbranch=0, indent=10)
|
||||
|
||||
count=0
|
||||
for boss,name in bosses :
|
||||
if count :
|
||||
f=tkinter.tix.Frame(hlist, name='sep%d' % count, height=2, width=150,
|
||||
bd=2, relief=tkinter.tix.SUNKEN )
|
||||
|
||||
hlist.add_child( itemtype=tkinter.tix.WINDOW,
|
||||
window=f, state=tkinter.tix.DISABLED )
|
||||
|
||||
hlist.add(boss, itemtype=tkinter.tix.TEXT, text=name)
|
||||
count = count+1
|
||||
|
||||
|
||||
for person,boss,name in employees :
|
||||
# '.' is the separator character we chose above
|
||||
#
|
||||
key= boss + '.' + person
|
||||
# ^^^^ ^^^^^^
|
||||
# parent entryPath / child's name
|
||||
|
||||
hlist.add( key, text=name )
|
||||
|
||||
# [Hint] Make sure the keys (e.g. 'boss.person') you choose
|
||||
# are unique names. If you cannot be sure of this (because of
|
||||
# the structure of your database, e.g.) you can use the
|
||||
# "add_child" command instead:
|
||||
#
|
||||
# hlist.addchild( boss, text=name)
|
||||
# ^^^^
|
||||
# parent entryPath
|
||||
|
||||
|
||||
# Use a ButtonBox to hold the buttons.
|
||||
#
|
||||
box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL )
|
||||
box.add( 'ok', text='Ok', underline=0, width=6,
|
||||
command = self.okcmd)
|
||||
|
||||
box.add( 'cancel', text='Cancel', underline=0, width=6,
|
||||
command = self.quitcmd)
|
||||
|
||||
box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 )
|
||||
|
||||
def okcmd (self):
|
||||
self.quitcmd()
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
|
||||
# This "if" statement makes it possible to run this script file inside or
|
||||
# outside of the main demo program "tixwidgets.py".
|
||||
#
|
||||
if __name__== '__main__' :
|
||||
root=tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,168 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidget": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program using tixwish.
|
||||
|
||||
# This file demonstrates how to use multiple columns and multiple styles
|
||||
# in the tixHList widget
|
||||
#
|
||||
# In a tixHList widget, you can have one ore more columns.
|
||||
#
|
||||
|
||||
import tkinter.tix
|
||||
|
||||
TCL_ALL_EVENTS = 0
|
||||
|
||||
def RunSample (root):
|
||||
shlist = DemoSHList(root)
|
||||
shlist.mainloop()
|
||||
shlist.destroy()
|
||||
|
||||
class DemoSHList:
|
||||
def __init__(self, w):
|
||||
self.root = w
|
||||
self.exit = -1
|
||||
|
||||
z = w.winfo_toplevel()
|
||||
z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd())
|
||||
|
||||
# We create the frame and the ScrolledHList widget
|
||||
# at the top of the dialog box
|
||||
#
|
||||
top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1)
|
||||
|
||||
# Put a simple hierachy into the HList (two levels). Use colors and
|
||||
# separator widgets (frames) to make the list look fancy
|
||||
#
|
||||
top.a = tkinter.tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' )
|
||||
top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP)
|
||||
|
||||
hlist=top.a.hlist
|
||||
|
||||
# Create the title for the HList widget
|
||||
# >> Notice that we have set the hlist.header subwidget option to true
|
||||
# so that the header is displayed
|
||||
#
|
||||
|
||||
boldfont=hlist.tk.call('tix','option','get','bold_font')
|
||||
|
||||
# First some styles for the headers
|
||||
style={}
|
||||
style['header'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist,
|
||||
anchor=tkinter.tix.CENTER, padx=8, pady=2, font = boldfont )
|
||||
|
||||
hlist.header_create(0, itemtype=tkinter.tix.TEXT, text='Name',
|
||||
style=style['header'])
|
||||
hlist.header_create(1, itemtype=tkinter.tix.TEXT, text='Position',
|
||||
style=style['header'])
|
||||
|
||||
# Notice that we use 3 columns in the hlist widget. This way when the user
|
||||
# expands the windows wide, the right side of the header doesn't look
|
||||
# chopped off. The following line ensures that the 3 column header is
|
||||
# not shown unless the hlist window is wider than its contents.
|
||||
#
|
||||
hlist.column_width(2,0)
|
||||
|
||||
# This is our little relational database
|
||||
#
|
||||
boss = ('doe', 'John Doe', 'Director')
|
||||
|
||||
managers = [
|
||||
('jeff', 'Jeff Waxman', 'Manager'),
|
||||
('john', 'John Lee', 'Manager'),
|
||||
('peter', 'Peter Kenson', 'Manager')
|
||||
]
|
||||
|
||||
employees = [
|
||||
('alex', 'john', 'Alex Kellman', 'Clerk'),
|
||||
('alan', 'john', 'Alan Adams', 'Clerk'),
|
||||
('andy', 'peter', 'Andreas Crawford', 'Salesman'),
|
||||
('doug', 'jeff', 'Douglas Bloom', 'Clerk'),
|
||||
('jon', 'peter', 'Jon Baraki', 'Salesman'),
|
||||
('chris', 'jeff', 'Chris Geoffrey', 'Clerk'),
|
||||
('chuck', 'jeff', 'Chuck McLean', 'Cleaner')
|
||||
]
|
||||
|
||||
style['mgr_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist)
|
||||
|
||||
style['mgr_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist)
|
||||
|
||||
style['empl_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist)
|
||||
|
||||
style['empl_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist)
|
||||
|
||||
# Let configure the appearance of the HList subwidget
|
||||
#
|
||||
hlist.config(separator='.', width=25, drawbranch=0, indent=10)
|
||||
hlist.column_width(0, chars=20)
|
||||
|
||||
# Create the boss
|
||||
#
|
||||
hlist.add ('.', itemtype=tkinter.tix.TEXT, text=boss[1],
|
||||
style=style['mgr_name'])
|
||||
hlist.item_create('.', 1, itemtype=tkinter.tix.TEXT, text=boss[2],
|
||||
style=style['mgr_posn'])
|
||||
|
||||
# Create the managers
|
||||
#
|
||||
|
||||
for key,name,posn in managers :
|
||||
e= '.'+ key
|
||||
hlist.add(e, itemtype=tkinter.tix.TEXT, text=name,
|
||||
style=style['mgr_name'])
|
||||
hlist.item_create(e, 1, itemtype=tkinter.tix.TEXT, text=posn,
|
||||
style=style['mgr_posn'])
|
||||
|
||||
|
||||
for key,mgr,name,posn in employees :
|
||||
# "." is the separator character we chose above
|
||||
|
||||
entrypath = '.' + mgr + '.' + key
|
||||
|
||||
# ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
|
||||
# parent entryPath / child's name
|
||||
|
||||
hlist.add(entrypath, text=name, style=style['empl_name'])
|
||||
hlist.item_create(entrypath, 1, itemtype=tkinter.tix.TEXT,
|
||||
text = posn, style = style['empl_posn'] )
|
||||
|
||||
|
||||
# Use a ButtonBox to hold the buttons.
|
||||
#
|
||||
box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL )
|
||||
box.add( 'ok', text='Ok', underline=0, width=6,
|
||||
command = self.okcmd )
|
||||
|
||||
box.add( 'cancel', text='Cancel', underline=0, width=6,
|
||||
command = self.quitcmd )
|
||||
|
||||
box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 )
|
||||
|
||||
def okcmd (self):
|
||||
self.quitcmd()
|
||||
|
||||
def quitcmd (self):
|
||||
self.exit = 0
|
||||
|
||||
def mainloop(self):
|
||||
while self.exit < 0:
|
||||
self.root.tk.dooneevent(TCL_ALL_EVENTS)
|
||||
|
||||
def destroy (self):
|
||||
self.root.destroy()
|
||||
|
||||
|
||||
# This "if" statement makes it possible to run this script file inside or
|
||||
# outside of the main demo program "tixwidgets.py".
|
||||
#
|
||||
if __name__== '__main__' :
|
||||
root=tkinter.tix.Tk()
|
||||
RunSample(root)
|
|
@ -1,80 +0,0 @@
|
|||
# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Tix Demostration Program
|
||||
#
|
||||
# This sample program is structured in such a way so that it can be
|
||||
# executed from the Tix demo program "tixwidgets.py": it must have a
|
||||
# procedure called "RunSample". It should also have the "if" statment
|
||||
# at the end of this file so that it can be run as a standalone
|
||||
# program.
|
||||
|
||||
# This file demonstrates how to use the TixTree widget to display
|
||||
# dynamic hierachical data (the files in the Unix file system)
|
||||
#
|
||||
|
||||
import tkinter.tix, os
|
||||
|
||||
def RunSample(w):
|
||||
top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1)
|
||||
tree = tkinter.tix.Tree(top, options='separator "/"')
|
||||
tree.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.LEFT)
|
||||
tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir)
|
||||
|
||||
# The / directory is added in the "open" mode. The user can open it
|
||||
# and then browse its subdirectories ...
|
||||
adddir(tree, "/")
|
||||
|
||||
box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL)
|
||||
box.add('ok', text='Ok', underline=0, command=w.destroy, width=6)
|
||||
box.add('cancel', text='Cancel', underline=0, command=w.destroy, width=6)
|
||||
box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X)
|
||||
top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1)
|
||||
|
||||
def adddir(tree, dir):
|
||||
if dir == '/':
|
||||
text = '/'
|
||||
else:
|
||||
text = os.path.basename(dir)
|
||||
tree.hlist.add(dir, itemtype=tkinter.tix.IMAGETEXT, text=text,
|
||||
image=tree.tk.call('tix', 'getimage', 'folder'))
|
||||
try:
|
||||
os.listdir(dir)
|
||||
tree.setmode(dir, 'open')
|
||||
except os.error:
|
||||
# No read permission ?
|
||||
pass
|
||||
|
||||
# This function is called whenever the user presses the (+) indicator or
|
||||
# double clicks on a directory whose mode is "open". It loads the files
|
||||
# inside that directory into the Tree widget.
|
||||
#
|
||||
# Note we didn't specify the closecmd option for the Tree widget, so it
|
||||
# performs the default action when the user presses the (-) indicator or
|
||||
# double clicks on a directory whose mode is "close": hide all of its child
|
||||
# entries
|
||||
def opendir(tree, dir):
|
||||
entries = tree.hlist.info_children(dir)
|
||||
if entries:
|
||||
# We have already loaded this directory. Let's just
|
||||
# show all the child entries
|
||||
#
|
||||
# Note: since we load the directory only once, it will not be
|
||||
# refreshed if the you add or remove files from this
|
||||
# directory.
|
||||
#
|
||||
for entry in entries:
|
||||
tree.hlist.show_entry(entry)
|
||||
files = os.listdir(dir)
|
||||
for file in files:
|
||||
if os.path.isdir(dir + '/' + file):
|
||||
adddir(tree, dir + '/' + file)
|
||||
else:
|
||||
tree.hlist.add(dir + '/' + file, itemtype=tkinter.tix.IMAGETEXT, text=file,
|
||||
image=tree.tk.call('tix', 'getimage', 'file'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tkinter.tix.Tk()
|
||||
RunSample(root)
|
||||
root.mainloop()
|
File diff suppressed because it is too large
Load diff
|
@ -1,11 +0,0 @@
|
|||
Several collections of example code for Tkinter.
|
||||
|
||||
See the toplevel README for an explanation of the difference between
|
||||
Tkinter and _tkinter, how to enable the Python Tk interface, and where
|
||||
to get Matt Conway's lifesaver document.
|
||||
|
||||
Subdirectories:
|
||||
|
||||
guido my original example set (fairly random collection)
|
||||
matt Matt Conway's examples, to go with his lifesaver document
|
||||
ttk Examples using the ttk module
|
|
@ -1,460 +0,0 @@
|
|||
|
||||
# The options of a widget are described by the following attributes
|
||||
# of the Pack and Widget dialogs:
|
||||
#
|
||||
# Dialog.current: {name: value}
|
||||
# -- changes during Widget's lifetime
|
||||
#
|
||||
# Dialog.options: {name: (default, klass)}
|
||||
# -- depends on widget class only
|
||||
#
|
||||
# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
|
||||
# -- totally static, though different between PackDialog and WidgetDialog
|
||||
# (but even that could be unified)
|
||||
|
||||
from tkinter import *
|
||||
|
||||
|
||||
class Option:
|
||||
|
||||
varclass = StringVar # May be overridden
|
||||
|
||||
def __init__(self, dialog, option):
|
||||
self.dialog = dialog
|
||||
self.option = option
|
||||
self.master = dialog.top
|
||||
self.default, self.klass = dialog.options[option]
|
||||
self.var = self.varclass(self.master)
|
||||
self.frame = Frame(self.master)
|
||||
self.frame.pack(fill=X)
|
||||
self.label = Label(self.frame, text=(option + ":"))
|
||||
self.label.pack(side=LEFT)
|
||||
self.update()
|
||||
self.addoption()
|
||||
|
||||
def refresh(self):
|
||||
self.dialog.refresh()
|
||||
self.update()
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
self.current = self.dialog.current[self.option]
|
||||
except KeyError:
|
||||
self.current = self.default
|
||||
self.var.set(self.current)
|
||||
|
||||
def set(self, e=None): # Should be overridden
|
||||
pass
|
||||
|
||||
|
||||
class BooleanOption(Option):
|
||||
|
||||
varclass = BooleanVar
|
||||
|
||||
def addoption(self):
|
||||
self.button = Checkbutton(self.frame,
|
||||
text='on/off',
|
||||
onvalue=1,
|
||||
offvalue=0,
|
||||
variable=self.var,
|
||||
relief=RAISED,
|
||||
borderwidth=2,
|
||||
command=self.set)
|
||||
self.button.pack(side=RIGHT)
|
||||
|
||||
|
||||
class EnumOption(Option):
|
||||
|
||||
def addoption(self):
|
||||
self.button = Menubutton(self.frame,
|
||||
textvariable=self.var,
|
||||
relief=RAISED, borderwidth=2)
|
||||
self.button.pack(side=RIGHT)
|
||||
self.menu = Menu(self.button)
|
||||
self.button['menu'] = self.menu
|
||||
for v in self.dialog.classes[self.klass]:
|
||||
self.menu.add_radiobutton(
|
||||
label=v,
|
||||
variable=self.var,
|
||||
value=v,
|
||||
command=self.set)
|
||||
|
||||
|
||||
class StringOption(Option):
|
||||
|
||||
def addoption(self):
|
||||
self.entry = Entry(self.frame,
|
||||
textvariable=self.var,
|
||||
width=10,
|
||||
relief=SUNKEN,
|
||||
borderwidth=2)
|
||||
self.entry.pack(side=RIGHT, fill=X, expand=1)
|
||||
self.entry.bind('<Return>', self.set)
|
||||
|
||||
|
||||
class ReadonlyOption(Option):
|
||||
|
||||
def addoption(self):
|
||||
self.label = Label(self.frame, textvariable=self.var,
|
||||
anchor=E)
|
||||
self.label.pack(side=RIGHT)
|
||||
|
||||
|
||||
class Dialog:
|
||||
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
self.fixclasses()
|
||||
self.refresh()
|
||||
self.top = Toplevel(self.master)
|
||||
self.top.title(self.__class__.__name__)
|
||||
self.top.minsize(1, 1)
|
||||
self.addchoices()
|
||||
|
||||
def refresh(self): pass # Must override
|
||||
|
||||
def fixclasses(self): pass # May override
|
||||
|
||||
def addchoices(self):
|
||||
self.choices = {}
|
||||
list = []
|
||||
for k, dc in self.options.items():
|
||||
list.append((k, dc))
|
||||
list.sort()
|
||||
for k, (d, c) in list:
|
||||
try:
|
||||
cl = self.classes[c]
|
||||
except KeyError:
|
||||
cl = 'unknown'
|
||||
if type(cl) is tuple:
|
||||
cl = self.enumoption
|
||||
elif cl == 'boolean':
|
||||
cl = self.booleanoption
|
||||
elif cl == 'readonly':
|
||||
cl = self.readonlyoption
|
||||
else:
|
||||
cl = self.stringoption
|
||||
self.choices[k] = cl(self, k)
|
||||
|
||||
# Must override:
|
||||
options = {}
|
||||
classes = {}
|
||||
|
||||
# May override:
|
||||
booleanoption = BooleanOption
|
||||
stringoption = StringOption
|
||||
enumoption = EnumOption
|
||||
readonlyoption = ReadonlyOption
|
||||
|
||||
|
||||
class PackDialog(Dialog):
|
||||
|
||||
def __init__(self, widget):
|
||||
self.widget = widget
|
||||
Dialog.__init__(self, widget)
|
||||
|
||||
def refresh(self):
|
||||
self.current = self.widget.info()
|
||||
self.current['.class'] = self.widget.winfo_class()
|
||||
self.current['.name'] = self.widget._w
|
||||
|
||||
class packoption: # Mix-in class
|
||||
def set(self, e=None):
|
||||
self.current = self.var.get()
|
||||
try:
|
||||
self.dialog.widget.pack(**{self.option: self.current})
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
self.refresh()
|
||||
|
||||
class booleanoption(packoption, BooleanOption): pass
|
||||
class enumoption(packoption, EnumOption): pass
|
||||
class stringoption(packoption, StringOption): pass
|
||||
class readonlyoption(packoption, ReadonlyOption): pass
|
||||
|
||||
options = {
|
||||
'.class': (None, 'Class'),
|
||||
'.name': (None, 'Name'),
|
||||
'after': (None, 'Widget'),
|
||||
'anchor': ('center', 'Anchor'),
|
||||
'before': (None, 'Widget'),
|
||||
'expand': ('no', 'Boolean'),
|
||||
'fill': ('none', 'Fill'),
|
||||
'in': (None, 'Widget'),
|
||||
'ipadx': (0, 'Pad'),
|
||||
'ipady': (0, 'Pad'),
|
||||
'padx': (0, 'Pad'),
|
||||
'pady': (0, 'Pad'),
|
||||
'side': ('top', 'Side'),
|
||||
}
|
||||
|
||||
classes = {
|
||||
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
|
||||
'Boolean': 'boolean',
|
||||
'Class': 'readonly',
|
||||
'Expand': 'boolean',
|
||||
'Fill': (NONE, X, Y, BOTH),
|
||||
'Name': 'readonly',
|
||||
'Pad': 'pixel',
|
||||
'Side': (TOP, RIGHT, BOTTOM, LEFT),
|
||||
'Widget': 'readonly',
|
||||
}
|
||||
|
||||
class RemotePackDialog(PackDialog):
|
||||
|
||||
def __init__(self, master, app, widget):
|
||||
self.master = master
|
||||
self.app = app
|
||||
self.widget = widget
|
||||
self.refresh()
|
||||
self.top = Toplevel(self.master)
|
||||
self.top.title(self.app + ' PackDialog')
|
||||
self.top.minsize(1, 1)
|
||||
self.addchoices()
|
||||
|
||||
def refresh(self):
|
||||
try:
|
||||
words = self.master.tk.splitlist(
|
||||
self.master.send(self.app,
|
||||
'pack',
|
||||
'info',
|
||||
self.widget))
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
return
|
||||
dict = {}
|
||||
for i in range(0, len(words), 2):
|
||||
key = words[i][1:]
|
||||
value = words[i+1]
|
||||
dict[key] = value
|
||||
dict['.class'] = self.master.send(self.app,
|
||||
'winfo',
|
||||
'class',
|
||||
self.widget)
|
||||
dict['.name'] = self.widget
|
||||
self.current = dict
|
||||
|
||||
class remotepackoption: # Mix-in class
|
||||
def set(self, e=None):
|
||||
self.current = self.var.get()
|
||||
try:
|
||||
self.dialog.master.send(
|
||||
self.dialog.app,
|
||||
'pack',
|
||||
'config',
|
||||
self.dialog.widget,
|
||||
'-'+self.option,
|
||||
self.dialog.master.tk.merge(
|
||||
self.current))
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
self.refresh()
|
||||
|
||||
class booleanoption(remotepackoption, BooleanOption): pass
|
||||
class enumoption(remotepackoption, EnumOption): pass
|
||||
class stringoption(remotepackoption, StringOption): pass
|
||||
class readonlyoption(remotepackoption, ReadonlyOption): pass
|
||||
|
||||
|
||||
class WidgetDialog(Dialog):
|
||||
|
||||
def __init__(self, widget):
|
||||
self.widget = widget
|
||||
self.klass = widget.winfo_class()
|
||||
Dialog.__init__(self, widget)
|
||||
|
||||
def fixclasses(self):
|
||||
if self.klass in self.addclasses:
|
||||
classes = {}
|
||||
for c in (self.classes,
|
||||
self.addclasses[self.klass]):
|
||||
for k in c.keys():
|
||||
classes[k] = c[k]
|
||||
self.classes = classes
|
||||
|
||||
def refresh(self):
|
||||
self.configuration = self.widget.config()
|
||||
self.update()
|
||||
self.current['.class'] = self.widget.winfo_class()
|
||||
self.current['.name'] = self.widget._w
|
||||
|
||||
def update(self):
|
||||
self.current = {}
|
||||
self.options = {}
|
||||
for k, v in self.configuration.items():
|
||||
if len(v) > 4:
|
||||
self.current[k] = v[4]
|
||||
self.options[k] = v[3], v[2] # default, klass
|
||||
self.options['.class'] = (None, 'Class')
|
||||
self.options['.name'] = (None, 'Name')
|
||||
|
||||
class widgetoption: # Mix-in class
|
||||
def set(self, e=None):
|
||||
self.current = self.var.get()
|
||||
try:
|
||||
self.dialog.widget[self.option] = self.current
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
self.refresh()
|
||||
|
||||
class booleanoption(widgetoption, BooleanOption): pass
|
||||
class enumoption(widgetoption, EnumOption): pass
|
||||
class stringoption(widgetoption, StringOption): pass
|
||||
class readonlyoption(widgetoption, ReadonlyOption): pass
|
||||
|
||||
# Universal classes
|
||||
classes = {
|
||||
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
|
||||
'Aspect': 'integer',
|
||||
'Background': 'color',
|
||||
'Bitmap': 'bitmap',
|
||||
'BorderWidth': 'pixel',
|
||||
'Class': 'readonly',
|
||||
'CloseEnough': 'double',
|
||||
'Command': 'command',
|
||||
'Confine': 'boolean',
|
||||
'Cursor': 'cursor',
|
||||
'CursorWidth': 'pixel',
|
||||
'DisabledForeground': 'color',
|
||||
'ExportSelection': 'boolean',
|
||||
'Font': 'font',
|
||||
'Foreground': 'color',
|
||||
'From': 'integer',
|
||||
'Geometry': 'geometry',
|
||||
'Height': 'pixel',
|
||||
'InsertWidth': 'time',
|
||||
'Justify': (LEFT, CENTER, RIGHT),
|
||||
'Label': 'string',
|
||||
'Length': 'pixel',
|
||||
'MenuName': 'widget',
|
||||
'Name': 'readonly',
|
||||
'OffTime': 'time',
|
||||
'OnTime': 'time',
|
||||
'Orient': (HORIZONTAL, VERTICAL),
|
||||
'Pad': 'pixel',
|
||||
'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
|
||||
'RepeatDelay': 'time',
|
||||
'RepeatInterval': 'time',
|
||||
'ScrollCommand': 'command',
|
||||
'ScrollIncrement': 'pixel',
|
||||
'ScrollRegion': 'rectangle',
|
||||
'ShowValue': 'boolean',
|
||||
'SetGrid': 'boolean',
|
||||
'Sliderforeground': 'color',
|
||||
'SliderLength': 'pixel',
|
||||
'Text': 'string',
|
||||
'TickInterval': 'integer',
|
||||
'To': 'integer',
|
||||
'Underline': 'index',
|
||||
'Variable': 'variable',
|
||||
'Value': 'string',
|
||||
'Width': 'pixel',
|
||||
'Wrap': (NONE, CHAR, WORD),
|
||||
}
|
||||
|
||||
# Classes that (may) differ per widget type
|
||||
_tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
|
||||
_bistate = {'State': (NORMAL, DISABLED)}
|
||||
addclasses = {
|
||||
'Button': _tristate,
|
||||
'Radiobutton': _tristate,
|
||||
'Checkbutton': _tristate,
|
||||
'Entry': _bistate,
|
||||
'Text': _bistate,
|
||||
'Menubutton': _tristate,
|
||||
'Slider': _bistate,
|
||||
}
|
||||
|
||||
|
||||
class RemoteWidgetDialog(WidgetDialog):
|
||||
|
||||
def __init__(self, master, app, widget):
|
||||
self.app = app
|
||||
self.widget = widget
|
||||
self.klass = master.send(self.app,
|
||||
'winfo',
|
||||
'class',
|
||||
self.widget)
|
||||
Dialog.__init__(self, master)
|
||||
|
||||
def refresh(self):
|
||||
try:
|
||||
items = self.master.tk.splitlist(
|
||||
self.master.send(self.app,
|
||||
self.widget,
|
||||
'config'))
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
return
|
||||
dict = {}
|
||||
for item in items:
|
||||
words = self.master.tk.splitlist(item)
|
||||
key = words[0][1:]
|
||||
value = (key,) + words[1:]
|
||||
dict[key] = value
|
||||
self.configuration = dict
|
||||
self.update()
|
||||
self.current['.class'] = self.klass
|
||||
self.current['.name'] = self.widget
|
||||
|
||||
class remotewidgetoption: # Mix-in class
|
||||
def set(self, e=None):
|
||||
self.current = self.var.get()
|
||||
try:
|
||||
self.dialog.master.send(
|
||||
self.dialog.app,
|
||||
self.dialog.widget,
|
||||
'config',
|
||||
'-'+self.option,
|
||||
self.current)
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
self.refresh()
|
||||
|
||||
class booleanoption(remotewidgetoption, BooleanOption): pass
|
||||
class enumoption(remotewidgetoption, EnumOption): pass
|
||||
class stringoption(remotewidgetoption, StringOption): pass
|
||||
class readonlyoption(remotewidgetoption, ReadonlyOption): pass
|
||||
|
||||
|
||||
def test():
|
||||
import sys
|
||||
root = Tk()
|
||||
root.minsize(1, 1)
|
||||
if sys.argv[1:]:
|
||||
remotetest(root, sys.argv[1])
|
||||
else:
|
||||
frame = Frame(root, name='frame')
|
||||
frame.pack(expand=1, fill=BOTH)
|
||||
button = Button(frame, name='button', text='button')
|
||||
button.pack(expand=1)
|
||||
canvas = Canvas(frame, name='canvas')
|
||||
canvas.pack()
|
||||
fpd = PackDialog(frame)
|
||||
fwd = WidgetDialog(frame)
|
||||
bpd = PackDialog(button)
|
||||
bwd = WidgetDialog(button)
|
||||
cpd = PackDialog(canvas)
|
||||
cwd = WidgetDialog(canvas)
|
||||
root.mainloop()
|
||||
|
||||
def remotetest(root, app):
|
||||
from listtree import listtree
|
||||
list = listtree(root, app)
|
||||
list.bind('<Any-Double-1>', opendialogs)
|
||||
list.app = app # Pass it on to handler
|
||||
|
||||
def opendialogs(e):
|
||||
list = e.widget
|
||||
sel = list.curselection()
|
||||
for i in sel:
|
||||
item = list.get(i)
|
||||
widget = item.split()[0]
|
||||
RemoteWidgetDialog(list, list.app, widget)
|
||||
if widget == '.': continue
|
||||
try:
|
||||
RemotePackDialog(list, list.app, widget)
|
||||
except TclError as msg:
|
||||
print(msg)
|
||||
|
||||
test()
|
|
@ -1,50 +0,0 @@
|
|||
# Brownian motion -- an example of a multi-threaded Tkinter program.
|
||||
|
||||
from tkinter import *
|
||||
import random
|
||||
import threading
|
||||
import time
|
||||
import sys
|
||||
|
||||
WIDTH = 400
|
||||
HEIGHT = 300
|
||||
SIGMA = 10
|
||||
BUZZ = 2
|
||||
RADIUS = 2
|
||||
LAMBDA = 10
|
||||
FILL = 'red'
|
||||
|
||||
stop = 0 # Set when main loop exits
|
||||
|
||||
def particle(canvas):
|
||||
r = RADIUS
|
||||
x = random.gauss(WIDTH/2.0, SIGMA)
|
||||
y = random.gauss(HEIGHT/2.0, SIGMA)
|
||||
p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL)
|
||||
while not stop:
|
||||
dx = random.gauss(0, BUZZ)
|
||||
dy = random.gauss(0, BUZZ)
|
||||
dt = random.expovariate(LAMBDA)
|
||||
try:
|
||||
canvas.move(p, dx, dy)
|
||||
except TclError:
|
||||
break
|
||||
time.sleep(dt)
|
||||
|
||||
def main():
|
||||
global stop
|
||||
root = Tk()
|
||||
canvas = Canvas(root, width=WIDTH, height=HEIGHT)
|
||||
canvas.pack(fill='both', expand=1)
|
||||
np = 30
|
||||
if sys.argv[1:]:
|
||||
np = int(sys.argv[1])
|
||||
for i in range(np):
|
||||
t = threading.Thread(target=particle, args=(canvas,))
|
||||
t.start()
|
||||
try:
|
||||
root.mainloop()
|
||||
finally:
|
||||
stop = 1
|
||||
|
||||
main()
|
|
@ -1,55 +0,0 @@
|
|||
# Brownian motion -- an example of a NON multi-threaded Tkinter program ;)
|
||||
# By Michele Simoniato, inspired by brownian.py
|
||||
|
||||
from tkinter import *
|
||||
import random
|
||||
import sys
|
||||
|
||||
WIDTH = 400
|
||||
HEIGHT = 300
|
||||
SIGMA = 10
|
||||
BUZZ = 2
|
||||
RADIUS = 2
|
||||
LAMBDA = 10
|
||||
FILL = 'red'
|
||||
|
||||
stop = 0 # Set when main loop exits
|
||||
root = None # main window
|
||||
|
||||
def particle(canvas): # particle = iterator over the moves
|
||||
r = RADIUS
|
||||
x = random.gauss(WIDTH/2.0, SIGMA)
|
||||
y = random.gauss(HEIGHT/2.0, SIGMA)
|
||||
p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL)
|
||||
while not stop:
|
||||
dx = random.gauss(0, BUZZ)
|
||||
dy = random.gauss(0, BUZZ)
|
||||
try:
|
||||
canvas.move(p, dx, dy)
|
||||
except TclError:
|
||||
break
|
||||
else:
|
||||
yield None
|
||||
|
||||
def move(particle): # move the particle at random time
|
||||
next(particle)
|
||||
dt = random.expovariate(LAMBDA)
|
||||
root.after(int(dt*1000), move, particle)
|
||||
|
||||
def main():
|
||||
global root, stop
|
||||
root = Tk()
|
||||
canvas = Canvas(root, width=WIDTH, height=HEIGHT)
|
||||
canvas.pack(fill='both', expand=1)
|
||||
np = 30
|
||||
if sys.argv[1:]:
|
||||
np = int(sys.argv[1])
|
||||
for i in range(np): # start the dance
|
||||
move(particle(canvas))
|
||||
try:
|
||||
root.mainloop()
|
||||
finally:
|
||||
stop = 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,264 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
from tkinter import *
|
||||
|
||||
|
||||
# Since Canvas.Group is no longer present, the following class reproduces
|
||||
# a subset of the old Group class that is used by this app.
|
||||
|
||||
class Group:
|
||||
def __init__(self, canvas, tag=None):
|
||||
if tag is None:
|
||||
tag = 'Group%d' % id(self)
|
||||
|
||||
self.tag = self.id = tag
|
||||
self.canvas = canvas
|
||||
self.canvas.dtag(self.tag)
|
||||
|
||||
def __str__(self):
|
||||
return self.tag
|
||||
|
||||
def _do(self, cmd, *args):
|
||||
return self.canvas.tk.call(self.canvas._w, cmd, self.tag, *args)
|
||||
|
||||
def addtag_withtag(self, tagOrId):
|
||||
self._do('addtag', 'withtag', tagOrId)
|
||||
|
||||
def bind(self, sequence=None, command=None, add=None):
|
||||
return self.canvas.tag_bind(self.id, sequence, command, add)
|
||||
|
||||
def move(self, x_amount, y_amount):
|
||||
self._do('move', x_amount, y_amount)
|
||||
|
||||
def dtag(self, tagToDelete=None):
|
||||
self._do('dtag', tagToDelete)
|
||||
|
||||
def tkraise(self, aboveThis=None):
|
||||
self._do('raise', aboveThis)
|
||||
|
||||
|
||||
class Object:
|
||||
|
||||
"""Base class for composite graphical objects.
|
||||
|
||||
Objects belong to a canvas, and can be moved around on the canvas.
|
||||
They also belong to at most one ``pile'' of objects, and can be
|
||||
transferred between piles (or removed from their pile).
|
||||
|
||||
Objects have a canonical ``x, y'' position which is moved when the
|
||||
object is moved. Where the object is relative to this position
|
||||
depends on the object; for simple objects, it may be their center.
|
||||
|
||||
Objects have mouse sensitivity. They can be clicked, dragged and
|
||||
double-clicked. The behavior may actually determined by the pile
|
||||
they are in.
|
||||
|
||||
All instance attributes are public since the derived class may
|
||||
need them.
|
||||
"""
|
||||
|
||||
def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
|
||||
self.canvas = canvas
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.pile = None
|
||||
self.group = Group(self.canvas)
|
||||
self.createitems(fill, text)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.group)
|
||||
|
||||
def createitems(self, fill, text):
|
||||
self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10,
|
||||
self.x + 20, self.y + 20, fill=fill, width=3)
|
||||
self.group.addtag_withtag(self.__oval)
|
||||
self.__text = self.canvas.create_text(self.x, self.y, text=text)
|
||||
self.group.addtag_withtag(self.__text)
|
||||
|
||||
def moveby(self, dx, dy):
|
||||
if dx == dy == 0:
|
||||
return
|
||||
self.group.move(dx, dy)
|
||||
self.x = self.x + dx
|
||||
self.y = self.y + dy
|
||||
|
||||
def moveto(self, x, y):
|
||||
self.moveby(x - self.x, y - self.y)
|
||||
|
||||
def transfer(self, pile):
|
||||
if self.pile:
|
||||
self.pile.delete(self)
|
||||
self.pile = None
|
||||
self.pile = pile
|
||||
if self.pile:
|
||||
self.pile.add(self)
|
||||
|
||||
def tkraise(self):
|
||||
self.group.tkraise()
|
||||
|
||||
|
||||
class Bottom(Object):
|
||||
"""An object to serve as the bottom of a pile."""
|
||||
|
||||
def createitems(self, *args):
|
||||
self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10,
|
||||
self.x + 20, self.y + 10, fill='gray', outline='')
|
||||
self.group.addtag_withtag(self.__oval)
|
||||
|
||||
|
||||
class Pile:
|
||||
"""A group of graphical objects."""
|
||||
|
||||
def __init__(self, canvas, x, y, tag=None):
|
||||
self.canvas = canvas
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.objects = []
|
||||
self.bottom = Bottom(self.canvas, self.x, self.y)
|
||||
self.group = Group(self.canvas, tag=tag)
|
||||
self.group.addtag_withtag(self.bottom.group)
|
||||
self.bindhandlers()
|
||||
|
||||
def bindhandlers(self):
|
||||
self.group.bind('<1>', self.clickhandler)
|
||||
self.group.bind('<Double-1>', self.doubleclickhandler)
|
||||
|
||||
def add(self, object):
|
||||
self.objects.append(object)
|
||||
self.group.addtag_withtag(object.group)
|
||||
self.position(object)
|
||||
|
||||
def delete(self, object):
|
||||
object.group.dtag(self.group)
|
||||
self.objects.remove(object)
|
||||
|
||||
def position(self, object):
|
||||
object.tkraise()
|
||||
i = self.objects.index(object)
|
||||
object.moveto(self.x + i*4, self.y + i*8)
|
||||
|
||||
def clickhandler(self, event):
|
||||
pass
|
||||
|
||||
def doubleclickhandler(self, event):
|
||||
pass
|
||||
|
||||
|
||||
class MovingPile(Pile):
|
||||
|
||||
def bindhandlers(self):
|
||||
Pile.bindhandlers(self)
|
||||
self.group.bind('<B1-Motion>', self.motionhandler)
|
||||
self.group.bind('<ButtonRelease-1>', self.releasehandler)
|
||||
|
||||
movethis = None
|
||||
|
||||
def clickhandler(self, event):
|
||||
tags = self.canvas.gettags('current')
|
||||
for i in range(len(self.objects)):
|
||||
o = self.objects[i]
|
||||
if o.group.tag in tags:
|
||||
break
|
||||
else:
|
||||
self.movethis = None
|
||||
return
|
||||
self.movethis = self.objects[i:]
|
||||
for o in self.movethis:
|
||||
o.tkraise()
|
||||
self.lastx = event.x
|
||||
self.lasty = event.y
|
||||
|
||||
doubleclickhandler = clickhandler
|
||||
|
||||
def motionhandler(self, event):
|
||||
if not self.movethis:
|
||||
return
|
||||
dx = event.x - self.lastx
|
||||
dy = event.y - self.lasty
|
||||
self.lastx = event.x
|
||||
self.lasty = event.y
|
||||
for o in self.movethis:
|
||||
o.moveby(dx, dy)
|
||||
|
||||
def releasehandler(self, event):
|
||||
objects = self.movethis
|
||||
if not objects:
|
||||
return
|
||||
self.movethis = None
|
||||
self.finishmove(objects)
|
||||
|
||||
def finishmove(self, objects):
|
||||
for o in objects:
|
||||
self.position(o)
|
||||
|
||||
|
||||
class Pile1(MovingPile):
|
||||
|
||||
x = 50
|
||||
y = 50
|
||||
tag = 'p1'
|
||||
|
||||
def __init__(self, demo):
|
||||
self.demo = demo
|
||||
MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag)
|
||||
|
||||
def doubleclickhandler(self, event):
|
||||
try:
|
||||
o = self.objects[-1]
|
||||
except IndexError:
|
||||
return
|
||||
o.transfer(self.other())
|
||||
MovingPile.doubleclickhandler(self, event)
|
||||
|
||||
def other(self):
|
||||
return self.demo.p2
|
||||
|
||||
def finishmove(self, objects):
|
||||
o = objects[0]
|
||||
p = self.other()
|
||||
x, y = o.x, o.y
|
||||
if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2:
|
||||
for o in objects:
|
||||
o.transfer(p)
|
||||
else:
|
||||
MovingPile.finishmove(self, objects)
|
||||
|
||||
class Pile2(Pile1):
|
||||
|
||||
x = 150
|
||||
y = 50
|
||||
tag = 'p2'
|
||||
|
||||
def other(self):
|
||||
return self.demo.p1
|
||||
|
||||
|
||||
class Demo:
|
||||
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
self.canvas = Canvas(master,
|
||||
width=200, height=200,
|
||||
background='yellow',
|
||||
relief=SUNKEN, borderwidth=2)
|
||||
self.canvas.pack(expand=1, fill=BOTH)
|
||||
self.p1 = Pile1(self)
|
||||
self.p2 = Pile2(self)
|
||||
o1 = Object(self.canvas, fill='red', text='o1')
|
||||
o2 = Object(self.canvas, fill='green', text='o2')
|
||||
o3 = Object(self.canvas, fill='light blue', text='o3')
|
||||
o1.transfer(self.p1)
|
||||
o2.transfer(self.p1)
|
||||
o3.transfer(self.p2)
|
||||
|
||||
|
||||
# Main function, run when invoked as a stand-alone Python program.
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
demo = Demo(root)
|
||||
root.protocol('WM_DELETE_WINDOW', root.quit)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,108 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# A Python function that generates dialog boxes with a text message,
|
||||
# optional bitmap, and any number of buttons.
|
||||
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
|
||||
|
||||
from tkinter import *
|
||||
import sys
|
||||
|
||||
|
||||
def dialog(master, title, text, bitmap, default, *args):
|
||||
|
||||
# 1. Create the top-level window and divide it into top
|
||||
# and bottom parts.
|
||||
|
||||
w = Toplevel(master, class_='Dialog')
|
||||
w.title(title)
|
||||
w.iconname('Dialog')
|
||||
|
||||
top = Frame(w, relief=RAISED, borderwidth=1)
|
||||
top.pack(side=TOP, fill=BOTH)
|
||||
bot = Frame(w, relief=RAISED, borderwidth=1)
|
||||
bot.pack(side=BOTTOM, fill=BOTH)
|
||||
|
||||
# 2. Fill the top part with the bitmap and message.
|
||||
|
||||
msg = Message(top, width='3i', text=text)
|
||||
msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
|
||||
if bitmap:
|
||||
bm = Label(top, bitmap=bitmap)
|
||||
bm.pack(side=LEFT, padx='3m', pady='3m')
|
||||
|
||||
# 3. Create a row of buttons at the bottom of the dialog.
|
||||
|
||||
var = IntVar()
|
||||
buttons = []
|
||||
i = 0
|
||||
for but in args:
|
||||
b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i))
|
||||
buttons.append(b)
|
||||
if i == default:
|
||||
bd = Frame(bot, relief=SUNKEN, borderwidth=1)
|
||||
bd.pack(side=LEFT, expand=1, padx='3m', pady='2m')
|
||||
b.lift()
|
||||
b.pack (in_=bd, side=LEFT,
|
||||
padx='2m', pady='2m', ipadx='2m', ipady='1m')
|
||||
else:
|
||||
b.pack (side=LEFT, expand=1,
|
||||
padx='3m', pady='3m', ipadx='2m', ipady='1m')
|
||||
i = i+1
|
||||
|
||||
# 4. Set up a binding for <Return>, if there's a default,
|
||||
# set a grab, and claim the focus too.
|
||||
|
||||
if default >= 0:
|
||||
w.bind('<Return>',
|
||||
lambda e, b=buttons[default], v=var, i=default:
|
||||
(b.flash(),
|
||||
v.set(i)))
|
||||
|
||||
oldFocus = w.focus_get()
|
||||
w.grab_set()
|
||||
w.focus_set()
|
||||
|
||||
# 5. Wait for the user to respond, then restore the focus
|
||||
# and return the index of the selected button.
|
||||
|
||||
w.waitvar(var)
|
||||
w.destroy()
|
||||
if oldFocus: oldFocus.focus_set()
|
||||
return var.get()
|
||||
|
||||
# The rest is the test program.
|
||||
|
||||
def go():
|
||||
i = dialog(mainWidget,
|
||||
'Not Responding',
|
||||
"The file server isn't responding right now; "
|
||||
"I'll keep trying.",
|
||||
'',
|
||||
-1,
|
||||
'OK')
|
||||
print('pressed button', i)
|
||||
i = dialog(mainWidget,
|
||||
'File Modified',
|
||||
'File "tcl.h" has been modified since '
|
||||
'the last time it was saved. '
|
||||
'Do you want to save it before exiting the application?',
|
||||
'warning',
|
||||
0,
|
||||
'Save File',
|
||||
'Discard Changes',
|
||||
'Return To Editor')
|
||||
print('pressed button', i)
|
||||
|
||||
def test():
|
||||
import sys
|
||||
global mainWidget
|
||||
mainWidget = Frame()
|
||||
Pack.config(mainWidget)
|
||||
start = Button(mainWidget, text='Press Here To Start', command=go)
|
||||
start.pack()
|
||||
endit = Button(mainWidget, text="Exit", command=sys.exit)
|
||||
endit.pack(fill=BOTH)
|
||||
mainWidget.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
|
@ -1,91 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Simulate "electrons" migrating across the screen.
|
||||
# An optional bitmap file in can be in the background.
|
||||
#
|
||||
# Usage: electrons [n [bitmapfile]]
|
||||
#
|
||||
# n is the number of electrons to animate; default is 30.
|
||||
#
|
||||
# The bitmap file can be any X11 bitmap file (look in
|
||||
# /usr/include/X11/bitmaps for samples); it is displayed as the
|
||||
# background of the animation. Default is no bitmap.
|
||||
|
||||
from tkinter import *
|
||||
import random
|
||||
|
||||
|
||||
# The graphical interface
|
||||
class Electrons:
|
||||
|
||||
# Create our objects
|
||||
def __init__(self, n, bitmap = None):
|
||||
self.n = n
|
||||
self.tk = tk = Tk()
|
||||
self.canvas = c = Canvas(tk)
|
||||
c.pack()
|
||||
width, height = tk.getint(c['width']), tk.getint(c['height'])
|
||||
|
||||
# Add background bitmap
|
||||
if bitmap:
|
||||
self.bitmap = c.create_bitmap(width/2, height/2,
|
||||
bitmap=bitmap,
|
||||
foreground='blue')
|
||||
|
||||
self.pieces = []
|
||||
x1, y1, x2, y2 = 10,70,14,74
|
||||
for i in range(n):
|
||||
p = c.create_oval(x1, y1, x2, y2, fill='red')
|
||||
self.pieces.append(p)
|
||||
y1, y2 = y1 +2, y2 + 2
|
||||
self.tk.update()
|
||||
|
||||
def random_move(self, n):
|
||||
c = self.canvas
|
||||
for p in self.pieces:
|
||||
x = random.choice(range(-2,4))
|
||||
y = random.choice(range(-3,4))
|
||||
c.move(p, x, y)
|
||||
self.tk.update()
|
||||
|
||||
# Run -- allow 500 movemens
|
||||
def run(self):
|
||||
try:
|
||||
for i in range(500):
|
||||
self.random_move(self.n)
|
||||
except TclError:
|
||||
try:
|
||||
self.tk.destroy()
|
||||
except TclError:
|
||||
pass
|
||||
|
||||
|
||||
# Main program
|
||||
def main():
|
||||
import sys
|
||||
|
||||
# First argument is number of electrons, default 30
|
||||
if sys.argv[1:]:
|
||||
n = int(sys.argv[1])
|
||||
else:
|
||||
n = 30
|
||||
|
||||
# Second argument is bitmap file, default none
|
||||
if sys.argv[2:]:
|
||||
bitmap = sys.argv[2]
|
||||
# Reverse meaning of leading '@' compared to Tk
|
||||
if bitmap[0] == '@': bitmap = bitmap[1:]
|
||||
else: bitmap = '@' + bitmap
|
||||
else:
|
||||
bitmap = None
|
||||
|
||||
# Create the graphical objects...
|
||||
h = Electrons(n, bitmap)
|
||||
|
||||
# ...and run!
|
||||
h.run()
|
||||
|
||||
|
||||
# Call main when run as script
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,17 +0,0 @@
|
|||
# Display hello, world in a button; clicking it quits the program
|
||||
|
||||
import sys
|
||||
from tkinter import *
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
button = Button(root)
|
||||
button['text'] = 'Hello, world'
|
||||
button['command'] = quit_callback # See below
|
||||
button.pack()
|
||||
root.mainloop()
|
||||
|
||||
def quit_callback():
|
||||
sys.exit(0)
|
||||
|
||||
main()
|
|
@ -1,23 +0,0 @@
|
|||
"""Draw on top of an image"""
|
||||
|
||||
from tkinter import *
|
||||
import sys
|
||||
|
||||
def main():
|
||||
filename = sys.argv[1]
|
||||
root = Tk()
|
||||
img = PhotoImage(file=filename)
|
||||
w, h = img.width(), img.height()
|
||||
canv = Canvas(root, width=w, height=h)
|
||||
canv.create_image(0, 0, anchor=NW, image=img)
|
||||
canv.pack()
|
||||
canv.bind('<Button-1>', blob)
|
||||
root.mainloop()
|
||||
|
||||
def blob(event):
|
||||
x, y = event.x, event.y
|
||||
canv = event.widget
|
||||
r = 5
|
||||
canv.create_oval(x-r, y-r, x+r, y+r, fill='red', outline="")
|
||||
|
||||
main()
|
|
@ -1,12 +0,0 @@
|
|||
from tkinter import *
|
||||
import sys
|
||||
|
||||
def main():
|
||||
filename = sys.argv[1]
|
||||
root = Tk()
|
||||
img = PhotoImage(file=filename)
|
||||
label = Label(root, image=img)
|
||||
label.pack()
|
||||
root.mainloop()
|
||||
|
||||
main()
|
|
@ -1,96 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
# Tkinter interface to Linux `kill' command.
|
||||
|
||||
from tkinter import *
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
class BarButton(Menubutton):
|
||||
def __init__(self, master=None, **cnf):
|
||||
Menubutton.__init__(self, master, **cnf)
|
||||
self.pack(side=LEFT)
|
||||
self.menu = Menu(self, name='menu')
|
||||
self['menu'] = self.menu
|
||||
|
||||
class Kill(Frame):
|
||||
# List of (name, option, pid_column)
|
||||
format_list = [('Default', '', 0),
|
||||
('Long', '-l', 2),
|
||||
('User', '-u', 1),
|
||||
('Jobs', '-j', 1),
|
||||
('Signal', '-s', 1),
|
||||
('Memory', '-m', 0),
|
||||
('VM', '-v', 0),
|
||||
('Hex', '-X', 0)]
|
||||
def kill(self, selected):
|
||||
c = self.format_list[self.format.get()][2]
|
||||
pid = selected.split()[c]
|
||||
os.system('kill -9 ' + pid)
|
||||
self.do_update()
|
||||
def do_update(self):
|
||||
name, option, column = self.format_list[self.format.get()]
|
||||
s = subprocess.getoutput('ps -w ' + option)
|
||||
list = s.split('\n')
|
||||
self.header.set(list[0])
|
||||
del list[0]
|
||||
y = self.frame.vscroll.get()[0]
|
||||
self.frame.list.delete(0, AtEnd())
|
||||
for line in list:
|
||||
self.frame.list.insert(0, line)
|
||||
self.frame.list.yview(int(y))
|
||||
def do_motion(self, e):
|
||||
e.widget.select_clear(0, END)
|
||||
e.widget.select_set(e.widget.nearest(e.y))
|
||||
def do_leave(self, e):
|
||||
e.widget.select_clear(0, END)
|
||||
def do_1(self, e):
|
||||
self.kill(e.widget.get(e.widget.nearest(e.y)))
|
||||
def __init__(self, master=None, **cnf):
|
||||
Frame.__init__(self, master, cnf)
|
||||
self.pack(expand=1, fill=BOTH)
|
||||
self.bar = Frame(self, name='bar', relief=RAISED,
|
||||
borderwidth=2)
|
||||
self.bar.pack(fill=X)
|
||||
self.bar.file = BarButton(self.bar, text='File')
|
||||
self.bar.file.menu.add_command(
|
||||
label='Quit', command=self.quit)
|
||||
self.bar.view = BarButton(self.bar, text='View')
|
||||
self.format = IntVar(self)
|
||||
self.format.set(2)
|
||||
for num in range(len(self.format_list)):
|
||||
self.bar.view.menu.add_radiobutton(
|
||||
label=self.format_list[num][0],
|
||||
command=self.do_update,
|
||||
variable=self.format,
|
||||
value=num)
|
||||
#self.bar.view.menu.add_separator()
|
||||
#XXX ...
|
||||
self.bar.tk_menuBar(self.bar.file, self.bar.view)
|
||||
self.frame = Frame(self, relief=RAISED, borderwidth=2)
|
||||
self.frame.pack(expand=1, fill=BOTH)
|
||||
self.header = StringVar(self)
|
||||
self.frame.label = Label(self.frame, relief=FLAT, anchor=NW,
|
||||
borderwidth=0,
|
||||
textvariable=self.header)
|
||||
self.frame.label.pack(fill=X)
|
||||
self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
|
||||
self.frame.list = Listbox(self.frame, relief=SUNKEN,
|
||||
selectbackground='#eed5b7',
|
||||
selectborderwidth=0,
|
||||
yscroll=self.frame.vscroll.set)
|
||||
self.frame.vscroll['command'] = self.frame.list.yview
|
||||
self.frame.vscroll.pack(side=RIGHT, fill=Y)
|
||||
self.frame.list.pack(expand=1, fill=BOTH)
|
||||
self.update = Button(self, text="Update",
|
||||
command=self.do_update)
|
||||
self.update.pack(expand=1, fill=X)
|
||||
self.frame.list.bind('<Motion>', self.do_motion)
|
||||
self.frame.list.bind('<Leave>', self.do_leave)
|
||||
self.frame.list.bind('<1>', self.do_1)
|
||||
self.do_update()
|
||||
|
||||
if __name__ == '__main__':
|
||||
kill = Kill(None, borderwidth=5)
|
||||
kill.winfo_toplevel().title('Tkinter Process Killer')
|
||||
kill.winfo_toplevel().minsize(1, 1)
|
||||
kill.mainloop()
|
|
@ -1,34 +0,0 @@
|
|||
# List a remote app's widget tree (names and classes only)
|
||||
|
||||
import sys
|
||||
|
||||
from tkinter import *
|
||||
|
||||
def listtree(master, app):
|
||||
list = Listbox(master, name='list')
|
||||
list.pack(expand=1, fill=BOTH)
|
||||
listnodes(list, app, '.', 0)
|
||||
return list
|
||||
|
||||
def listnodes(list, app, widget, level):
|
||||
klass = list.send(app, 'winfo', 'class', widget)
|
||||
list.insert(END, '%s (%s)' % (widget, klass))
|
||||
children = list.tk.splitlist(
|
||||
list.send(app, 'winfo', 'children', widget))
|
||||
for c in children:
|
||||
listnodes(list, app, c, level+1)
|
||||
|
||||
def main():
|
||||
if not sys.argv[1:]:
|
||||
sys.stderr.write('Usage: listtree appname\n')
|
||||
sys.exit(2)
|
||||
app = sys.argv[1]
|
||||
tk = Tk()
|
||||
tk.minsize(1, 1)
|
||||
f = Frame(tk, name='f')
|
||||
f.pack(expand=1, fill=BOTH)
|
||||
list = listtree(f, app)
|
||||
tk.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,215 +0,0 @@
|
|||
# Widget to display a man page
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from tkinter import *
|
||||
from tkinter.font import Font
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
# XXX Recognizing footers is system dependent
|
||||
# (This one works for IRIX 5.2 and Solaris 2.2)
|
||||
footerprog = re.compile(
|
||||
'^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
|
||||
emptyprog = re.compile('^[ \t]*\n')
|
||||
ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
|
||||
|
||||
|
||||
class EditableManPage(ScrolledText):
|
||||
"""Basic Man Page class -- does not disable editing."""
|
||||
|
||||
def __init__(self, master=None, **cnf):
|
||||
ScrolledText.__init__(self, master, **cnf)
|
||||
|
||||
bold = Font(font=self['font']).copy()
|
||||
bold.config(weight='bold')
|
||||
italic = Font(font=self['font']).copy()
|
||||
italic.config(slant='italic')
|
||||
|
||||
# Define tags for formatting styles
|
||||
self.tag_config('X', underline=1)
|
||||
self.tag_config('!', font=bold)
|
||||
self.tag_config('_', font=italic)
|
||||
|
||||
# Set state to idle
|
||||
self.fp = None
|
||||
self.lineno = 0
|
||||
|
||||
def busy(self):
|
||||
"""Test whether we are busy parsing a file."""
|
||||
return self.fp != None
|
||||
|
||||
def kill(self):
|
||||
"""Ensure we're not busy."""
|
||||
if self.busy():
|
||||
self._endparser()
|
||||
|
||||
def asyncparsefile(self, fp):
|
||||
"""Parse a file, in the background."""
|
||||
self._startparser(fp)
|
||||
self.tk.createfilehandler(fp, READABLE,
|
||||
self._filehandler)
|
||||
|
||||
parsefile = asyncparsefile # Alias
|
||||
|
||||
def _filehandler(self, fp, mask):
|
||||
"""I/O handler used by background parsing."""
|
||||
nextline = self.fp.readline()
|
||||
if not nextline:
|
||||
self._endparser()
|
||||
return
|
||||
self._parseline(nextline)
|
||||
|
||||
def syncparsefile(self, fp):
|
||||
"""Parse a file, now (cannot be aborted)."""
|
||||
self._startparser(fp)
|
||||
while True:
|
||||
nextline = fp.readline()
|
||||
if not nextline:
|
||||
break
|
||||
self._parseline(nextline)
|
||||
self._endparser()
|
||||
|
||||
def _startparser(self, fp):
|
||||
"""Initialize parsing from a particular file -- must not be busy."""
|
||||
if self.busy():
|
||||
raise RuntimeError('startparser: still busy')
|
||||
fp.fileno() # Test for file-ness
|
||||
self.fp = fp
|
||||
self.lineno = 0
|
||||
self.ok = 0
|
||||
self.empty = 0
|
||||
self.buffer = None
|
||||
savestate = self['state']
|
||||
self['state'] = NORMAL
|
||||
self.delete('1.0', END)
|
||||
self['state'] = savestate
|
||||
|
||||
def _endparser(self):
|
||||
"""End parsing -- must be busy, need not be at EOF."""
|
||||
if not self.busy():
|
||||
raise RuntimeError('endparser: not busy')
|
||||
if self.buffer:
|
||||
self._parseline('')
|
||||
try:
|
||||
self.tk.deletefilehandler(self.fp)
|
||||
except TclError:
|
||||
pass
|
||||
self.fp.close()
|
||||
self.fp = None
|
||||
del self.ok, self.empty, self.buffer
|
||||
|
||||
def _parseline(self, nextline):
|
||||
"""Parse a single line."""
|
||||
if not self.buffer:
|
||||
# Save this line -- we need one line read-ahead
|
||||
self.buffer = nextline
|
||||
return
|
||||
if emptyprog.match(self.buffer):
|
||||
# Buffered line was empty -- set a flag
|
||||
self.empty = 1
|
||||
self.buffer = nextline
|
||||
return
|
||||
textline = self.buffer
|
||||
if ulprog.match(nextline):
|
||||
# Next line is properties for buffered line
|
||||
propline = nextline
|
||||
self.buffer = None
|
||||
else:
|
||||
# Next line is read-ahead
|
||||
propline = None
|
||||
self.buffer = nextline
|
||||
if not self.ok:
|
||||
# First non blank line after footer must be header
|
||||
# -- skip that too
|
||||
self.ok = 1
|
||||
self.empty = 0
|
||||
return
|
||||
if footerprog.match(textline):
|
||||
# Footer -- start skipping until next non-blank line
|
||||
self.ok = 0
|
||||
self.empty = 0
|
||||
return
|
||||
savestate = self['state']
|
||||
self['state'] = NORMAL
|
||||
if TkVersion >= 4.0:
|
||||
self.mark_set('insert', 'end-1c')
|
||||
else:
|
||||
self.mark_set('insert', END)
|
||||
if self.empty:
|
||||
# One or more previous lines were empty
|
||||
# -- insert one blank line in the text
|
||||
self._insert_prop('\n')
|
||||
self.lineno = self.lineno + 1
|
||||
self.empty = 0
|
||||
if not propline:
|
||||
# No properties
|
||||
self._insert_prop(textline)
|
||||
else:
|
||||
# Search for properties
|
||||
p = ''
|
||||
j = 0
|
||||
for i in range(min(len(propline), len(textline))):
|
||||
if propline[i] != p:
|
||||
if j < i:
|
||||
self._insert_prop(textline[j:i], p)
|
||||
j = i
|
||||
p = propline[i]
|
||||
self._insert_prop(textline[j:])
|
||||
self.lineno = self.lineno + 1
|
||||
self['state'] = savestate
|
||||
|
||||
def _insert_prop(self, str, prop = ' '):
|
||||
"""Insert a string at the end, with at most one property (tag)."""
|
||||
here = self.index(AtInsert())
|
||||
self.insert(AtInsert(), str)
|
||||
if TkVersion <= 4.0:
|
||||
tags = self.tag_names(here)
|
||||
for tag in tags:
|
||||
self.tag_remove(tag, here, AtInsert())
|
||||
if prop != ' ':
|
||||
self.tag_add(prop, here, AtInsert())
|
||||
|
||||
|
||||
class ReadonlyManPage(EditableManPage):
|
||||
"""Readonly Man Page class -- disables editing, otherwise the same."""
|
||||
|
||||
def __init__(self, master=None, **cnf):
|
||||
cnf['state'] = DISABLED
|
||||
EditableManPage.__init__(self, master, **cnf)
|
||||
|
||||
# Alias
|
||||
ManPage = ReadonlyManPage
|
||||
|
||||
# usage: ManPage [manpage]; or ManPage [-f] file
|
||||
# -f means that the file is nroff -man output run through ul -i
|
||||
def main():
|
||||
# XXX This directory may be different on your system
|
||||
MANDIR = ''
|
||||
DEFAULTPAGE = 'Tcl'
|
||||
formatted = 0
|
||||
if sys.argv[1:] and sys.argv[1] == '-f':
|
||||
formatted = 1
|
||||
del sys.argv[1]
|
||||
if sys.argv[1:]:
|
||||
name = sys.argv[1]
|
||||
else:
|
||||
name = DEFAULTPAGE
|
||||
if not formatted:
|
||||
if name[-2:-1] != '.':
|
||||
name = name + '.n'
|
||||
name = os.path.join(MANDIR, name)
|
||||
root = Tk()
|
||||
root.minsize(1, 1)
|
||||
manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
|
||||
manpage.pack(expand=1, fill=BOTH)
|
||||
if formatted:
|
||||
fp = open(name, 'r')
|
||||
else:
|
||||
fp = os.popen('nroff -man -c %s | ul -i' % name, 'r')
|
||||
manpage.parsefile(fp)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,286 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Scan MH folder, display results in window
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import getopt
|
||||
import mailbox
|
||||
from tkinter import *
|
||||
|
||||
from dialog import dialog
|
||||
|
||||
MBOXPATH = os.environ['HOME'] + '/Mail'
|
||||
|
||||
def main():
|
||||
global root, tk, top, mid, bot
|
||||
global folderbox, foldermenu, scanbox, scanmenu, viewer
|
||||
global folder, seq
|
||||
global mh, mhf
|
||||
|
||||
# Parse command line options
|
||||
|
||||
folder = 'inbox'
|
||||
seq = 'all'
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], '')
|
||||
except getopt.error as msg:
|
||||
print(msg)
|
||||
sys.exit(2)
|
||||
for arg in args:
|
||||
if arg[:1] == '+':
|
||||
folder = arg[1:]
|
||||
else:
|
||||
seq = arg
|
||||
|
||||
# Initialize MH
|
||||
|
||||
mh = mailbox.MH(MBOXPATH)
|
||||
mhf = mh.get_folder(folder)
|
||||
|
||||
# Build widget hierarchy
|
||||
|
||||
root = Tk()
|
||||
tk = root.tk
|
||||
|
||||
top = Frame(root)
|
||||
top.pack({'expand': 1, 'fill': 'both'})
|
||||
|
||||
# Build right part: folder list
|
||||
|
||||
right = Frame(top)
|
||||
right.pack({'fill': 'y', 'side': 'right'})
|
||||
|
||||
folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
|
||||
folderbar.pack({'fill': 'y', 'side': 'right'})
|
||||
|
||||
folderbox = Listbox(right, {'exportselection': 0})
|
||||
folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
|
||||
|
||||
foldermenu = Menu(root)
|
||||
foldermenu.add('command',
|
||||
{'label': 'Open Folder',
|
||||
'command': open_folder})
|
||||
foldermenu.add('separator')
|
||||
foldermenu.add('command',
|
||||
{'label': 'Quit',
|
||||
'command': 'exit'})
|
||||
foldermenu.bind('<ButtonRelease-3>', folder_unpost)
|
||||
|
||||
folderbox['yscrollcommand'] = (folderbar, 'set')
|
||||
folderbar['command'] = (folderbox, 'yview')
|
||||
folderbox.bind('<Double-1>', open_folder, 1)
|
||||
folderbox.bind('<3>', folder_post)
|
||||
|
||||
# Build left part: scan list
|
||||
|
||||
left = Frame(top)
|
||||
left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
|
||||
|
||||
scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
|
||||
scanbar.pack({'fill': 'y', 'side': 'right'})
|
||||
|
||||
scanbox = Listbox(left, {'font': 'fixed'})
|
||||
scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
|
||||
|
||||
scanmenu = Menu(root)
|
||||
scanmenu.add('command',
|
||||
{'label': 'Open Message',
|
||||
'command': open_message})
|
||||
scanmenu.add('command',
|
||||
{'label': 'Remove Message',
|
||||
'command': remove_message})
|
||||
scanmenu.add('command',
|
||||
{'label': 'Refile Message',
|
||||
'command': refile_message})
|
||||
scanmenu.add('separator')
|
||||
scanmenu.add('command',
|
||||
{'label': 'Quit',
|
||||
'command': 'exit'})
|
||||
scanmenu.bind('<ButtonRelease-3>', scan_unpost)
|
||||
|
||||
scanbox['yscrollcommand'] = (scanbar, 'set')
|
||||
scanbar['command'] = (scanbox, 'yview')
|
||||
scanbox.bind('<Double-1>', open_message)
|
||||
scanbox.bind('<3>', scan_post)
|
||||
|
||||
# Separator between middle and bottom part
|
||||
|
||||
rule2 = Frame(root, {'bg': 'black'})
|
||||
rule2.pack({'fill': 'x'})
|
||||
|
||||
# Build bottom part: current message
|
||||
|
||||
bot = Frame(root)
|
||||
bot.pack({'expand': 1, 'fill': 'both'})
|
||||
#
|
||||
viewer = None
|
||||
|
||||
# Window manager commands
|
||||
|
||||
root.minsize(800, 1) # Make window resizable
|
||||
|
||||
# Fill folderbox with text
|
||||
|
||||
setfolders()
|
||||
|
||||
# Fill scanbox with text
|
||||
|
||||
rescan()
|
||||
|
||||
# Enter mainloop
|
||||
|
||||
root.mainloop()
|
||||
|
||||
def folder_post(e):
|
||||
x, y = e.x_root, e.y_root
|
||||
foldermenu.post(x - 10, y - 10)
|
||||
foldermenu.grab_set()
|
||||
|
||||
def folder_unpost(e):
|
||||
tk.call('update', 'idletasks')
|
||||
foldermenu.grab_release()
|
||||
foldermenu.unpost()
|
||||
foldermenu.invoke('active')
|
||||
|
||||
def scan_post(e):
|
||||
x, y = e.x_root, e.y_root
|
||||
scanmenu.post(x - 10, y - 10)
|
||||
scanmenu.grab_set()
|
||||
|
||||
def scan_unpost(e):
|
||||
tk.call('update', 'idletasks')
|
||||
scanmenu.grab_release()
|
||||
scanmenu.unpost()
|
||||
scanmenu.invoke('active')
|
||||
|
||||
scanparser = re.compile('^ *([0-9]+)')
|
||||
|
||||
def open_folder(e=None):
|
||||
global folder, mhf
|
||||
sel = folderbox.curselection()
|
||||
if len(sel) != 1:
|
||||
if len(sel) > 1:
|
||||
msg = "Please open one folder at a time"
|
||||
else:
|
||||
msg = "Please select a folder to open"
|
||||
dialog(root, "Can't Open Folder", msg, "", 0, "OK")
|
||||
return
|
||||
i = sel[0]
|
||||
folder = folderbox.get(i)
|
||||
mhf = mh.get_folder(folder)
|
||||
rescan()
|
||||
|
||||
def open_message(e=None):
|
||||
global viewer
|
||||
sel = scanbox.curselection()
|
||||
if len(sel) != 1:
|
||||
if len(sel) > 1:
|
||||
msg = "Please open one message at a time"
|
||||
else:
|
||||
msg = "Please select a message to open"
|
||||
dialog(root, "Can't Open Message", msg, "", 0, "OK")
|
||||
return
|
||||
cursor = scanbox['cursor']
|
||||
scanbox['cursor'] = 'watch'
|
||||
tk.call('update', 'idletasks')
|
||||
i = sel[0]
|
||||
line = scanbox.get(i)
|
||||
m = scanparser.match(line)
|
||||
if m:
|
||||
num = int(m.group(1))
|
||||
m = mhf.get_message(num)
|
||||
if viewer: viewer.destroy()
|
||||
from mimeviewer import MimeViewer
|
||||
viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
|
||||
viewer.pack()
|
||||
viewer.show()
|
||||
scanbox['cursor'] = cursor
|
||||
|
||||
def interestingheader(header):
|
||||
return header != 'received'
|
||||
|
||||
def remove_message(e=None):
|
||||
itop = scanbox.nearest(0)
|
||||
sel = scanbox.curselection()
|
||||
if not sel:
|
||||
dialog(root, "No Message To Remove",
|
||||
"Please select a message to remove", "", 0, "OK")
|
||||
return
|
||||
todo = []
|
||||
for i in sel:
|
||||
line = scanbox.get(i)
|
||||
m = scanparser.match(line)
|
||||
if m:
|
||||
toremove = int(m.group(1))
|
||||
todo.append(toremove)
|
||||
mhf.remove(toremove)
|
||||
rescan()
|
||||
fixfocus(min(todo), itop)
|
||||
|
||||
lastrefile = ''
|
||||
tofolder = None
|
||||
def refile_message(e=None):
|
||||
global lastrefile, tofolder
|
||||
itop = scanbox.nearest(0)
|
||||
sel = scanbox.curselection()
|
||||
if not sel:
|
||||
dialog(root, "No Message To Refile",
|
||||
"Please select a message to refile", "", 0, "OK")
|
||||
return
|
||||
foldersel = folderbox.curselection()
|
||||
if len(foldersel) != 1:
|
||||
if not foldersel:
|
||||
msg = "Please select a folder to refile to"
|
||||
else:
|
||||
msg = "Please select exactly one folder to refile to"
|
||||
dialog(root, "No Folder To Refile", msg, "", 0, "OK")
|
||||
return
|
||||
refileto = folderbox.get(foldersel[0])
|
||||
todo = []
|
||||
for i in sel:
|
||||
line = scanbox.get(i)
|
||||
m = scanparser.match(line)
|
||||
if m:
|
||||
todo.append(int(m.group(1)))
|
||||
if lastrefile != refileto or not tofolder:
|
||||
lastrefile = refileto
|
||||
tofolder = None
|
||||
tofolder = mh.get_folder(lastrefile)
|
||||
mhf.refilemessages(todo, tofolder)
|
||||
rescan()
|
||||
fixfocus(min(todo), itop)
|
||||
|
||||
def fixfocus(near, itop):
|
||||
n = scanbox.size()
|
||||
for i in range(n):
|
||||
line = scanbox.get(repr(i))
|
||||
m = scanparser.match(line)
|
||||
if m:
|
||||
num = int(m.group(1))
|
||||
if num >= near:
|
||||
break
|
||||
else:
|
||||
i = 'end'
|
||||
scanbox.yview(itop)
|
||||
|
||||
def setfolders():
|
||||
folderbox.delete(0, 'end')
|
||||
for fn in mh.list_folders():
|
||||
folderbox.insert('end', fn)
|
||||
|
||||
def rescan():
|
||||
global viewer
|
||||
if viewer:
|
||||
viewer.destroy()
|
||||
viewer = None
|
||||
scanbox.delete(0, 'end')
|
||||
for line in scanfolder(folder, seq):
|
||||
scanbox.insert('end', line)
|
||||
|
||||
def scanfolder(folder = 'inbox', sequence = 'all'):
|
||||
return [line[:-1] for line in
|
||||
os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()]
|
||||
|
||||
main()
|
|
@ -1,159 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# View a single MIME multipart message.
|
||||
# Display each part as a box.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import getopt
|
||||
import mailbox
|
||||
from tkinter import *
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
|
||||
MBOXPATH = os.environ['HOME'] + '/Mail'
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
def getcurrent(self):
|
||||
"""Return the current message. Raise Error when there is none."""
|
||||
seqs = self.get_sequences()
|
||||
try:
|
||||
return max(seqs['cur'])
|
||||
except (ValueError, KeyError):
|
||||
raise Error("no cur message")
|
||||
|
||||
|
||||
class MimeViewer:
|
||||
def __init__(self, parent, title, msg):
|
||||
self.title = title
|
||||
self.msg = msg
|
||||
self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
|
||||
self.frame.packing = {'expand': 0, 'fill': 'both'}
|
||||
self.button = Checkbutton(self.frame,
|
||||
{'text': title,
|
||||
'command': self.toggle})
|
||||
self.button.pack({'anchor': 'w'})
|
||||
headertext = []
|
||||
for item in msg.items():
|
||||
headertext.append("%s: %s" % item)
|
||||
headertext = '\n'.join(headertext)
|
||||
height = countlines(headertext, 4)
|
||||
if height:
|
||||
self.htext = ScrolledText(self.frame,
|
||||
{'height': height,
|
||||
'width': 80,
|
||||
'wrap': 'none',
|
||||
'relief': 'raised',
|
||||
'bd': 2})
|
||||
self.htext.packing = {'expand': 1, 'fill': 'both',
|
||||
'after': self.button}
|
||||
self.htext.insert('end', headertext)
|
||||
else:
|
||||
self.htext = Frame(self.frame,
|
||||
{'relief': 'raised', 'bd': 2})
|
||||
self.htext.packing = {'side': 'top',
|
||||
'ipady': 2,
|
||||
'fill': 'x',
|
||||
'after': self.button}
|
||||
body = msg.get_payload()
|
||||
if type(body) == str:
|
||||
self.pad = None
|
||||
height = countlines(body, 10)
|
||||
if height:
|
||||
self.btext = ScrolledText(self.frame,
|
||||
{'height': height,
|
||||
'width': 80,
|
||||
'wrap': 'none',
|
||||
'relief': 'raised',
|
||||
'bd': 2})
|
||||
self.btext.packing = {'expand': 1,
|
||||
'fill': 'both'}
|
||||
self.btext.insert('end', body)
|
||||
else:
|
||||
self.btext = None
|
||||
self.parts = None
|
||||
else:
|
||||
self.pad = Frame(self.frame,
|
||||
{'relief': 'flat', 'bd': 2})
|
||||
self.pad.packing = {'side': 'left', 'ipadx': 10,
|
||||
'fill': 'y', 'after': self.htext}
|
||||
self.parts = []
|
||||
for i in range(len(body)):
|
||||
p = MimeViewer(self.frame,
|
||||
'%s.%d' % (title, i+1),
|
||||
body[i])
|
||||
self.parts.append(p)
|
||||
self.btext = None
|
||||
self.collapsed = 1
|
||||
def pack(self):
|
||||
self.frame.pack(self.frame.packing)
|
||||
def destroy(self):
|
||||
self.frame.destroy()
|
||||
def show(self):
|
||||
if self.collapsed:
|
||||
self.button.invoke()
|
||||
def toggle(self):
|
||||
if self.collapsed:
|
||||
self.explode()
|
||||
else:
|
||||
self.collapse()
|
||||
def collapse(self):
|
||||
self.collapsed = 1
|
||||
for comp in self.htext, self.btext, self.pad:
|
||||
if comp:
|
||||
comp.forget()
|
||||
if self.parts:
|
||||
for part in self.parts:
|
||||
part.frame.forget()
|
||||
self.frame.pack({'expand': 0})
|
||||
def explode(self):
|
||||
self.collapsed = 0
|
||||
for comp in self.htext, self.btext, self.pad:
|
||||
if comp: comp.pack(comp.packing)
|
||||
if self.parts:
|
||||
for part in self.parts:
|
||||
part.pack()
|
||||
self.frame.pack({'expand': 1})
|
||||
|
||||
def countlines(str, limit):
|
||||
i = 0
|
||||
n = 0
|
||||
while n < limit:
|
||||
i = str.find('\n', i)
|
||||
if i < 0: break
|
||||
n = n+1
|
||||
i = i+1
|
||||
return n
|
||||
|
||||
def main():
|
||||
opts, args = getopt.getopt(sys.argv[1:], '')
|
||||
for o, a in opts:
|
||||
pass
|
||||
message = None
|
||||
folder = 'inbox'
|
||||
for arg in args:
|
||||
if arg[:1] == '+':
|
||||
folder = arg[1:]
|
||||
else:
|
||||
message = int(arg)
|
||||
|
||||
mh = mailbox.MH(MBOXPATH)
|
||||
f = mh.get_folder(folder)
|
||||
if message is None:
|
||||
message = getcurrent(f)
|
||||
m = mailbox.MHMessage(f.get(message))
|
||||
|
||||
root = Tk()
|
||||
tk = root.tk
|
||||
|
||||
top = MimeViewer(root, '+%s/%d' % (folder, message), m)
|
||||
top.pack()
|
||||
top.show()
|
||||
|
||||
root.minsize(1, 1)
|
||||
|
||||
tk.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,47 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
"""Play with the new Tk 8.0 toplevel menu option."""
|
||||
|
||||
from tkinter import *
|
||||
|
||||
class App:
|
||||
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
|
||||
self.menubar = Menu(self.master)
|
||||
|
||||
self.filemenu = Menu(self.menubar)
|
||||
|
||||
self.filemenu.add_command(label="New")
|
||||
self.filemenu.add_command(label="Open...")
|
||||
self.filemenu.add_command(label="Close")
|
||||
self.filemenu.add_separator()
|
||||
self.filemenu.add_command(label="Quit", command=self.master.quit)
|
||||
|
||||
self.editmenu = Menu(self.menubar)
|
||||
|
||||
self.editmenu.add_command(label="Cut")
|
||||
self.editmenu.add_command(label="Copy")
|
||||
self.editmenu.add_command(label="Paste")
|
||||
|
||||
self.helpmenu = Menu(self.menubar, name='help')
|
||||
|
||||
self.helpmenu.add_command(label="About...")
|
||||
|
||||
self.menubar.add_cascade(label="File", menu=self.filemenu)
|
||||
self.menubar.add_cascade(label="Edit", menu=self.editmenu)
|
||||
self.menubar.add_cascade(label="Help", menu=self.helpmenu)
|
||||
|
||||
self.top = Toplevel(menu=self.menubar)
|
||||
|
||||
# Rest of app goes here...
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
root.withdraw()
|
||||
app = App(root)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,27 +0,0 @@
|
|||
# option menu sample (Fredrik Lundh, September 1997)
|
||||
|
||||
from tkinter import *
|
||||
|
||||
root = Tk()
|
||||
|
||||
#
|
||||
# standard usage
|
||||
|
||||
var1 = StringVar()
|
||||
var1.set("One") # default selection
|
||||
|
||||
menu1 = OptionMenu(root, var1, "One", "Two", "Three")
|
||||
menu1.pack()
|
||||
|
||||
#
|
||||
# initialize from a sequence
|
||||
|
||||
CHOICES = "Aah", "Bee", "Cee", "Dee", "Eff"
|
||||
|
||||
var2 = StringVar()
|
||||
var2.set(CHOICES[0])
|
||||
|
||||
menu2 = OptionMenu(root, var2, *CHOICES)
|
||||
menu2.pack()
|
||||
|
||||
root.mainloop()
|
|
@ -1,60 +0,0 @@
|
|||
""""Paint program by Dave Michell.
|
||||
|
||||
Subject: tkinter "paint" example
|
||||
From: Dave Mitchell <davem@magnet.com>
|
||||
To: python-list@cwi.nl
|
||||
Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST)
|
||||
|
||||
Not too long ago (last week maybe?) someone posted a request
|
||||
for an example of a paint program using Tkinter. Try as I might
|
||||
I can't seem to find it in the archive, so i'll just post mine
|
||||
here and hope that the person who requested it sees this!
|
||||
|
||||
All this does is put up a canvas and draw a smooth black line
|
||||
whenever you have the mouse button down, but hopefully it will
|
||||
be enough to start with.. It would be easy enough to add some
|
||||
options like other shapes or colors...
|
||||
|
||||
yours,
|
||||
dave mitchell
|
||||
davem@magnet.com
|
||||
"""
|
||||
|
||||
from tkinter import *
|
||||
|
||||
"""paint.py: not exactly a paint program.. just a smooth line drawing demo."""
|
||||
|
||||
b1 = "up"
|
||||
xold, yold = None, None
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
drawing_area = Canvas(root)
|
||||
drawing_area.pack()
|
||||
drawing_area.bind("<Motion>", motion)
|
||||
drawing_area.bind("<ButtonPress-1>", b1down)
|
||||
drawing_area.bind("<ButtonRelease-1>", b1up)
|
||||
root.mainloop()
|
||||
|
||||
def b1down(event):
|
||||
global b1
|
||||
b1 = "down" # you only want to draw when the button is down
|
||||
# because "Motion" events happen -all the time-
|
||||
|
||||
def b1up(event):
|
||||
global b1, xold, yold
|
||||
b1 = "up"
|
||||
xold = None # reset the line when you let go of the button
|
||||
yold = None
|
||||
|
||||
def motion(event):
|
||||
if b1 == "down":
|
||||
global xold, yold
|
||||
if xold is not None and yold is not None:
|
||||
event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE)
|
||||
# here's where you draw it. smooth. neat.
|
||||
xold = event.x
|
||||
yold = event.y
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,159 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# A Python program implementing rmt, an application for remotely
|
||||
# controlling other Tk applications.
|
||||
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276.
|
||||
|
||||
# Note that because of forward references in the original, we
|
||||
# sometimes delay bindings until after the corresponding procedure is
|
||||
# defined. We also introduce names for some unnamed code blocks in
|
||||
# the original because of restrictions on lambda forms in Python.
|
||||
|
||||
# XXX This should be written in a more Python-like style!!!
|
||||
|
||||
from tkinter import *
|
||||
import sys
|
||||
|
||||
# 1. Create basic application structure: menu bar on top of
|
||||
# text widget, scrollbar on right.
|
||||
|
||||
root = Tk()
|
||||
tk = root.tk
|
||||
mBar = Frame(root, relief=RAISED, borderwidth=2)
|
||||
mBar.pack(fill=X)
|
||||
|
||||
f = Frame(root)
|
||||
f.pack(expand=1, fill=BOTH)
|
||||
s = Scrollbar(f, relief=FLAT)
|
||||
s.pack(side=RIGHT, fill=Y)
|
||||
t = Text(f, relief=RAISED, borderwidth=2, yscrollcommand=s.set, setgrid=1)
|
||||
t.pack(side=LEFT, fill=BOTH, expand=1)
|
||||
t.tag_config('bold')
|
||||
s['command'] = t.yview
|
||||
|
||||
root.title('Tk Remote Controller')
|
||||
root.iconname('Tk Remote')
|
||||
|
||||
# 2. Create menu button and menus.
|
||||
|
||||
file = Menubutton(mBar, text='File', underline=0)
|
||||
file.pack(side=LEFT)
|
||||
file_m = Menu(file)
|
||||
file['menu'] = file_m
|
||||
file_m_apps = Menu(file_m, tearoff=0)
|
||||
file_m.add_cascade(label='Select Application', underline=0,
|
||||
menu=file_m_apps)
|
||||
file_m.add_command(label='Quit', underline=0, command=sys.exit)
|
||||
|
||||
# 3. Create bindings for text widget to allow commands to be
|
||||
# entered and information to be selected. New characters
|
||||
# can only be added at the end of the text (can't ever move
|
||||
# insertion point).
|
||||
|
||||
def single1(e):
|
||||
x = e.x
|
||||
y = e.y
|
||||
t.setvar('tk_priv(selectMode)', 'char')
|
||||
t.mark_set('anchor', At(x, y))
|
||||
# Should focus W
|
||||
t.bind('<1>', single1)
|
||||
|
||||
def double1(e):
|
||||
x = e.x
|
||||
y = e.y
|
||||
t.setvar('tk_priv(selectMode)', 'word')
|
||||
t.tk_textSelectTo(At(x, y))
|
||||
t.bind('<Double-1>', double1)
|
||||
|
||||
def triple1(e):
|
||||
x = e.x
|
||||
y = e.y
|
||||
t.setvar('tk_priv(selectMode)', 'line')
|
||||
t.tk_textSelectTo(At(x, y))
|
||||
t.bind('<Triple-1>', triple1)
|
||||
|
||||
def returnkey(e):
|
||||
t.insert(AtInsert(), '\n')
|
||||
invoke()
|
||||
t.bind('<Return>', returnkey)
|
||||
|
||||
def controlv(e):
|
||||
t.insert(AtInsert(), t.selection_get())
|
||||
t.yview_pickplace(AtInsert())
|
||||
if t.index(AtInsert())[-2:] == '.0':
|
||||
invoke()
|
||||
t.bind('<Control-v>', controlv)
|
||||
|
||||
# 4. Procedure to backspace over one character, as long as
|
||||
# the character isn't part of the prompt.
|
||||
|
||||
def backspace(e):
|
||||
if t.index('promptEnd') != t.index('insert - 1 char'):
|
||||
t.delete('insert - 1 char', AtInsert())
|
||||
t.yview_pickplace(AtInsert())
|
||||
t.bind('<BackSpace>', backspace)
|
||||
t.bind('<Control-h>', backspace)
|
||||
t.bind('<Delete>', backspace)
|
||||
|
||||
|
||||
# 5. Procedure that's invoked when return is typed: if
|
||||
# there's not yet a complete command (e.g. braces are open)
|
||||
# then do nothing. Otherwise, execute command (locally or
|
||||
# remotely), output the result or error message, and issue
|
||||
# a new prompt.
|
||||
|
||||
def invoke():
|
||||
cmd = t.get('promptEnd + 1 char', AtInsert())
|
||||
if t.getboolean(tk.call('info', 'complete', cmd)): # XXX
|
||||
if app == root.winfo_name():
|
||||
msg = tk.call('eval', cmd) # XXX
|
||||
else:
|
||||
msg = t.send(app, cmd)
|
||||
if msg:
|
||||
t.insert(AtInsert(), msg + '\n')
|
||||
prompt()
|
||||
t.yview_pickplace(AtInsert())
|
||||
|
||||
def prompt():
|
||||
t.insert(AtInsert(), app + ': ')
|
||||
t.mark_set('promptEnd', 'insert - 1 char')
|
||||
t.tag_add('bold', 'insert linestart', 'promptEnd')
|
||||
|
||||
# 6. Procedure to select a new application. Also changes
|
||||
# the prompt on the current command line to reflect the new
|
||||
# name.
|
||||
|
||||
def newApp(appName):
|
||||
global app
|
||||
app = appName
|
||||
t.delete('promptEnd linestart', 'promptEnd')
|
||||
t.insert('promptEnd', appName + ':')
|
||||
t.tag_add('bold', 'promptEnd linestart', 'promptEnd')
|
||||
|
||||
def fillAppsMenu():
|
||||
file_m_apps.add('command')
|
||||
file_m_apps.delete(0, 'last')
|
||||
names = root.winfo_interps()
|
||||
names = list(names) # convert tuple to list
|
||||
names.sort()
|
||||
for name in names:
|
||||
try:
|
||||
root.send(name, 'winfo name .')
|
||||
except TclError:
|
||||
# Inoperative window -- ignore it
|
||||
pass
|
||||
else:
|
||||
file_m_apps.add_command(
|
||||
label=name,
|
||||
command=lambda name=name: newApp(name))
|
||||
|
||||
file_m_apps['postcommand'] = fillAppsMenu
|
||||
mBar.tk_menuBar(file)
|
||||
|
||||
# 7. Miscellaneous initialization.
|
||||
|
||||
app = root.winfo_name()
|
||||
prompt()
|
||||
t.focus()
|
||||
|
||||
root.mainloop()
|
|
@ -1,146 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
from tkinter import *
|
||||
from tkinter.scrolledtext import ScrolledText
|
||||
from tkinter.dialog import Dialog
|
||||
import signal
|
||||
|
||||
BUFSIZE = 512
|
||||
|
||||
class ShellWindow(ScrolledText):
|
||||
|
||||
def __init__(self, master=None, shell=None, **cnf):
|
||||
if not shell:
|
||||
try:
|
||||
shell = os.environ['SHELL']
|
||||
except KeyError:
|
||||
shell = '/bin/sh'
|
||||
shell = shell + ' -i'
|
||||
args = shell.split()
|
||||
shell = args[0]
|
||||
|
||||
ScrolledText.__init__(self, master, **cnf)
|
||||
self.pos = '1.0'
|
||||
self.bind('<Return>', self.inputhandler)
|
||||
self.bind('<Control-c>', self.sigint)
|
||||
self.bind('<Control-t>', self.sigterm)
|
||||
self.bind('<Control-k>', self.sigkill)
|
||||
self.bind('<Control-d>', self.sendeof)
|
||||
|
||||
self.pid, self.fromchild, self.tochild = spawn(shell, args)
|
||||
self.tk.createfilehandler(self.fromchild, READABLE,
|
||||
self.outputhandler)
|
||||
|
||||
def outputhandler(self, file, mask):
|
||||
data = os.read(file, BUFSIZE).decode()
|
||||
if not data:
|
||||
self.tk.deletefilehandler(file)
|
||||
pid, sts = os.waitpid(self.pid, 0)
|
||||
print('pid', pid, 'status', sts)
|
||||
self.pid = None
|
||||
detail = sts>>8
|
||||
cause = sts & 0xff
|
||||
if cause == 0:
|
||||
msg = "exit status %d" % detail
|
||||
else:
|
||||
msg = "killed by signal %d" % (cause & 0x7f)
|
||||
if cause & 0x80:
|
||||
msg = msg + " -- core dumped"
|
||||
Dialog(self.master,
|
||||
text=msg,
|
||||
title="Exit status",
|
||||
bitmap='warning',
|
||||
default=0,
|
||||
strings=('OK',))
|
||||
return
|
||||
self.insert(END, data)
|
||||
self.pos = self.index("end - 1 char")
|
||||
self.yview_pickplace(END)
|
||||
|
||||
def inputhandler(self, *args):
|
||||
if not self.pid:
|
||||
self.no_process()
|
||||
return "break"
|
||||
self.insert(END, "\n")
|
||||
line = self.get(self.pos, "end - 1 char")
|
||||
self.pos = self.index(END)
|
||||
os.write(self.tochild, line.encode())
|
||||
return "break"
|
||||
|
||||
def sendeof(self, *args):
|
||||
if not self.pid:
|
||||
self.no_process()
|
||||
return "break"
|
||||
os.close(self.tochild)
|
||||
return "break"
|
||||
|
||||
def sendsig(self, sig):
|
||||
if not self.pid:
|
||||
self.no_process()
|
||||
return "break"
|
||||
os.kill(self.pid, sig)
|
||||
return "break"
|
||||
|
||||
def sigint(self, *args):
|
||||
return self.sendsig(signal.SIGINT)
|
||||
|
||||
def sigquit(self, *args):
|
||||
return self.sendsig(signal.SIGQUIT)
|
||||
|
||||
def sigterm(self, *args):
|
||||
return self.sendsig(signal.SIGTERM)
|
||||
|
||||
def sigkill(self, *args):
|
||||
return self.sendsig(signal.SIGKILL)
|
||||
|
||||
def no_process(self):
|
||||
Dialog(self.master,
|
||||
text="No active process",
|
||||
title="No process",
|
||||
bitmap='error',
|
||||
default=0,
|
||||
strings=('OK',))
|
||||
|
||||
MAXFD = 100 # Max number of file descriptors (os.getdtablesize()???)
|
||||
|
||||
def spawn(prog, args):
|
||||
p2cread, p2cwrite = os.pipe()
|
||||
c2pread, c2pwrite = os.pipe()
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
# Child
|
||||
for i in 0, 1, 2:
|
||||
try:
|
||||
os.close(i)
|
||||
except os.error:
|
||||
pass
|
||||
if os.dup(p2cread) != 0:
|
||||
sys.stderr.write('popen2: bad read dup\n')
|
||||
if os.dup(c2pwrite) != 1:
|
||||
sys.stderr.write('popen2: bad write dup\n')
|
||||
if os.dup(c2pwrite) != 2:
|
||||
sys.stderr.write('popen2: bad write dup\n')
|
||||
os.closerange(3, MAXFD)
|
||||
try:
|
||||
os.execvp(prog, args)
|
||||
finally:
|
||||
sys.stderr.write('execvp failed\n')
|
||||
os._exit(1)
|
||||
os.close(p2cread)
|
||||
os.close(c2pwrite)
|
||||
return pid, c2pread, p2cwrite
|
||||
|
||||
def test():
|
||||
shell = ' '.join(sys.argv[1: ])
|
||||
root = Tk()
|
||||
root.minsize(1, 1)
|
||||
if shell:
|
||||
w = ShellWindow(root, shell=shell)
|
||||
else:
|
||||
w = ShellWindow(root)
|
||||
w.pack(expand=1, fill=BOTH)
|
||||
w.focus_set()
|
||||
w.tk.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
|
@ -1,626 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
"""Solitaire game, much like the one that comes with MS Windows.
|
||||
|
||||
Limitations:
|
||||
|
||||
- No cute graphical images for the playing cards faces or backs.
|
||||
- No scoring or timer.
|
||||
- No undo.
|
||||
- No option to turn 3 cards at a time.
|
||||
- No keyboard shortcuts.
|
||||
- Less fancy animation when you win.
|
||||
- The determination of which stack you drag to is more relaxed.
|
||||
|
||||
Apology:
|
||||
|
||||
I'm not much of a card player, so my terminology in these comments may
|
||||
at times be a little unusual. If you have suggestions, please let me
|
||||
know!
|
||||
|
||||
"""
|
||||
|
||||
# Imports
|
||||
|
||||
import random
|
||||
|
||||
from tkinter import *
|
||||
from canvasevents import Group
|
||||
|
||||
|
||||
# Constants determining the size and lay-out of cards and stacks. We
|
||||
# work in a "grid" where each card/stack is surrounded by MARGIN
|
||||
# pixels of space on each side, so adjacent stacks are separated by
|
||||
# 2*MARGIN pixels. OFFSET is the offset used for displaying the
|
||||
# face down cards in the row stacks.
|
||||
|
||||
CARDWIDTH = 100
|
||||
CARDHEIGHT = 150
|
||||
MARGIN = 10
|
||||
XSPACING = CARDWIDTH + 2*MARGIN
|
||||
YSPACING = CARDHEIGHT + 4*MARGIN
|
||||
OFFSET = 5
|
||||
|
||||
# The background color, green to look like a playing table. The
|
||||
# standard green is way too bright, and dark green is way to dark, so
|
||||
# we use something in between. (There are a few more colors that
|
||||
# could be customized, but they are less controversial.)
|
||||
|
||||
BACKGROUND = '#070'
|
||||
|
||||
|
||||
# Suits and colors. The values of the symbolic suit names are the
|
||||
# strings used to display them (you change these and VALNAMES to
|
||||
# internationalize the game). The COLOR dictionary maps suit names to
|
||||
# colors (red and black) which must be Tk color names. The keys() of
|
||||
# the COLOR dictionary conveniently provides us with a list of all
|
||||
# suits (in arbitrary order).
|
||||
|
||||
HEARTS = 'Heart'
|
||||
DIAMONDS = 'Diamond'
|
||||
CLUBS = 'Club'
|
||||
SPADES = 'Spade'
|
||||
|
||||
RED = 'red'
|
||||
BLACK = 'black'
|
||||
|
||||
COLOR = {}
|
||||
for s in (HEARTS, DIAMONDS):
|
||||
COLOR[s] = RED
|
||||
for s in (CLUBS, SPADES):
|
||||
COLOR[s] = BLACK
|
||||
|
||||
ALLSUITS = list(COLOR.keys())
|
||||
NSUITS = len(ALLSUITS)
|
||||
|
||||
|
||||
# Card values are 1-13. We also define symbolic names for the picture
|
||||
# cards. ALLVALUES is a list of all card values.
|
||||
|
||||
ACE = 1
|
||||
JACK = 11
|
||||
QUEEN = 12
|
||||
KING = 13
|
||||
ALLVALUES = range(1, 14) # (one more than the highest value)
|
||||
NVALUES = len(ALLVALUES)
|
||||
|
||||
|
||||
# VALNAMES is a list that maps a card value to string. It contains a
|
||||
# dummy element at index 0 so it can be indexed directly with the card
|
||||
# value.
|
||||
|
||||
VALNAMES = ["", "A"] + list(map(str, range(2, 11))) + ["J", "Q", "K"]
|
||||
|
||||
|
||||
# Solitaire constants. The only one I can think of is the number of
|
||||
# row stacks.
|
||||
|
||||
NROWS = 7
|
||||
|
||||
|
||||
# The rest of the program consists of class definitions. These are
|
||||
# further described in their documentation strings.
|
||||
|
||||
|
||||
class Card:
|
||||
|
||||
"""A playing card.
|
||||
|
||||
A card doesn't record to which stack it belongs; only the stack
|
||||
records this (it turns out that we always know this from the
|
||||
context, and this saves a ``double update'' with potential for
|
||||
inconsistencies).
|
||||
|
||||
Public methods:
|
||||
|
||||
moveto(x, y) -- move the card to an absolute position
|
||||
moveby(dx, dy) -- move the card by a relative offset
|
||||
tkraise() -- raise the card to the top of its stack
|
||||
showface(), showback() -- turn the card face up or down & raise it
|
||||
|
||||
Public read-only instance variables:
|
||||
|
||||
suit, value, color -- the card's suit, value and color
|
||||
face_shown -- true when the card is shown face up, else false
|
||||
|
||||
Semi-public read-only instance variables (XXX should be made
|
||||
private):
|
||||
|
||||
group -- the Canvas.Group representing the card
|
||||
x, y -- the position of the card's top left corner
|
||||
|
||||
Private instance variables:
|
||||
|
||||
__back, __rect, __text -- the canvas items making up the card
|
||||
|
||||
(To show the card face up, the text item is placed in front of
|
||||
rect and the back is placed behind it. To show it face down, this
|
||||
is reversed. The card is created face down.)
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, suit, value, canvas):
|
||||
"""Card constructor.
|
||||
|
||||
Arguments are the card's suit and value, and the canvas widget.
|
||||
|
||||
The card is created at position (0, 0), with its face down
|
||||
(adding it to a stack will position it according to that
|
||||
stack's rules).
|
||||
|
||||
"""
|
||||
self.suit = suit
|
||||
self.value = value
|
||||
self.color = COLOR[suit]
|
||||
self.face_shown = 0
|
||||
|
||||
self.x = self.y = 0
|
||||
self.canvas = canvas
|
||||
self.group = Group(canvas)
|
||||
|
||||
text = "%s %s" % (VALNAMES[value], suit)
|
||||
self.__text = canvas.create_text(CARDWIDTH // 2, 0, anchor=N,
|
||||
fill=self.color, text=text)
|
||||
self.group.addtag_withtag(self.__text)
|
||||
|
||||
self.__rect = canvas.create_rectangle(0, 0, CARDWIDTH, CARDHEIGHT,
|
||||
outline='black', fill='white')
|
||||
self.group.addtag_withtag(self.__rect)
|
||||
|
||||
self.__back = canvas.create_rectangle(MARGIN, MARGIN,
|
||||
CARDWIDTH - MARGIN,
|
||||
CARDHEIGHT - MARGIN,
|
||||
outline='black', fill='blue')
|
||||
self.group.addtag_withtag(self.__back)
|
||||
|
||||
def __repr__(self):
|
||||
"""Return a string for debug print statements."""
|
||||
return "Card(%r, %r)" % (self.suit, self.value)
|
||||
|
||||
def moveto(self, x, y):
|
||||
"""Move the card to absolute position (x, y)."""
|
||||
self.moveby(x - self.x, y - self.y)
|
||||
|
||||
def moveby(self, dx, dy):
|
||||
"""Move the card by (dx, dy)."""
|
||||
self.x = self.x + dx
|
||||
self.y = self.y + dy
|
||||
self.group.move(dx, dy)
|
||||
|
||||
def tkraise(self):
|
||||
"""Raise the card above all other objects in its canvas."""
|
||||
self.group.tkraise()
|
||||
|
||||
def showface(self):
|
||||
"""Turn the card's face up."""
|
||||
self.tkraise()
|
||||
self.canvas.tag_raise(self.__rect)
|
||||
self.canvas.tag_raise(self.__text)
|
||||
self.face_shown = 1
|
||||
|
||||
def showback(self):
|
||||
"""Turn the card's face down."""
|
||||
self.tkraise()
|
||||
self.canvas.tag_raise(self.__rect)
|
||||
self.canvas.tag_raise(self.__back)
|
||||
self.face_shown = 0
|
||||
|
||||
|
||||
class Stack:
|
||||
|
||||
"""A generic stack of cards.
|
||||
|
||||
This is used as a base class for all other stacks (e.g. the deck,
|
||||
the suit stacks, and the row stacks).
|
||||
|
||||
Public methods:
|
||||
|
||||
add(card) -- add a card to the stack
|
||||
delete(card) -- delete a card from the stack
|
||||
showtop() -- show the top card (if any) face up
|
||||
deal() -- delete and return the top card, or None if empty
|
||||
|
||||
Method that subclasses may override:
|
||||
|
||||
position(card) -- move the card to its proper (x, y) position
|
||||
|
||||
The default position() method places all cards at the stack's
|
||||
own (x, y) position.
|
||||
|
||||
userclickhandler(), userdoubleclickhandler() -- called to do
|
||||
subclass specific things on single and double clicks
|
||||
|
||||
The default user (single) click handler shows the top card
|
||||
face up. The default user double click handler calls the user
|
||||
single click handler.
|
||||
|
||||
usermovehandler(cards) -- called to complete a subpile move
|
||||
|
||||
The default user move handler moves all moved cards back to
|
||||
their original position (by calling the position() method).
|
||||
|
||||
Private methods:
|
||||
|
||||
clickhandler(event), doubleclickhandler(event),
|
||||
motionhandler(event), releasehandler(event) -- event handlers
|
||||
|
||||
The default event handlers turn the top card of the stack with
|
||||
its face up on a (single or double) click, and also support
|
||||
moving a subpile around.
|
||||
|
||||
startmoving(event) -- begin a move operation
|
||||
finishmoving() -- finish a move operation
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, x, y, game=None):
|
||||
"""Stack constructor.
|
||||
|
||||
Arguments are the stack's nominal x and y position (the top
|
||||
left corner of the first card placed in the stack), and the
|
||||
game object (which is used to get the canvas; subclasses use
|
||||
the game object to find other stacks).
|
||||
|
||||
"""
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.game = game
|
||||
self.cards = []
|
||||
self.group = Group(self.game.canvas)
|
||||
self.group.bind('<1>', self.clickhandler)
|
||||
self.group.bind('<Double-1>', self.doubleclickhandler)
|
||||
self.group.bind('<B1-Motion>', self.motionhandler)
|
||||
self.group.bind('<ButtonRelease-1>', self.releasehandler)
|
||||
self.makebottom()
|
||||
|
||||
def makebottom(self):
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
"""Return a string for debug print statements."""
|
||||
return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y)
|
||||
|
||||
# Public methods
|
||||
|
||||
def add(self, card):
|
||||
self.cards.append(card)
|
||||
card.tkraise()
|
||||
self.position(card)
|
||||
self.group.addtag_withtag(card.group)
|
||||
|
||||
def delete(self, card):
|
||||
self.cards.remove(card)
|
||||
card.group.dtag(self.group)
|
||||
|
||||
def showtop(self):
|
||||
if self.cards:
|
||||
self.cards[-1].showface()
|
||||
|
||||
def deal(self):
|
||||
if not self.cards:
|
||||
return None
|
||||
card = self.cards[-1]
|
||||
self.delete(card)
|
||||
return card
|
||||
|
||||
# Subclass overridable methods
|
||||
|
||||
def position(self, card):
|
||||
card.moveto(self.x, self.y)
|
||||
|
||||
def userclickhandler(self):
|
||||
self.showtop()
|
||||
|
||||
def userdoubleclickhandler(self):
|
||||
self.userclickhandler()
|
||||
|
||||
def usermovehandler(self, cards):
|
||||
for card in cards:
|
||||
self.position(card)
|
||||
|
||||
# Event handlers
|
||||
|
||||
def clickhandler(self, event):
|
||||
self.finishmoving() # In case we lost an event
|
||||
self.userclickhandler()
|
||||
self.startmoving(event)
|
||||
|
||||
def motionhandler(self, event):
|
||||
self.keepmoving(event)
|
||||
|
||||
def releasehandler(self, event):
|
||||
self.keepmoving(event)
|
||||
self.finishmoving()
|
||||
|
||||
def doubleclickhandler(self, event):
|
||||
self.finishmoving() # In case we lost an event
|
||||
self.userdoubleclickhandler()
|
||||
self.startmoving(event)
|
||||
|
||||
# Move internals
|
||||
|
||||
moving = None
|
||||
|
||||
def startmoving(self, event):
|
||||
self.moving = None
|
||||
tags = self.game.canvas.gettags('current')
|
||||
for i in range(len(self.cards)):
|
||||
card = self.cards[i]
|
||||
if card.group.tag in tags:
|
||||
break
|
||||
else:
|
||||
return
|
||||
if not card.face_shown:
|
||||
return
|
||||
self.moving = self.cards[i:]
|
||||
self.lastx = event.x
|
||||
self.lasty = event.y
|
||||
for card in self.moving:
|
||||
card.tkraise()
|
||||
|
||||
def keepmoving(self, event):
|
||||
if not self.moving:
|
||||
return
|
||||
dx = event.x - self.lastx
|
||||
dy = event.y - self.lasty
|
||||
self.lastx = event.x
|
||||
self.lasty = event.y
|
||||
if dx or dy:
|
||||
for card in self.moving:
|
||||
card.moveby(dx, dy)
|
||||
|
||||
def finishmoving(self):
|
||||
cards = self.moving
|
||||
self.moving = None
|
||||
if cards:
|
||||
self.usermovehandler(cards)
|
||||
|
||||
|
||||
class Deck(Stack):
|
||||
|
||||
"""The deck is a stack with support for shuffling.
|
||||
|
||||
New methods:
|
||||
|
||||
fill() -- create the playing cards
|
||||
shuffle() -- shuffle the playing cards
|
||||
|
||||
A single click moves the top card to the game's open deck and
|
||||
moves it face up; if we're out of cards, it moves the open deck
|
||||
back to the deck.
|
||||
|
||||
"""
|
||||
|
||||
def makebottom(self):
|
||||
bottom = self.game.canvas.create_rectangle(self.x, self.y,
|
||||
self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black',
|
||||
fill=BACKGROUND)
|
||||
self.group.addtag_withtag(bottom)
|
||||
|
||||
def fill(self):
|
||||
for suit in ALLSUITS:
|
||||
for value in ALLVALUES:
|
||||
self.add(Card(suit, value, self.game.canvas))
|
||||
|
||||
def shuffle(self):
|
||||
n = len(self.cards)
|
||||
newcards = []
|
||||
for i in randperm(n):
|
||||
newcards.append(self.cards[i])
|
||||
self.cards = newcards
|
||||
|
||||
def userclickhandler(self):
|
||||
opendeck = self.game.opendeck
|
||||
card = self.deal()
|
||||
if not card:
|
||||
while 1:
|
||||
card = opendeck.deal()
|
||||
if not card:
|
||||
break
|
||||
self.add(card)
|
||||
card.showback()
|
||||
else:
|
||||
self.game.opendeck.add(card)
|
||||
card.showface()
|
||||
|
||||
|
||||
def randperm(n):
|
||||
"""Function returning a random permutation of range(n)."""
|
||||
r = list(range(n))
|
||||
x = []
|
||||
while r:
|
||||
i = random.choice(r)
|
||||
x.append(i)
|
||||
r.remove(i)
|
||||
return x
|
||||
|
||||
|
||||
class OpenStack(Stack):
|
||||
|
||||
def acceptable(self, cards):
|
||||
return 0
|
||||
|
||||
def usermovehandler(self, cards):
|
||||
card = cards[0]
|
||||
stack = self.game.closeststack(card)
|
||||
if not stack or stack is self or not stack.acceptable(cards):
|
||||
Stack.usermovehandler(self, cards)
|
||||
else:
|
||||
for card in cards:
|
||||
self.delete(card)
|
||||
stack.add(card)
|
||||
self.game.wincheck()
|
||||
|
||||
def userdoubleclickhandler(self):
|
||||
if not self.cards:
|
||||
return
|
||||
card = self.cards[-1]
|
||||
if not card.face_shown:
|
||||
self.userclickhandler()
|
||||
return
|
||||
for s in self.game.suits:
|
||||
if s.acceptable([card]):
|
||||
self.delete(card)
|
||||
s.add(card)
|
||||
self.game.wincheck()
|
||||
break
|
||||
|
||||
|
||||
class SuitStack(OpenStack):
|
||||
|
||||
def makebottom(self):
|
||||
bottom = self.game.canvas.create_rectangle(self.x, self.y,
|
||||
self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black', fill='')
|
||||
|
||||
def userclickhandler(self):
|
||||
pass
|
||||
|
||||
def userdoubleclickhandler(self):
|
||||
pass
|
||||
|
||||
def acceptable(self, cards):
|
||||
if len(cards) != 1:
|
||||
return 0
|
||||
card = cards[0]
|
||||
if not self.cards:
|
||||
return card.value == ACE
|
||||
topcard = self.cards[-1]
|
||||
return card.suit == topcard.suit and card.value == topcard.value + 1
|
||||
|
||||
|
||||
class RowStack(OpenStack):
|
||||
|
||||
def acceptable(self, cards):
|
||||
card = cards[0]
|
||||
if not self.cards:
|
||||
return card.value == KING
|
||||
topcard = self.cards[-1]
|
||||
if not topcard.face_shown:
|
||||
return 0
|
||||
return card.color != topcard.color and card.value == topcard.value - 1
|
||||
|
||||
def position(self, card):
|
||||
y = self.y
|
||||
for c in self.cards:
|
||||
if c == card:
|
||||
break
|
||||
if c.face_shown:
|
||||
y = y + 2*MARGIN
|
||||
else:
|
||||
y = y + OFFSET
|
||||
card.moveto(self.x, y)
|
||||
|
||||
|
||||
class Solitaire:
|
||||
|
||||
def __init__(self, master):
|
||||
self.master = master
|
||||
|
||||
self.canvas = Canvas(self.master,
|
||||
background=BACKGROUND,
|
||||
highlightthickness=0,
|
||||
width=NROWS*XSPACING,
|
||||
height=3*YSPACING + 20 + MARGIN)
|
||||
self.canvas.pack(fill=BOTH, expand=TRUE)
|
||||
|
||||
self.dealbutton = Button(self.canvas,
|
||||
text="Deal",
|
||||
highlightthickness=0,
|
||||
background=BACKGROUND,
|
||||
activebackground="green",
|
||||
command=self.deal)
|
||||
self.canvas.create_window(MARGIN, 3 * YSPACING + 20,
|
||||
window=self.dealbutton, anchor=SW)
|
||||
|
||||
x = MARGIN
|
||||
y = MARGIN
|
||||
|
||||
self.deck = Deck(x, y, self)
|
||||
|
||||
x = x + XSPACING
|
||||
self.opendeck = OpenStack(x, y, self)
|
||||
|
||||
x = x + XSPACING
|
||||
self.suits = []
|
||||
for i in range(NSUITS):
|
||||
x = x + XSPACING
|
||||
self.suits.append(SuitStack(x, y, self))
|
||||
|
||||
x = MARGIN
|
||||
y = y + YSPACING
|
||||
|
||||
self.rows = []
|
||||
for i in range(NROWS):
|
||||
self.rows.append(RowStack(x, y, self))
|
||||
x = x + XSPACING
|
||||
|
||||
self.openstacks = [self.opendeck] + self.suits + self.rows
|
||||
|
||||
self.deck.fill()
|
||||
self.deal()
|
||||
|
||||
def wincheck(self):
|
||||
for s in self.suits:
|
||||
if len(s.cards) != NVALUES:
|
||||
return
|
||||
self.win()
|
||||
self.deal()
|
||||
|
||||
def win(self):
|
||||
"""Stupid animation when you win."""
|
||||
cards = []
|
||||
for s in self.openstacks:
|
||||
cards = cards + s.cards
|
||||
while cards:
|
||||
card = random.choice(cards)
|
||||
cards.remove(card)
|
||||
self.animatedmoveto(card, self.deck)
|
||||
|
||||
def animatedmoveto(self, card, dest):
|
||||
for i in range(10, 0, -1):
|
||||
dx, dy = (dest.x-card.x)//i, (dest.y-card.y)//i
|
||||
card.moveby(dx, dy)
|
||||
self.master.update_idletasks()
|
||||
|
||||
def closeststack(self, card):
|
||||
closest = None
|
||||
cdist = 999999999
|
||||
# Since we only compare distances,
|
||||
# we don't bother to take the square root.
|
||||
for stack in self.openstacks:
|
||||
dist = (stack.x - card.x)**2 + (stack.y - card.y)**2
|
||||
if dist < cdist:
|
||||
closest = stack
|
||||
cdist = dist
|
||||
return closest
|
||||
|
||||
def deal(self):
|
||||
self.reset()
|
||||
self.deck.shuffle()
|
||||
for i in range(NROWS):
|
||||
for r in self.rows[i:]:
|
||||
card = self.deck.deal()
|
||||
r.add(card)
|
||||
for r in self.rows:
|
||||
r.showtop()
|
||||
|
||||
def reset(self):
|
||||
for stack in self.openstacks:
|
||||
while 1:
|
||||
card = stack.deal()
|
||||
if not card:
|
||||
break
|
||||
self.deck.add(card)
|
||||
card.showback()
|
||||
|
||||
|
||||
# Main function, run when invoked as a stand-alone Python program.
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
game = Solitaire(root)
|
||||
root.protocol('WM_DELETE_WINDOW', root.quit)
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,124 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Tkinter interface to SYSV `ps' and `kill' commands.
|
||||
|
||||
from tkinter import *
|
||||
|
||||
if TkVersion < 4.0:
|
||||
raise ImportError("This version of svkill requires Tk 4.0 or later")
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
user = os.environ['LOGNAME']
|
||||
|
||||
class BarButton(Menubutton):
|
||||
def __init__(self, master=None, **cnf):
|
||||
Menubutton.__init__(self, master, **cnf)
|
||||
self.pack(side=LEFT)
|
||||
self.menu = Menu(self, name='menu')
|
||||
self['menu'] = self.menu
|
||||
|
||||
class Kill(Frame):
|
||||
# List of (name, option, pid_column)
|
||||
view_list = [
|
||||
('Default', ''),
|
||||
('Every (-e)', '-e'),
|
||||
('Non process group leaders (-d)', '-d'),
|
||||
('Non leaders with tty (-a)', '-a'),
|
||||
('For this user (-u %s)' % user, '-u %s' % user),
|
||||
]
|
||||
format_list = [
|
||||
('Default', '', 0),
|
||||
('Long (-l)', '-l', 3),
|
||||
('Full (-f)', '-f', 1),
|
||||
('Full Long (-f -l)', '-l -f', 3),
|
||||
('Session and group ID (-j)', '-j', 0),
|
||||
('Scheduler properties (-c)', '-c', 0),
|
||||
]
|
||||
def kill(self, selected):
|
||||
c = self.format_list[self.format.get()][2]
|
||||
pid = selected.split()[c]
|
||||
os.system('kill -9 ' + pid)
|
||||
self.do_update()
|
||||
def do_update(self):
|
||||
format = self.format_list[self.format.get()][1]
|
||||
view = self.view_list[self.view.get()][1]
|
||||
s = subprocess.getoutput('ps %s %s' % (view, format))
|
||||
list = s.split('\n')
|
||||
self.header.set(list[0] + ' ')
|
||||
del list[0]
|
||||
self.frame.list.delete(0, AtEnd())
|
||||
for line in list:
|
||||
self.frame.list.insert(0, line)
|
||||
def do_motion(self, e):
|
||||
e.widget.select_clear('0', 'end')
|
||||
e.widget.select_set(e.widget.nearest(e.y))
|
||||
def do_leave(self, e):
|
||||
e.widget.select_clear('0', 'end')
|
||||
def do_1(self, e):
|
||||
self.kill(e.widget.get(e.widget.nearest(e.y)))
|
||||
def __init__(self, master=None, **cnf):
|
||||
Frame.__init__(self, master, **cnf)
|
||||
self.pack(expand=1, fill=BOTH)
|
||||
self.bar = Frame(self, name='bar', relief=RAISED,
|
||||
borderwidth=2)
|
||||
self.bar.pack(fill=X)
|
||||
self.bar.file = BarButton(self.bar, text='File')
|
||||
self.bar.file.menu.add_command(
|
||||
label='Quit', command=self.quit)
|
||||
self.bar.view = BarButton(self.bar, text='View')
|
||||
self.bar.format = BarButton(self.bar, text='Format')
|
||||
self.view = IntVar(self)
|
||||
self.view.set(0)
|
||||
self.format = IntVar(self)
|
||||
self.format.set(0)
|
||||
for num in range(len(self.view_list)):
|
||||
label, option = self.view_list[num]
|
||||
self.bar.view.menu.add_radiobutton(
|
||||
label=label,
|
||||
command=self.do_update,
|
||||
variable=self.view,
|
||||
value=num)
|
||||
for num in range(len(self.format_list)):
|
||||
label, option, col = self.format_list[num]
|
||||
self.bar.format.menu.add_radiobutton(
|
||||
label=label,
|
||||
command=self.do_update,
|
||||
variable=self.format,
|
||||
value=num)
|
||||
self.bar.tk_menuBar(self.bar.file,
|
||||
self.bar.view,
|
||||
self.bar.format)
|
||||
self.frame = Frame(self, relief=RAISED, borderwidth=2)
|
||||
self.frame.pack(expand=1, fill=BOTH)
|
||||
self.header = StringVar(self)
|
||||
self.frame.label = Label(
|
||||
self.frame, relief=FLAT, anchor=NW, borderwidth=0,
|
||||
textvariable=self.header)
|
||||
self.frame.label.pack(fill=Y, anchor=W)
|
||||
self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
|
||||
self.frame.list = Listbox(
|
||||
self.frame,
|
||||
relief=SUNKEN,
|
||||
width=40, height=10,
|
||||
selectbackground='#eed5b7',
|
||||
selectborderwidth=0,
|
||||
selectmode=BROWSE,
|
||||
yscroll=self.frame.vscroll.set)
|
||||
self.frame.vscroll['command'] = self.frame.list.yview
|
||||
self.frame.vscroll.pack(side=RIGHT, fill=Y)
|
||||
self.frame.list.pack(expand=1, fill=BOTH)
|
||||
self.update = Button(self, text='Update',
|
||||
command=self.do_update)
|
||||
self.update.pack(fill=X)
|
||||
self.frame.list.bind('<Motion>', self.do_motion)
|
||||
self.frame.list.bind('<Leave>', self.do_leave)
|
||||
self.frame.list.bind('<1>', self.do_1)
|
||||
self.do_update()
|
||||
|
||||
if __name__ == '__main__':
|
||||
kill = Kill(None, borderwidth=5)
|
||||
kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)')
|
||||
kill.winfo_toplevel().minsize(1, 1)
|
||||
kill.mainloop()
|
|
@ -1,55 +0,0 @@
|
|||
# Show how to do switchable panels.
|
||||
|
||||
from tkinter import *
|
||||
|
||||
class App:
|
||||
|
||||
def __init__(self, top=None, master=None):
|
||||
if top is None:
|
||||
if master is None:
|
||||
top = Tk()
|
||||
else:
|
||||
top = Toplevel(master)
|
||||
self.top = top
|
||||
self.buttonframe = Frame(top)
|
||||
self.buttonframe.pack()
|
||||
self.panelframe = Frame(top, borderwidth=2, relief=GROOVE)
|
||||
self.panelframe.pack(expand=1, fill=BOTH)
|
||||
self.panels = {}
|
||||
self.curpanel = None
|
||||
|
||||
def addpanel(self, name, klass):
|
||||
button = Button(self.buttonframe, text=name,
|
||||
command=lambda self=self, name=name: self.show(name))
|
||||
button.pack(side=LEFT)
|
||||
frame = Frame(self.panelframe)
|
||||
instance = klass(frame)
|
||||
self.panels[name] = (button, frame, instance)
|
||||
if self.curpanel is None:
|
||||
self.show(name)
|
||||
|
||||
def show(self, name):
|
||||
(button, frame, instance) = self.panels[name]
|
||||
if self.curpanel:
|
||||
self.curpanel.pack_forget()
|
||||
self.curpanel = frame
|
||||
frame.pack(expand=1, fill="both")
|
||||
|
||||
class LabelPanel:
|
||||
def __init__(self, frame):
|
||||
self.label = Label(frame, text="Hello world")
|
||||
self.label.pack()
|
||||
|
||||
class ButtonPanel:
|
||||
def __init__(self, frame):
|
||||
self.button = Button(frame, text="Press me")
|
||||
self.button.pack()
|
||||
|
||||
def main():
|
||||
app = App()
|
||||
app.addpanel("label", LabelPanel)
|
||||
app.addpanel("button", ButtonPanel)
|
||||
app.top.mainloop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,267 +0,0 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
# Tk man page browser -- currently only shows the Tcl/Tk man pages
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from tkinter import *
|
||||
|
||||
from manpage import ManPage
|
||||
|
||||
MANNDIRLIST = ['/usr/local/man/mann', '/usr/share/man/mann']
|
||||
MAN3DIRLIST = ['/usr/local/man/man3', '/usr/share/man/man3']
|
||||
|
||||
foundmanndir = 0
|
||||
for dir in MANNDIRLIST:
|
||||
if os.path.exists(dir):
|
||||
MANNDIR = dir
|
||||
foundmanndir = 1
|
||||
|
||||
foundman3dir = 0
|
||||
for dir in MAN3DIRLIST:
|
||||
if os.path.exists(dir):
|
||||
MAN3DIR = dir
|
||||
foundman3dir = 1
|
||||
|
||||
if not foundmanndir or not foundman3dir:
|
||||
sys.stderr.write('\n')
|
||||
if not foundmanndir:
|
||||
msg = """\
|
||||
Failed to find mann directory.
|
||||
Please add the correct entry to the MANNDIRLIST
|
||||
at the top of %s script.""" % \
|
||||
sys.argv[0]
|
||||
sys.stderr.write("%s\n\n" % msg)
|
||||
if not foundman3dir:
|
||||
msg = """\
|
||||
Failed to find man3 directory.
|
||||
Please add the correct entry to the MAN3DIRLIST
|
||||
at the top of %s script.""" % \
|
||||
sys.argv[0]
|
||||
sys.stderr.write("%s\n\n" % msg)
|
||||
sys.exit(1)
|
||||
|
||||
del foundmanndir
|
||||
del foundman3dir
|
||||
|
||||
def listmanpages(mandir):
|
||||
files = os.listdir(mandir)
|
||||
names = []
|
||||
for file in files:
|
||||
if file[-2:-1] == '.' and (file[-1] in 'ln123456789'):
|
||||
names.append(file[:-2])
|
||||
names.sort()
|
||||
return names
|
||||
|
||||
class SelectionBox:
|
||||
|
||||
def __init__(self, master=None):
|
||||
self.choices = []
|
||||
|
||||
self.frame = Frame(master, name="frame")
|
||||
self.frame.pack(expand=1, fill=BOTH)
|
||||
self.master = self.frame.master
|
||||
self.subframe = Frame(self.frame, name="subframe")
|
||||
self.subframe.pack(expand=0, fill=BOTH)
|
||||
self.leftsubframe = Frame(self.subframe, name='leftsubframe')
|
||||
self.leftsubframe.pack(side=LEFT, expand=1, fill=BOTH)
|
||||
self.rightsubframe = Frame(self.subframe, name='rightsubframe')
|
||||
self.rightsubframe.pack(side=RIGHT, expand=1, fill=BOTH)
|
||||
self.chaptervar = StringVar(master)
|
||||
self.chapter = Menubutton(self.rightsubframe, name='chapter',
|
||||
text='Directory', relief=RAISED,
|
||||
borderwidth=2)
|
||||
self.chapter.pack(side=TOP)
|
||||
self.chaptermenu = Menu(self.chapter, name='chaptermenu')
|
||||
self.chaptermenu.add_radiobutton(label='C functions',
|
||||
value=MAN3DIR,
|
||||
variable=self.chaptervar,
|
||||
command=self.newchapter)
|
||||
self.chaptermenu.add_radiobutton(label='Tcl/Tk functions',
|
||||
value=MANNDIR,
|
||||
variable=self.chaptervar,
|
||||
command=self.newchapter)
|
||||
self.chapter['menu'] = self.chaptermenu
|
||||
self.listbox = Listbox(self.rightsubframe, name='listbox',
|
||||
relief=SUNKEN, borderwidth=2,
|
||||
width=20, height=5)
|
||||
self.listbox.pack(expand=1, fill=BOTH)
|
||||
self.l1 = Button(self.leftsubframe, name='l1',
|
||||
text='Display manual page named:',
|
||||
command=self.entry_cb)
|
||||
self.l1.pack(side=TOP)
|
||||
self.entry = Entry(self.leftsubframe, name='entry',
|
||||
relief=SUNKEN, borderwidth=2,
|
||||
width=20)
|
||||
self.entry.pack(expand=0, fill=X)
|
||||
self.l2frame = Frame(self.leftsubframe, name='l2frame')
|
||||
self.l2frame.pack(expand=0, fill=NONE)
|
||||
self.l2 = Button(self.l2frame, name='l2',
|
||||
text='Search regexp:',
|
||||
command=self.search_cb)
|
||||
self.l2.pack(side=LEFT)
|
||||
self.casevar = BooleanVar()
|
||||
self.casesense = Checkbutton(self.l2frame, name='casesense',
|
||||
text='Case sensitive',
|
||||
variable=self.casevar,
|
||||
relief=FLAT)
|
||||
self.casesense.pack(side=LEFT)
|
||||
self.search = Entry(self.leftsubframe, name='search',
|
||||
relief=SUNKEN, borderwidth=2,
|
||||
width=20)
|
||||
self.search.pack(expand=0, fill=X)
|
||||
self.title = Label(self.leftsubframe, name='title',
|
||||
text='(none)')
|
||||
self.title.pack(side=BOTTOM)
|
||||
self.text = ManPage(self.frame, name='text',
|
||||
relief=SUNKEN, borderwidth=2,
|
||||
wrap=NONE, width=72,
|
||||
selectbackground='pink')
|
||||
self.text.pack(expand=1, fill=BOTH)
|
||||
|
||||
self.entry.bind('<Return>', self.entry_cb)
|
||||
self.search.bind('<Return>', self.search_cb)
|
||||
self.listbox.bind('<Double-1>', self.listbox_cb)
|
||||
|
||||
self.entry.bind('<Tab>', self.entry_tab)
|
||||
self.search.bind('<Tab>', self.search_tab)
|
||||
self.text.bind('<Tab>', self.text_tab)
|
||||
|
||||
self.entry.focus_set()
|
||||
|
||||
self.chaptervar.set(MANNDIR)
|
||||
self.newchapter()
|
||||
|
||||
def newchapter(self):
|
||||
mandir = self.chaptervar.get()
|
||||
self.choices = []
|
||||
self.addlist(listmanpages(mandir))
|
||||
|
||||
def addchoice(self, choice):
|
||||
if choice not in self.choices:
|
||||
self.choices.append(choice)
|
||||
self.choices.sort()
|
||||
self.update()
|
||||
|
||||
def addlist(self, list):
|
||||
self.choices[len(self.choices):] = list
|
||||
self.choices.sort()
|
||||
self.update()
|
||||
|
||||
def entry_cb(self, *e):
|
||||
self.update()
|
||||
|
||||
def listbox_cb(self, e):
|
||||
selection = self.listbox.curselection()
|
||||
if selection and len(selection) == 1:
|
||||
name = self.listbox.get(selection[0])
|
||||
self.show_page(name)
|
||||
|
||||
def search_cb(self, *e):
|
||||
self.search_string(self.search.get())
|
||||
|
||||
def entry_tab(self, e):
|
||||
self.search.focus_set()
|
||||
|
||||
def search_tab(self, e):
|
||||
self.entry.focus_set()
|
||||
|
||||
def text_tab(self, e):
|
||||
self.entry.focus_set()
|
||||
|
||||
def updatelist(self):
|
||||
key = self.entry.get()
|
||||
ok = list(filter(lambda name, key=key, n=len(key): name[:n]==key,
|
||||
self.choices))
|
||||
if not ok:
|
||||
self.frame.bell()
|
||||
self.listbox.delete(0, AtEnd())
|
||||
exactmatch = 0
|
||||
for item in ok:
|
||||
if item == key: exactmatch = 1
|
||||
self.listbox.insert(AtEnd(), item)
|
||||
if exactmatch:
|
||||
return key
|
||||
n = self.listbox.size()
|
||||
if n == 1:
|
||||
return self.listbox.get(0)
|
||||
# Else return None, meaning not a unique selection
|
||||
|
||||
def update(self):
|
||||
name = self.updatelist()
|
||||
if name:
|
||||
self.show_page(name)
|
||||
self.entry.delete(0, AtEnd())
|
||||
self.updatelist()
|
||||
|
||||
def show_page(self, name):
|
||||
file = '%s/%s.?' % (self.chaptervar.get(), name)
|
||||
fp = os.popen('nroff -man -c %s | ul -i' % file, 'r')
|
||||
self.text.kill()
|
||||
self.title['text'] = name
|
||||
self.text.parsefile(fp)
|
||||
|
||||
def search_string(self, search):
|
||||
if not search:
|
||||
self.frame.bell()
|
||||
print('Empty search string')
|
||||
return
|
||||
if not self.casevar.get():
|
||||
map = re.IGNORECASE
|
||||
else:
|
||||
map = None
|
||||
try:
|
||||
if map:
|
||||
prog = re.compile(search, map)
|
||||
else:
|
||||
prog = re.compile(search)
|
||||
except re.error as msg:
|
||||
self.frame.bell()
|
||||
print('Regex error:', msg)
|
||||
return
|
||||
here = self.text.index(AtInsert())
|
||||
lineno = int(here[:here.find('.')])
|
||||
end = self.text.index(AtEnd())
|
||||
endlineno = int(end[:end.find('.')])
|
||||
wraplineno = lineno
|
||||
found = 0
|
||||
while 1:
|
||||
lineno = lineno + 1
|
||||
if lineno > endlineno:
|
||||
if wraplineno <= 0:
|
||||
break
|
||||
endlineno = wraplineno
|
||||
lineno = 0
|
||||
wraplineno = 0
|
||||
line = self.text.get('%d.0 linestart' % lineno,
|
||||
'%d.0 lineend' % lineno)
|
||||
i = prog.search(line)
|
||||
if i:
|
||||
found = 1
|
||||
n = max(1, len(i.group(0)))
|
||||
try:
|
||||
self.text.tag_remove('sel',
|
||||
AtSelFirst(),
|
||||
AtSelLast())
|
||||
except TclError:
|
||||
pass
|
||||
self.text.tag_add('sel',
|
||||
'%d.%d' % (lineno, i.start()),
|
||||
'%d.%d' % (lineno, i.start()+n))
|
||||
self.text.mark_set(AtInsert(),
|
||||
'%d.%d' % (lineno, i.start()))
|
||||
self.text.yview_pickplace(AtInsert())
|
||||
break
|
||||
if not found:
|
||||
self.frame.bell()
|
||||
|
||||
def main():
|
||||
root = Tk()
|
||||
sb = SelectionBox(root)
|
||||
if sys.argv[1:]:
|
||||
sb.show_page(sys.argv[1])
|
||||
root.minsize(1, 1)
|
||||
root.mainloop()
|
||||
|
||||
main()
|
|
@ -1,34 +0,0 @@
|
|||
# This is about all it requires to write a wish shell in Python!
|
||||
|
||||
import _tkinter
|
||||
import os
|
||||
import sys
|
||||
|
||||
tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1, 1)
|
||||
tk.call('update')
|
||||
|
||||
cmd = ''
|
||||
|
||||
while True:
|
||||
if cmd:
|
||||
prompt = ''
|
||||
else:
|
||||
prompt = '% '
|
||||
try:
|
||||
sys.stdout.write(prompt)
|
||||
sys.stdout.flush()
|
||||
line = sys.stdin.readline()
|
||||
if not line:
|
||||
break
|
||||
except EOFError:
|
||||
break
|
||||
cmd += line
|
||||
if tk.getboolean(tk.call('info', 'complete', cmd)):
|
||||
tk.record(line)
|
||||
try:
|
||||
result = tk.call('eval', cmd)
|
||||
except _tkinter.TclError as msg:
|
||||
print('TclError:', msg)
|
||||
else:
|
||||
if result: print(result)
|
||||
cmd = ''
|
|
@ -1,27 +0,0 @@
|
|||
from tkinter import *
|
||||
|
||||
# note that there is no explicit call to start Tk.
|
||||
# Tkinter is smart enough to start the system if it's not already going.
|
||||
|
||||
class Test(Frame):
|
||||
def printit(self):
|
||||
print("hi")
|
||||
|
||||
def createWidgets(self):
|
||||
self.QUIT = Button(self, text='QUIT', foreground='red',
|
||||
command=self.quit)
|
||||
|
||||
self.QUIT.pack(side=LEFT, fill=BOTH)
|
||||
|
||||
# a hello button
|
||||
self.hi_there = Button(self, text='Hello',
|
||||
command=self.printit)
|
||||
self.hi_there.pack(side=LEFT)
|
||||
|
||||
def __init__(self, master=None):
|
||||
Frame.__init__(self, master)
|
||||
Pack.config(self)
|
||||
self.createWidgets()
|
||||
|
||||
test = Test()
|
||||
test.mainloop()
|
|
@ -1,30 +0,0 @@
|
|||
This directory contains some ad-hoc examples of Tkinter widget
|
||||
creation. The files named
|
||||
|
||||
*-simple.py
|
||||
|
||||
are the ones to start with if you're looking for a bare-bones usage of
|
||||
a widget. The other files are meant to show common usage patters that
|
||||
are a tad more involved.
|
||||
|
||||
If you have a suggestion for an example program, please send mail to
|
||||
|
||||
conway@virginia.edu
|
||||
|
||||
and I'll include it.
|
||||
|
||||
|
||||
matt
|
||||
|
||||
TODO
|
||||
-------
|
||||
The X selection
|
||||
Dialog Boxes
|
||||
More canvas examples
|
||||
Message widgets
|
||||
Text Editors
|
||||
Scrollbars
|
||||
Listboxes
|
||||
|
||||
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
from tkinter import *
|
||||
|
||||
# This program shows how to use the "after" function to make animation.
|
||||
|
||||
class Test(Frame):
|
||||
def printit(self):
|
||||
print("hi")
|
||||
|
||||
def createWidgets(self):
|
||||
self.QUIT = Button(self, text='QUIT', foreground='red',
|
||||
command=self.quit)
|
||||
self.QUIT.pack(side=LEFT, fill=BOTH)
|
||||
|
||||
self.draw = Canvas(self, width="5i", height="5i")
|
||||
|
||||
# all of these work..
|
||||
self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
|
||||
self.draw.pack(side=LEFT)
|
||||
|
||||
def moveThing(self, *args):
|
||||
# move 1/10 of an inch every 1/10 sec (1" per second, smoothly)
|
||||
self.draw.move("thing", "0.01i", "0.01i")
|
||||
self.after(10, self.moveThing)
|
||||
|
||||
|
||||
def __init__(self, master=None):
|
||||
Frame.__init__(self, master)
|
||||
Pack.config(self)
|
||||
self.createWidgets()
|
||||
self.after(10, self.moveThing)
|
||||
|
||||
|
||||
test = Test()
|
||||
|
||||
test.mainloop()
|
|
@ -1,44 +0,0 @@
|
|||
from tkinter import *
|
||||
|
||||
# this is the same as simple-demo-1.py, but uses
|
||||
# subclassing.
|
||||
# note that there is no explicit call to start Tk.
|
||||
# Tkinter is smart enough to start the system if it's not already going.
|
||||
|
||||
|
||||
class Test(Frame):
|
||||
def printit(self):
|
||||
print("hi")
|
||||
|
||||
def createWidgets(self):
|
||||
self.QUIT = Button(self, text='QUIT', foreground='red',
|
||||
command=self.quit)
|
||||
self.QUIT.pack(side=BOTTOM, fill=BOTH)
|
||||
|
||||
self.draw = Canvas(self, width="5i", height="5i")
|
||||
|
||||
self.speed = Scale(self, orient=HORIZONTAL, from_=-100, to=100)
|
||||
|
||||
self.speed.pack(side=BOTTOM, fill=X)
|
||||
|
||||
# all of these work..
|
||||
self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue")
|
||||
self.draw.pack(side=LEFT)
|
||||
|
||||
def moveThing(self, *args):
|
||||
velocity = self.speed.get()
|
||||
str = float(velocity) / 1000.0
|
||||
str = "%ri" % (str,)
|
||||
self.draw.move("thing", str, str)
|
||||
self.after(10, self.moveThing)
|
||||
|
||||
def __init__(self, master=None):
|
||||
Frame.__init__(self, master)
|
||||
Pack.config(self)
|
||||
self.createWidgets()
|
||||
self.after(10, self.moveThing)
|
||||
|
||||
|
||||
test = Test()
|
||||
|
||||
test.mainloop()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue