From: eficas <>
Date: Tue, 17 May 2005 11:54:51 +0000 (+0000)
Subject: *** empty log message ***
X-Git-Tag: CC_param_poursuite~136
X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4523e2d8899a00de7ff7b56b56a44fc1afbdd151;p=modules%2Feficas.git
*** empty log message ***
---
diff --git a/Accas/A_AU_PLUS_UN.py b/Accas/A_AU_PLUS_UN.py
new file mode 100644
index 00000000..e7742703
--- /dev/null
+++ b/Accas/A_AU_PLUS_UN.py
@@ -0,0 +1,29 @@
+#@ MODIF A_AU_PLUS_UN Accas DATE 28/01/2005 AUTEUR VABHHTS J.PELLET
+# -*- coding: iso-8859-1 -*-
+# CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2005 EDF R&D WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+# ======================================================================
+
+from Noyau import N_REGLE
+from Validation import V_AU_PLUS_UN
+
+class AU_PLUS_UN(V_AU_PLUS_UN.AU_PLUS_UN,N_REGLE.REGLE):
+ """
+ La classe utilise l'initialiseur de REGLE. Il n'est pas
+ nécessaire d'expliciter son initialiseur car
+ V_AU_PLUS_UN.AU_PLUS_UN n'en a pas
+ """
diff --git a/Accas/__init__.py b/Accas/__init__.py
index e8414f9c..21636df6 100644
--- a/Accas/__init__.py
+++ b/Accas/__init__.py
@@ -52,6 +52,7 @@ from A_MCSIMP import MCSIMP
# Les règles
from A_AU_MOINS_UN import AU_MOINS_UN
+from A_AU_PLUS_UN import AU_PLUS_UN
from A_UN_PARMI import UN_PARMI
from A_PRESENT_PRESENT import PRESENT_PRESENT
from A_PRESENT_ABSENT import PRESENT_ABSENT
diff --git a/Aster/Cata/Macro/__init__.py b/Aster/Cata/Macro/__init__.py
index 4aebb58b..a23fff6f 100644
--- a/Aster/Cata/Macro/__init__.py
+++ b/Aster/Cata/Macro/__init__.py
@@ -19,3 +19,6 @@
#
#
# ======================================================================
+print 80
+import traceback
+traceback.print_stack()
diff --git a/Aster/Cata/Macro/calc_fonction_ops.py b/Aster/Cata/Macro/calc_fonction_ops.py
new file mode 100644
index 00000000..8a2907bb
--- /dev/null
+++ b/Aster/Cata/Macro/calc_fonction_ops.py
@@ -0,0 +1,322 @@
+#@ MODIF calc_fonction_ops Macro DATE 12/05/2005 AUTEUR DURAND C.DURAND
+# -*- coding: iso-8859-1 -*-
+# CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2005 EDF R&D WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+# ======================================================================
+
+
+def tocomplex(arg):
+ if arg[0]=='RI' : return complex(arg[1],arg[2])
+ if arg[0]=='MP' : return complex(arg[1]*cos(arg[2]),arg[1]*sin(arg[2]))
+
+def calc_fonction_ops(self,FFT,DERIVE,INTEGRE,LISS_ENVELOP,
+ SPEC_OSCI,ABS,COMB,COMB_C,COMPOSE,EXTRACTION,
+ ENVELOPPE,ASSE,CORR_ACCE,PUISSANCE,INVERSE,
+ NOM_PARA,NOM_RESU,INTERPOL,PROL_DROITE,
+ PROL_GAUCHE,NOM_PARA_FONC,INTERPOL_FONC,PROL_DROITE_FONC,
+ PROL_GAUCHE_FONC,**args):
+ """
+ Ecriture de la macro CALC_FONCTION
+ """
+ ier=0
+ import types
+ import string
+ import copy
+ from math import pi
+ from Utilitai.t_fonction import t_fonction,t_fonction_c,t_nappe
+ from Accas import _F
+ from Cata.cata import nappe_sdaster,fonction_sdaster,fonction_c
+ from Utilitai.Utmess import UTMESS
+ from Numeric import alltrue,less,array,reshape,cos,sin,exp,sqrt
+ from Numeric import choose,zeros,Float
+ import aster_fonctions
+
+ ### On importe les definitions des commandes a utiliser dans la macro
+ DEFI_FONCTION = self.get_cmd('DEFI_FONCTION')
+ DEFI_NAPPE = self.get_cmd('DEFI_NAPPE')
+
+ ### Comptage commandes + déclaration concept sortant
+ self.set_icmd(1)
+ self.DeclareOut('C_out',self.sd)
+
+ ### type de traitement
+ ###
+ if (INTEGRE != None):
+ __ff=INTEGRE['FONCTION'].convert()
+ if INTEGRE['METHODE']=='TRAPEZE' : __ex=__ff.trapeze(INTEGRE['COEF'])
+ if INTEGRE['METHODE']=='SIMPSON' : __ex=__ff.simpson(INTEGRE['COEF'])
+ ###
+ if (DERIVE != None):
+ __ff=DERIVE['FONCTION'].convert()
+ __ex=__ff.derive()
+ ###
+ if (INVERSE != None):
+ __ff=INVERSE['FONCTION'].convert()
+ __ex=__ff.inverse()
+ ###
+ if (ABS != None):
+ __ff=ABS['FONCTION'].convert()
+ __ex=__ff.abs()
+ ###
+ if (COMPOSE != None):
+ __ff=COMPOSE['FONC_RESU'].convert()
+ __fg=COMPOSE['FONC_PARA'].convert()
+ __ex=__ff[__fg]
+ ###
+ if (ASSE != None):
+ __f0=ASSE['FONCTION'][0].convert()
+ __f1=ASSE['FONCTION'][1].convert()
+ __ex=__f0.cat(__f1,ASSE['SURCHARGE'])
+ ###
+ if (COMB != None):
+ if args['LIST_PARA']!=None : vale_x=args['LIST_PARA'].Valeurs()
+ else :
+ vale_x=[]
+ for mcfact in COMB :
+ vale_x=vale_x+mcfact['FONCTION'].Absc()
+ vale_x=dict([(i,0) for i in vale_x]).keys()
+ vale_x.sort()
+ list_fonc=[]
+ if isinstance(self.sd,nappe_sdaster):
+ for mcfact in COMB :
+ list_fonc.append(mcfact['FONCTION'].convert())
+ list_fonch=[]
+ for f in list_fonc :
+ __ex=f
+ for g in list_fonc :
+ __ex=__ex.homo_support(g)
+ list_fonch.append(__ex)
+ list_fonc=list_fonch
+ elif isinstance(self.sd,fonction_sdaster):
+ for mcfact in COMB :
+ __ex=mcfact['FONCTION'].convert()
+ list_fonc.append(__ex.evalfonc(vale_x))
+
+ __ex=list_fonc[0]
+ __ex=__ex*COMB[0]['COEF']
+ i=1
+ for item in list_fonc[1:] :
+ item=item*COMB[i]['COEF']
+ __ex=__ex+item
+ i=i+1
+ ###
+ if (COMB_C != None):
+ if args['LIST_PARA']!=None : vale_x=args['LIST_PARA'].Valeurs()
+ else :
+ vale_x=[]
+ for mcfact in COMB_C :
+ vale_x=vale_x+mcfact['FONCTION'].Absc()
+ vale_x=dict([(i,0) for i in vale_x]).keys()
+ vale_x.sort()
+ list_fonc=[]
+ if isinstance(self.sd,nappe_sdaster):
+ for mcfact in COMB_C :
+ list_fonc.append(mcfact['FONCTION'].convert())
+ list_fonch=[]
+ for f in list_fonc :
+ __ex=f
+ for g in list_fonc :
+ __ex=__ex.homo_support(g)
+ list_fonch.appen(__ex)
+ list_fonc=list_fonch
+ elif isinstance(self.sd,fonction_sdaster) or isinstance(self.sd,fonction_c):
+ for mcfact in COMB_C :
+ __ex=mcfact['FONCTION'].convert(arg='complex')
+ list_fonc.append(__ex.evalfonc(vale_x))
+
+ __ex=list_fonc[0]
+ if COMB_C[0]['COEF_R']!=None: __ex=__ex*complex(COMB_C[0]['COEF_R'])
+ if COMB_C[0]['COEF_C']!=None: __ex=__ex*tocomplex(COMB_C[0]['COEF_C'])
+ i=1
+ for item in list_fonc[1:] :
+ if COMB_C[i]['COEF_R']!=None: coef=complex(COMB_C[i]['COEF_R'])
+ if COMB_C[i]['COEF_C']!=None: coef=tocomplex(COMB_C[i]['COEF_C'])
+ item=item*coef
+ __ex=__ex+item
+ i=i+1
+ ###
+ if (PUISSANCE != None):
+ __ff=PUISSANCE['FONCTION'].convert()
+ __ex=__ff
+ for i in range(PUISSANCE['EXPOSANT']-1) : __ex=__ex*__ff
+ ###
+ if (EXTRACTION != None):
+ if EXTRACTION['PARTIE']=='REEL' : __ex=EXTRACTION['FONCTION'].convert(arg='real')
+ if EXTRACTION['PARTIE']=='IMAG' : __ex=EXTRACTION['FONCTION'].convert(arg='imag')
+ if EXTRACTION['PARTIE']=='MODULE' : __ex=EXTRACTION['FONCTION'].convert(arg='modul')
+ if EXTRACTION['PARTIE']=='PHASE' : __ex=EXTRACTION['FONCTION'].convert(arg='phase')
+ ###
+ if (ENVELOPPE != None):
+ list_fonc=[]
+ if isinstance(self.sd,nappe_sdaster):
+ for f in ENVELOPPE['FONCTION'] : list_fonc.append(f.convert())
+ list_fonch=[]
+ for f in list_fonc :
+ __ff=f
+ for g in list_fonc :
+ __ff=__ff.homo_support(g)
+ list_fonch.append(__ff)
+ list_fonc=list_fonch
+ vale_para=list_fonc[0].vale_para
+ para =list_fonc[0].para
+ l_fonc_f =[]
+ for i in range(len(vale_para)):
+ __ff=list_fonc[0].l_fonc[i]
+ if ENVELOPPE['CRITERE']=='SUP' :
+ for f in list_fonc[1:] : __ff=__ff.sup(f.l_fonc[i])
+ if ENVELOPPE['CRITERE']=='INF' :
+ for f in list_fonc[1:] : __ff=__ff.inf(f.l_fonc[i])
+ l_fonc_f.append(__ff)
+ __ex=t_nappe(vale_para,l_fonc_f,para)
+ elif isinstance(self.sd,fonction_sdaster):
+ for f in ENVELOPPE['FONCTION'] : list_fonc.append(f.convert())
+ __ex=list_fonc[0]
+ if ENVELOPPE['CRITERE']=='SUP' :
+ for f in list_fonc[1:] : __ex=__ex.sup(f)
+ if ENVELOPPE['CRITERE']=='INF' :
+ for f in list_fonc[1:] : __ex=__ex.inf(f)
+ ###
+ if (CORR_ACCE != None):
+ __ex=CORR_ACCE['FONCTION'].convert()
+ para=copy.copy(__ex.para)
+ # suppression de la tendance de l accelero
+ __ex=__ex.suppr_tend()
+ # calcul de la vitesse
+ __ex=__ex.trapeze(0.)
+ # calcul de la tendance de la vitesse : y = a1*x +a0
+ __ex=__ex.suppr_tend()
+ if CORR_ACCE['CORR_DEPL']=='OUI':
+ # suppression de la tendance deplacement
+ # calcul du deplacement : integration
+ __ex=__ex.trapeze(0.)
+ # calcul de la tendance du déplacement : y = a1*x +a0
+ __ex=__ex.suppr_tend()
+ # regeneration de la vitesse : derivation
+ __ex=__ex.derive()
+ # regeneration de l accelero : derivation
+ __ex=__ex.derive()
+ __ex.para=para
+ ###
+ if (FFT != None):
+ if isinstance(self.sd,fonction_c):
+ __ff=FFT['FONCTION'].convert()
+ __ex=__ff.fft(FFT['METHODE'])
+ if isinstance(self.sd,fonction_sdaster):
+ __ff=FFT['FONCTION'].convert(arg='complex')
+ __ex=__ff.fft(FFT['METHODE'],FFT['SYME'])
+ ###
+ if (SPEC_OSCI != None):
+ if SPEC_OSCI['AMOR_REDUIT']==None :
+ l_amor=[0.02,0.05,0.1]
+ UTMESS('I','CALC_FONCTION',' : génération par défaut de 3 amortissements :'+str(l_amor))
+ else :
+ if type(SPEC_OSCI['AMOR_REDUIT']) not in (types.ListType,types.TupleType):
+ l_amor=[SPEC_OSCI['AMOR_REDUIT'],]
+ else : l_amor= SPEC_OSCI['AMOR_REDUIT']
+ if SPEC_OSCI['FREQ']==None and SPEC_OSCI['LIST_FREQ']==None:
+ l_freq=[]
+ for i in range(56) : l_freq.append( 0.2+0.050*i)
+ for i in range( 8) : l_freq.append( 3.0+0.075*i)
+ for i in range(14) : l_freq.append( 3.6+0.100*i)
+ for i in range(24) : l_freq.append( 5.0+0.125*i)
+ for i in range(28) : l_freq.append( 8.0+0.250*i)
+ for i in range( 6) : l_freq.append(15.0+0.500*i)
+ for i in range( 4) : l_freq.append(18.0+1.000*i)
+ for i in range(10) : l_freq.append(22.0+1.500*i)
+ texte=[]
+ for i in range(len(l_freq)/5) :
+ texte.append(' %f %f %f %f %f' %tuple(l_freq[i*5:i*5+5]))
+ UTMESS('I','CALC_FONCTION',' : génération par défaut de 150 fréquences :\n'+'\n'.join(texte))
+ elif SPEC_OSCI['LIST_FREQ']!=None:
+ l_freq=SPEC_OSCI['LIST_FREQ'].Valeurs()
+ elif SPEC_OSCI['FREQ']!=None:
+ if type(SPEC_OSCI['FREQ']) not in (types.ListType,types.TupleType):
+ l_freq=[SPEC_OSCI['FREQ'],]
+ else : l_freq= SPEC_OSCI['FREQ']
+ if abs(SPEC_OSCI['NORME'])<1.E-10 :
+ UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, la norme ne peut etre nulle')
+ if SPEC_OSCI['NATURE_FONC']!='ACCE' :
+ UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, le type de la fonction doit etre ACCE')
+ if SPEC_OSCI['METHODE']!='NIGAM' :
+ UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, seule la méthode NIGAM est codée')
+ eps=1.e-6
+ for amor in l_amor :
+ if amor>(1-eps) :
+ UTMESS('S','CALC_FONCTION',' : SPEC_OSCI, la méthode choisie '\
+ 'suppose des amortissements sous-critiques, amor<1.')
+
+ __ff=SPEC_OSCI['FONCTION'].convert()
+
+ # appel à SPEC_OSCI
+ spectr = aster_fonctions.SPEC_OSCI(__ff.vale_x, __ff.vale_y, l_freq, l_amor)
+
+ # construction de la nappe
+ vale_para = l_amor
+ para = { 'INTERPOL' : ['LIN','LOG'],
+ 'NOM_PARA_FONC' : 'FREQ',
+ 'NOM_PARA' : 'AMOR',
+ 'PROL_DROITE' : 'EXCLU',
+ 'PROL_GAUCHE' : 'EXCLU',
+ 'NOM_RESU' : SPEC_OSCI['NATURE'] }
+ para_fonc = { 'INTERPOL' : ['LOG','LOG'],
+ 'NOM_PARA' : 'FREQ',
+ 'PROL_DROITE' : 'CONSTANT',
+ 'PROL_GAUCHE' : 'EXCLU',
+ 'NOM_RESU' : SPEC_OSCI['NATURE'] }
+ if SPEC_OSCI['NATURE']=='DEPL' : ideb = 0
+ elif SPEC_OSCI['NATURE']=='VITE' : ideb = 1
+ else : ideb = 2
+ l_fonc = []
+ for iamor in range(len(l_amor)) :
+ l_fonc.append(t_fonction(l_freq,spectr[iamor,ideb,:]/SPEC_OSCI['NORME'],para_fonc))
+ __ex=t_nappe(vale_para,l_fonc,para)
+ ###
+ if (LISS_ENVELOP!= None): return
+
+ ### creation de la fonction produite par appel à DEFI_FONCTION
+ ### on récupère les paramètres issus du calcul de __ex
+ ### et on les surcharge par ceux imposés par l'utilisateur
+
+ if isinstance(__ex,t_fonction) or isinstance(__ex,t_fonction_c):
+ para=__ex.para
+ if NOM_PARA !=None : para['NOM_PARA'] =NOM_PARA
+ if NOM_RESU !=None : para['NOM_RESU'] =NOM_RESU
+ if PROL_DROITE!=None : para['PROL_DROITE']=PROL_DROITE
+ if PROL_GAUCHE!=None : para['PROL_GAUCHE']=PROL_GAUCHE
+ if INTERPOL !=None : para['INTERPOL'] =INTERPOL
+ if isinstance(__ex,t_fonction_c): para['VALE_C'] = __ex.tabul()
+ elif isinstance(__ex,t_fonction) : para['VALE'] = __ex.tabul()
+ C_out=DEFI_FONCTION(**para)
+ elif isinstance(__ex,t_nappe):
+ def_fonc=[]
+ for f in __ex.l_fonc :
+ para=f.para
+ def_fonc.append(_F(VALE =f.tabul(),
+ INTERPOL =f.para['INTERPOL'],
+ PROL_DROITE=f.para['PROL_DROITE'],
+ PROL_GAUCHE=f.para['PROL_GAUCHE'],)
+ )
+ para=__ex.para
+ if NOM_PARA !=None : para['NOM_PARA'] =NOM_PARA
+ if NOM_RESU !=None : para['NOM_RESU'] =NOM_RESU
+ if PROL_DROITE !=None : para['PROL_DROITE']=PROL_DROITE
+ if PROL_GAUCHE !=None : para['PROL_GAUCHE']=PROL_GAUCHE
+ if NOM_PARA_FONC !=None : para['NOM_PARA_FONC'] =INTERPOL
+ if INTERPOL_FONC !=None : para['INTERPOL'] =INTERPOL
+ C_out=DEFI_NAPPE(PARA=__ex.vale_para.tolist(),DEFI_FONCTION=def_fonc,**para)
+ return ier
+
diff --git a/Aster/Cata/Macro/calc_precont_ops.py b/Aster/Cata/Macro/calc_precont_ops.py
index b345ca86..a012dfb5 100644
--- a/Aster/Cata/Macro/calc_precont_ops.py
+++ b/Aster/Cata/Macro/calc_precont_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF calc_precont_ops Macro DATE 22/11/2004 AUTEUR LEBOUVIE F.LEBOUVIER
+#@ MODIF calc_precont_ops Macro DATE 07/03/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -319,7 +319,7 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
# 1.6 Blocage de tous les noeuds des cables actifs
# --------------------------------------------------
- __B_CA=AFFE_CHAR_MECA(MODELE=__M_CA,
+ _B_CA=AFFE_CHAR_MECA(MODELE=__M_CA,
DDL_IMPO= _F( GROUP_MA = __GROUP_MA_A,
DX = 0.,
DY = 0.,
@@ -328,11 +328,11 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
# 1.7 Chargements concernant les cables
# -------------------------------------
- __C_CN=AFFE_CHAR_MECA(MODELE=__M_CA,**motscles)
- __C_CA=AFFE_CHAR_MECA(MODELE=MODELE,**motscle2)
- __C_CT=AFFE_CHAR_MECA(MODELE=MODELE,**motscle3)
+ _C_CN=AFFE_CHAR_MECA(MODELE=__M_CA,**motscles)
+ _C_CA=AFFE_CHAR_MECA(MODELE=MODELE,**motscle2)
+ _C_CT=AFFE_CHAR_MECA(MODELE=MODELE,**motscle3)
if CABLE_BP_INACTIF:
- __C_CI=AFFE_CHAR_MECA(MODELE=MODELE,**motscle6)
+ _C_CI=AFFE_CHAR_MECA(MODELE=MODELE,**motscle6)
@@ -343,7 +343,7 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
#-------------------------------------------------------------------
# 2.1 Premiere etape : calcul sur le(s) cable(s) et
- # recuperation des __F_CAs aux noeuds
+ # recuperation des _F_CAs aux noeuds
# on travaile entre tmin et tmax
#-------------------------------------------------------------------
@@ -351,8 +351,8 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
MODELE = __M_CA,
CHAM_MATER = CHAM_MATER,
CARA_ELEM = CARA_ELEM,
- EXCIT =(_F(CHARGE = __B_CA),
- _F(CHARGE = __C_CN),),
+ EXCIT =(_F(CHARGE = _B_CA),
+ _F(CHARGE = _C_CN),),
COMP_INCR =_F( RELATION = 'ELAS',
DEFORMATION = 'PETIT',
TOUT = 'OUI'),
@@ -382,7 +382,7 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
CHAM_GD=__REA,
COEF_R = -1.), )
- __F_CA=AFFE_CHAR_MECA(MODELE=__M_CA,
+ _F_CA=AFFE_CHAR_MECA(MODELE=__M_CA,
VECT_ASSE = __REAC )
@@ -400,12 +400,12 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
if dExcit[-1][i]==None : del dExcit[-1][i]
if CABLE_BP_INACTIF:
- dExcit.append(_F(CHARGE=__C_CI),)
+ dExcit.append(_F(CHARGE=_C_CI),)
# Creation du mots-cle EXCIT pour le STAT_NON_LINE
dExcit1=copy.copy(dExcit)
- dExcit1.append(_F(CHARGE=__C_CA),)
- dExcit1.append(_F(CHARGE = __F_CA,
+ dExcit1.append(_F(CHARGE=_C_CA),)
+ dExcit1.append(_F(CHARGE = _F_CA,
FONC_MULT=__FCT ),)
RES=STAT_NON_LINE(
@@ -439,7 +439,7 @@ def calc_precont_ops(self,reuse,MODELE,CHAM_MATER,CARA_ELEM,EXCIT,
# Creation du mots-cles EXCIT pour le STAT_NON_LINE
dExcit2=copy.copy(dExcit)
- dExcit2.append(_F(CHARGE=__C_CT,) )
+ dExcit2.append(_F(CHARGE=_C_CT,) )
# Calcul sur un seul pas (de __TINT a __TMAX)
RES=STAT_NON_LINE( reuse = RES,
diff --git a/Aster/Cata/Macro/impr_fonction_ops.py b/Aster/Cata/Macro/impr_fonction_ops.py
index 4f2ace21..1e9d6e49 100644
--- a/Aster/Cata/Macro/impr_fonction_ops.py
+++ b/Aster/Cata/Macro/impr_fonction_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF impr_fonction_ops Macro DATE 30/11/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF impr_fonction_ops Macro DATE 11/05/2005 AUTEUR MCOURTOI M.COURTOIS
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -31,9 +31,10 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
"""
macro='IMPR_FONCTION'
import aster
- from Accas import _F
- from Utilitai import Graph
- from Utilitai.Utmess import UTMESS
+ from Accas import _F
+ from Utilitai import Graph
+ from Utilitai.Utmess import UTMESS
+ from Utilitai.UniteAster import UniteAster
ier=0
# La macro compte pour 1 dans la numerotation des commandes
self.set_icmd(1)
@@ -42,21 +43,21 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
# Le nom de la variable doit etre obligatoirement le nom de la commande
CALC_FONC_INTERP = self.get_cmd('CALC_FONC_INTERP')
DEFI_LIST_REEL = self.get_cmd('DEFI_LIST_REEL')
- DEFI_FICHIER = self.get_cmd('DEFI_FICHIER')
DETRUIRE = self.get_cmd('DETRUIRE')
#----------------------------------------------
# 0. Traitement des arguments, initialisations
# unité logique des fichiers réservés
ul_reserve=(8,)
+ UL = UniteAster()
# 0.1. Fichier
nomfich=None
if args['UNITE'] and args['UNITE']<>6:
- nomfich='fort.'+str(args['UNITE'])
+ nomfich=UL.Nom(args['UNITE'])
if INFO==2:
print ' Nom du fichier :',nomfich
- if nomfich and os.path.exists(nomfich):
+ if nomfich and os.path.exists(nomfich) and os.stat(nomfich).st_size<>0:
if FORMAT=='XMGRACE':
niv='A'
else:
@@ -74,7 +75,8 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
for Ci in COURBE:
iocc+=1
dC = Ci.cree_dict_valeurs(Ci.mc_liste)
- if dC.has_key('LIST_PARA') and i0==0: i0=iocc
+ if dC.has_key('LIST_PARA') and dC['LIST_PARA']!=None and i0==0:
+ i0=iocc
for mc in dC.keys():
if dC[mc]==None: del dC[mc]
Courbe.append(dC)
@@ -142,6 +144,7 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
if typ=='nappe_sdaster':
lpar,lval=obj.Valeurs()
dico,ldicf=obj.Parametres()
+ Leg=dCi['LEGENDE']
for i in range(len(lpar)):
p=lpar[i]
lx=lval[i][0]
@@ -169,12 +172,16 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
lx=lv2[0][0]
ly=lv2[0][1]
# on stocke les données dans le Graph
+ nomresu=dic['NOM_RESU'].strip()+'_'+str(len(graph.Legendes))
dicC={
'Val' : [lx,ly],
- 'Lab' : [dic['NOM_PARA_FONC'],dic['NOM_RESU']]
+ 'Lab' : [dic['NOM_PARA_FONC'],nomresu]
}
+ # ajoute la valeur du paramètre
+ dCi['LEGENDE'] = '%s %s=%g' % (Leg,dic['NOM_PARA'].strip(),p)
Graph.AjoutParaCourbe(dicC, args=dCi)
graph.AjoutCourbe(**dicC)
+ DETRUIRE(CONCEPT=_F(NOM=('li__','ftmp__'),),ALARME='NON',INFO=1)
else:
ftmp__=obj
dpar=ftmp__.Parametres()
@@ -194,17 +201,19 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
lx=lval[0]
lr=lval[1]
if typ=='fonction_c' and dCi.has_key('PARTIE'):
- if dCi['PARTIE']=='COMPLEXE' : lr=lval[2]
+ if dCi['PARTIE']=='IMAG' : lr=lval[2]
# on stocke les données dans le Graph
if typ=='fonction_c' and not dCi.has_key('PARTIE'):
+ nomresu=dpar['NOM_RESU'].strip()+'_'+str(len(graph.Legendes))
dicC={
'Val' : lval,
- 'Lab' : [dpar['NOM_PARA'],dpar['NOM_RESU']+'_R',dpar['NOM_RESU']+'_I']
+ 'Lab' : [dpar['NOM_PARA'],nomresu+'_R',nomresu+'_I']
}
else:
+ nomresu=dpar['NOM_RESU'].strip()+'_'+str(len(graph.Legendes))
dicC={
'Val' : [lx,lr],
- 'Lab' : [dpar['NOM_PARA'],dpar['NOM_RESU']]
+ 'Lab' : [dpar['NOM_PARA'],nomresu]
}
Graph.AjoutParaCourbe(dicC, args=dCi)
graph.AjoutCourbe(**dicC)
@@ -275,14 +284,18 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
# on stocke les données dans le Graph
# on imprime la liste des paramètres seulement si LIST_PARA
if intloc:
+ nomresur=dpar['NOM_RESU'].strip()+'_'+str(len(graph.Legendes))
+ nomresu2=dpa2['NOM_RESU'].strip()+'_'+str(len(graph.Legendes)+1)
dicC={
'Val' : [lt,lx,ly],
- 'Lab' : [dpar['NOM_PARA'],dpar['NOM_RESU'],dpa2['NOM_RESU']]
+ 'Lab' : [dpar['NOM_PARA'],nomresur,nomresu2]
}
else:
+ nomresur=dpar['NOM_RESU'].strip()+'_'+str(len(graph.Legendes))
+ nomresu2=dpa2['NOM_RESU'].strip()+'_'+str(len(graph.Legendes)+1)
dicC={
'Val' : [lx,ly],
- 'Lab' : [dpar['NOM_RESU'],dpa2['NOM_RESU']]
+ 'Lab' : [nomresur,nomresu2]
}
Graph.AjoutParaCourbe(dicC, args=dCi)
graph.AjoutCourbe(**dicC)
@@ -358,7 +371,7 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
elif FORMAT=='AGRAF':
nomdigr=None
if args['UNITE_DIGR']<>6:
- nomdigr='fort.'+str(args['UNITE_DIGR'])
+ nomdigr=UL.Nom(args['UNITE_DIGR'])
kargs['FICHIER']=[nomfich, nomdigr]
kargs['dform']={ 'formR' : '%12.5E' }
@@ -373,21 +386,15 @@ def impr_fonction_ops(self, FORMAT, COURBE, INFO, **args):
# Traiter le cas des UL réservées
if args['UNITE'] and args['UNITE'] in ul_reserve:
- DEFI_FICHIER( ACTION='LIBERER', UNITE=args['UNITE'], )
+ UL.Etat(args['UNITE'], etat='F')
if FORMAT=='AGRAF' and args['UNITE_DIGR']<>args['UNITE'] \
and args['UNITE_DIGR'] in ul_reserve:
- DEFI_FICHIER( ACTION='LIBERER', UNITE=args['UNITE_DIGR'], )
+ UL.Etat(args['UNITE_DIGR'], etat='F')
# 2.4. On trace !
graph.Trace(**kargs)
# 99. Traiter le cas des UL réservées
- if args['UNITE'] and args['UNITE'] in ul_reserve:
- DEFI_FICHIER( ACTION='ASSOCIER', UNITE=args['UNITE'],
- TYPE='ASCII', ACCES='APPEND' )
- if FORMAT=='AGRAF' and args['UNITE_DIGR']<>args['UNITE'] \
- and args['UNITE_DIGR'] in ul_reserve:
- DEFI_FICHIER( ACTION='ASSOCIER', UNITE=args['UNITE_DIGR'],
- TYPE='ASCII', ACCES='APPEND' )
+ UL.EtatInit()
return ier
diff --git a/Aster/Cata/Macro/impr_table_ops.py b/Aster/Cata/Macro/impr_table_ops.py
index ca1a492f..74776f0b 100644
--- a/Aster/Cata/Macro/impr_table_ops.py
+++ b/Aster/Cata/Macro/impr_table_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF impr_table_ops Macro DATE 30/11/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF impr_table_ops Macro DATE 11/05/2005 AUTEUR MCOURTOI M.COURTOIS
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -35,9 +35,10 @@ def impr_table_ops(self, FORMAT, TABLE, INFO, **args):
"""
macro='IMPR_TABLE'
import aster
- from Accas import _F
- from Cata.cata import table_jeveux
- from Utilitai.Utmess import UTMESS
+ from Accas import _F
+ from Cata.cata import table_jeveux
+ from Utilitai.Utmess import UTMESS
+ from Utilitai.UniteAster import UniteAster
ier=0
# La macro compte pour 1 dans la numerotation des commandes
self.set_icmd(1)
@@ -45,19 +46,19 @@ def impr_table_ops(self, FORMAT, TABLE, INFO, **args):
# On importe les definitions des commandes a utiliser dans la macro
# Le nom de la variable doit etre obligatoirement le nom de la commande
DETRUIRE = self.get_cmd('DETRUIRE')
- DEFI_FICHIER = self.get_cmd('DEFI_FICHIER')
RECU_FONCTION = self.get_cmd('RECU_FONCTION')
#----------------------------------------------
# 0. Traitement des arguments, initialisations
# unité logique des fichiers réservés
ul_reserve=(8,)
+ UL = UniteAster()
# 0.1. Fichier
nomfich=None
if args['UNITE'] and args['UNITE']<>6:
- nomfich='fort.'+str(args['UNITE'])
- if nomfich and os.path.exists(nomfich):
+ nomfich=UL.Nom(args['UNITE'])
+ if nomfich and os.path.exists(nomfich) and os.stat(nomfich).st_size<>0:
if FORMAT=='XMGRACE':
UTMESS('A',macro,'Le fichier '+nomfich+' existe déjà, on écrit ' \
'à la suite.')
@@ -111,7 +112,7 @@ def impr_table_ops(self, FORMAT, TABLE, INFO, **args):
# 0.4.2. Traiter le cas des UL réservées
if args['UNITE'] and args['UNITE'] in ul_reserve:
- DEFI_FICHIER( ACTION='LIBERER', UNITE=args['UNITE'], )
+ UL.Etat(args['UNITE'], etat='F')
#----------------------------------------------
# Boucle sur les tables
@@ -205,9 +206,7 @@ def impr_table_ops(self, FORMAT, TABLE, INFO, **args):
DETRUIRE(CONCEPT=_F(NOM=('__fonc',),), ALARME='NON', INFO=1,)
# 99. Traiter le cas des UL réservées
- if args['UNITE'] and args['UNITE'] in ul_reserve:
- DEFI_FICHIER( ACTION='ASSOCIER', UNITE=args['UNITE'],
- TYPE='ASCII', ACCES='APPEND' )
+ UL.EtatInit()
return ier
diff --git a/Aster/Cata/Macro/info_fonction_ops.py b/Aster/Cata/Macro/info_fonction_ops.py
new file mode 100644
index 00000000..b728f6a4
--- /dev/null
+++ b/Aster/Cata/Macro/info_fonction_ops.py
@@ -0,0 +1,252 @@
+#@ MODIF info_fonction_ops Macro DATE 12/05/2005 AUTEUR DURAND C.DURAND
+# -*- coding: iso-8859-1 -*-
+# CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2005 EDF R&D WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+# ======================================================================
+def info_fonction_ops(self,RMS,NOCI_SEISME,MAX,NORME,ECART_TYPE,**args):
+ """
+ Ecriture de la macro INFO_FONCTION
+ """
+ ier=0
+ import string
+ from Utilitai.t_fonction import t_fonction,t_fonction_c,t_nappe
+ import math
+ from Accas import _F
+ from Utilitai.Utmess import UTMESS
+
+ ### On importe les definitions des commandes a utiliser dans la macro
+ CREA_TABLE = self.get_cmd('CREA_TABLE')
+ CALC_FONCTION = self.get_cmd('CALC_FONCTION')
+
+ ### Comptage commandes + déclaration concept sortant
+ self.set_icmd(1)
+ self.DeclareOut('C_out',self.sd)
+
+ ### type de traitement
+
+ ###
+ if (MAX != None):
+ __ff=MAX['FONCTION'].convert()
+ __ex=__ff.extreme()
+ n_mini=len(__ex['min'])
+ n_maxi=len(__ex['max'])
+ listeMCF=[_F(LISTE_K=[MAX['FONCTION'].nom]*(n_mini+n_maxi),PARA='FONCTION'),
+ _F(LISTE_K=['MINI',]*n_mini+['MAXI',]*n_maxi,PARA='TYPE'),]
+ if isinstance(__ff,t_nappe) :
+ listeMCF=listeMCF+[\
+ _F(LISTE_R=[i[0] for i in __ex['min']]+[i[0] for i in __ex['max']],PARA=__ff.para['NOM_PARA']),\
+ _F(LISTE_R=[i[1] for i in __ex['min']]+[i[1] for i in __ex['max']],PARA=__ff.para['NOM_PARA_FONC']),\
+ _F(LISTE_R=[i[2] for i in __ex['min']]+[i[2] for i in __ex['max']],PARA=__ff.para['NOM_RESU'])]
+ else :
+ listeMCF=listeMCF+[\
+ _F(LISTE_R=[i[0] for i in __ex['min']]+[i[0] for i in __ex['max']],PARA=__ff.para['NOM_PARA']),\
+ _F(LISTE_R=[i[1] for i in __ex['min']]+[i[1] for i in __ex['max']],PARA=__ff.para['NOM_RESU'])]
+ C_out=CREA_TABLE(LISTE=listeMCF)
+
+ ###
+ if (ECART_TYPE != None):
+ __ff=ECART_TYPE['FONCTION'].convert()
+ if ECART_TYPE['INST_INIT']!=None : tini=ECART_TYPE['INST_INIT']
+ else : tini=__ff.vale_x[0]
+ if ECART_TYPE['INST_FIN' ]!=None : tfin=ECART_TYPE['INST_FIN' ]
+ else : tfin=__ff.vale_x[-1]
+ __ff=__ff.cut(tini,__ff.vale_x[-1],ECART_TYPE['PRECISION'],ECART_TYPE['CRITERE'])
+ __ff=__ff.cut(__ff.vale_x[0],tfin,ECART_TYPE['PRECISION'],ECART_TYPE['CRITERE'])
+ if ECART_TYPE['METHODE' ]=='SIMPSON' : __ex=__ff.simpson(0.)
+ if ECART_TYPE['METHODE' ]=='TRAPEZE' : __ex=__ff.trapeze(0.)
+ fmoy=__ex.vale_y[-1]/(__ff.vale_x[-1]-__ff.vale_x[0])
+ __ff=__ff+(-1*fmoy)
+ __ff=__ff*__ff
+ if ECART_TYPE['METHODE' ]=='SIMPSON' : __ez=__ff.simpson(0.)
+ if ECART_TYPE['METHODE' ]=='TRAPEZE' : __ez=__ff.trapeze(0.)
+ sigma=math.sqrt(__ez.vale_y[-1]/(__ff.vale_x[-1]-__ff.vale_x[0]))
+ C_out=CREA_TABLE(LISTE=(_F(LISTE_K=ECART_TYPE['FONCTION'].nom,PARA='FONCTION'),
+ _F(LISTE_K=ECART_TYPE['METHODE'] ,PARA='METHODE'),
+ _F(LISTE_R=fmoy ,PARA='MOYENNE'),
+ _F(LISTE_R=sigma ,PARA='ECART_TYPE'),
+ _F(LISTE_R=tini ,PARA='INST_INIT'),
+ _F(LISTE_R=tfin ,PARA='INST_FIN'),)
+ )
+
+ ###
+ if (RMS != None):
+ RMS =list(RMS)
+ sigm =[]
+ tmpi =[]
+ tmpf =[]
+ nomf =[]
+ meth =[]
+ for i_rms in RMS :
+ __ff=i_rms['FONCTION'].convert()
+ if i_rms['INST_INIT']!=None : tini=i_rms['INST_INIT']
+ else : tini=__ff.vale_x[0]
+ if i_rms['INST_FIN' ]!=None : tfin=i_rms['INST_FIN' ]
+ else : tfin=__ff.vale_x[-1]
+ __ff=__ff.cut(tini,__ff.vale_x[-1],i_rms['PRECISION'],i_rms['CRITERE'])
+ __ff=__ff.cut(__ff.vale_x[0],tfin,i_rms['PRECISION'],i_rms['CRITERE'])
+ __ff=__ff*__ff
+ if i_rms['METHODE' ]=='SIMPSON' : __ez=__ff.simpson(0.)
+ if i_rms['METHODE' ]=='TRAPEZE' :
+ __ez=__ff.trapeze(0.)
+ sigm.append(math.sqrt(__ez.vale_y[-1]/(__ff.vale_x[-1]-__ff.vale_x[0])))
+ tmpi.append(tini)
+ tmpf.append(tfin)
+ nomf.append(i_rms['FONCTION'].nom)
+ meth.append(i_rms['METHODE'])
+ C_out=CREA_TABLE(LISTE=(_F(LISTE_K=nomf ,PARA='FONCTION'),
+ _F(LISTE_K=meth ,PARA='METHODE'),
+ _F(LISTE_R=tmpi ,PARA='INST_INIT'),
+ _F(LISTE_R=tmpf ,PARA='INST_FIN'),
+ _F(LISTE_R=sigm ,PARA='RMS'), )
+ )
+
+ ###
+ if (NORME != None):
+ __ff=NORME['FONCTION'].convert()
+ norme=[]
+ for __fi in __ff.l_fonc :
+ norme.append(__fi.normel2())
+ nom=[NORME['FONCTION'].nom,]*len(norme)
+ C_out=CREA_TABLE(LISTE=(_F(LISTE_R=norme ,PARA='NORME'),
+ _F(LISTE_K=nom ,PARA='FONCTION'), )
+ )
+
+ ###
+ if (NOCI_SEISME != None):
+ l_table=[]
+ if NOCI_SEISME['SPEC_OSCI'] !=None :
+ ### cas intensité spectrale d'une nappe de SRO
+ ### la seule option licite est INTE_SPEC
+ UTMESS('I','INFO_FONCTION',''' : intensite spectrale, avant de calculer l'\
+intensite spectrale, il est prudent de verifier la norme de la nappe sur laquelle \
+porte le calcul, ceci peut etre une source d erreurs.''')
+ amor=NOCI_SEISME['AMOR_REDUIT']
+ fini=NOCI_SEISME['FREQ_INIT' ]
+ ffin=NOCI_SEISME['FREQ_FIN' ]
+ __sp =NOCI_SEISME['SPEC_OSCI'].convert()
+ vale_x=__sp.l_fonc[0].vale_x
+ vale_y=[__sp(amor,f) for f in vale_x]
+ para =__sp.l_fonc[0].para
+ __srov=t_fonction(vale_x,vale_y,para)
+ if NOCI_SEISME['NATURE']=='DEPL' :
+ __srov.vale_y=(__srov.vale_y/__srov.vale_x)*2.*math.pi
+ elif NOCI_SEISME['NATURE']=='VITE' :
+ __srov.vale_y=__srov.vale_y/__srov.vale_x/__srov.vale_x
+ elif NOCI_SEISME['NATURE']=='ACCE' :
+ __srov.vale_y=__srov.vale_y/__srov.vale_x/__srov.vale_x
+ __srov.vale_y=__srov.vale_y/__srov.vale_x/2./math.pi
+ __srov=__srov.cut(fini,ffin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ insp=__srov.trapeze(0.).vale_y[-1]
+ l_table.append(_F(LISTE_R=fini ,PARA='FREQ_INIT' ))
+ l_table.append(_F(LISTE_R=ffin ,PARA='FREQ_FIN' ))
+ l_table.append(_F(LISTE_R=amor ,PARA='AMOR_REDUIT'))
+ l_table.append(_F(LISTE_R=insp ,PARA='INTE_SPECT' ))
+ if NOCI_SEISME['FONCTION'] !=None :
+ ### cas fonction
+ l_table.append(_F(LISTE_K=NOCI_SEISME['FONCTION'].nom,PARA='FONCTION'))
+ __ac=NOCI_SEISME['FONCTION'].convert()
+ option= NOCI_SEISME['OPTION']
+ if NOCI_SEISME['INST_INIT']!=None : tdeb=NOCI_SEISME['INST_INIT']
+ else : tdeb=__ac.vale_x[0]
+ if NOCI_SEISME['INST_FIN' ]!=None : tfin=NOCI_SEISME['INST_FIN' ]
+ else : tfin=__ac.vale_x[-1]
+ # calcul de la vitesse :
+ __vi=__ac.trapeze(NOCI_SEISME['COEF'])
+ # calcul du déplacement :
+ __de=__vi.trapeze(NOCI_SEISME['COEF'])
+ # calcul de |acceleration| :
+ __aa=__ac.abs()
+ # calcul de integrale(|acceleration|) :
+ ### on "coupe" la fonction entre tdeb et tfin
+ __ac=__ac.cut(tdeb,tfin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ __vi=__vi.cut(tdeb,tfin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ __de=__de.cut(tdeb,tfin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ __aa=__aa.cut(tdeb,tfin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ if NOCI_SEISME['FREQ' ]!=None : l_freq=NOCI_SEISME['FREQ']
+ elif NOCI_SEISME['LIST_FREQ']!=None : l_freq=NOCI_SEISME['LIST_FREQ'].Valeurs()
+ else :
+ # fréquences par défaut
+ l_freq=[]
+ for i in range(56) : l_freq.append( 0.2+0.050*i)
+ for i in range( 8) : l_freq.append( 3.0+0.075*i)
+ for i in range(14) : l_freq.append( 3.6+0.100*i)
+ for i in range(24) : l_freq.append( 5.0+0.125*i)
+ for i in range(28) : l_freq.append( 8.0+0.250*i)
+ for i in range( 6) : l_freq.append(15.0+0.500*i)
+ for i in range( 4) : l_freq.append(18.0+1.000*i)
+ for i in range(10) : l_freq.append(22.0+1.500*i)
+ if option in('TOUT','MAXI','ACCE_SUR_VITE') :
+ # calcul du max des valeurs absolues
+ maxa_ac=__ac.abs().extreme()['max'][0][1]
+ maxa_vi=__vi.abs().extreme()['max'][0][1]
+ maxa_de=__de.abs().extreme()['max'][0][1]
+ l_table.append(_F(LISTE_R=maxa_ac,PARA='ACCE_MAX'))
+ l_table.append(_F(LISTE_R=maxa_vi,PARA='VITE_MAX'))
+ l_table.append(_F(LISTE_R=maxa_de,PARA='DEPL_MAX'))
+ l_table.append(_F(LISTE_R=maxa_ac/maxa_vi,PARA='ACCE_SUR_VITE'))
+ if option in('TOUT','INTE_ARIAS') :
+ __a2=__ac*__ac
+ inte_arias=__a2.trapeze(0.).vale_y[-1]
+ inte_arias=inte_arias*math.pi/NOCI_SEISME['PESANTEUR']/2.
+ l_table.append(_F(LISTE_R=inte_arias,PARA='INTE_ARIAS'))
+ if option in('TOUT','POUV_DEST') :
+ __v2=__vi*__vi
+ pouv_dest=__v2.trapeze(0.).vale_y[-1]
+ pouv_dest=pouv_dest*(math.pi)**3/NOCI_SEISME['PESANTEUR']/2.
+ l_table.append(_F(LISTE_R=pouv_dest,PARA='POUV_DEST'))
+ if option in('TOUT','VITE_ABSO_CUMU') :
+ __vc=__aa.trapeze(0.)
+ vite_abso=__vc.vale_y[-1]
+ l_table.append(_F(LISTE_R=vite_abso,PARA='VITE_ABSO_CUMU'))
+ if option in('TOUT','INTE_SPEC') :
+ amor=NOCI_SEISME['AMOR_REDUIT']
+ fini=NOCI_SEISME['FREQ_INIT' ]
+ ffin=NOCI_SEISME['FREQ_FIN' ]
+ __so= CALC_FONCTION(SPEC_OSCI=_F(
+ NATURE ='VITE',
+ NATURE_FONC='ACCE',
+ FONCTION =NOCI_SEISME['FONCTION'],
+ METHODE ='NIGAM',
+ NORME =NOCI_SEISME['NORME'],
+ FREQ =l_freq,
+ AMOR_REDUIT=(amor,)
+ ), )
+ __srov=__so.convert().l_fonc[0]
+ __srov=__srov.cut(fini,ffin,NOCI_SEISME['PRECISION'],NOCI_SEISME['CRITERE'])
+ __srov.vale_y=__srov.vale_y/__srov.vale_x/__srov.vale_x
+ insp=__srov.trapeze(0.).vale_y[-1]
+ l_table.append(_F(LISTE_R=fini ,PARA='FREQ_INIT' ))
+ l_table.append(_F(LISTE_R=ffin ,PARA='FREQ_FIN' ))
+ l_table.append(_F(LISTE_R=amor ,PARA='AMOR_REDUIT'))
+ l_table.append(_F(LISTE_R=insp ,PARA='INTE_SPECT' ))
+ if option in('TOUT','DUREE_PHAS_FORT') :
+ __a2=__ac*__ac
+ __i2=__a2.trapeze(0.)
+ arias = __i2.vale_y[-1]*math.pi/NOCI_SEISME['PESANTEUR']/2.
+ valinf = arias * NOCI_SEISME['BORNE_INF']
+ valsup = arias * NOCI_SEISME['BORNE_SUP']
+ for i in range(len(__i2.vale_x)) :
+ ariask = __i2.vale_y[i]*math.pi/NOCI_SEISME['PESANTEUR']/2.
+ if ariask>=valinf : break
+ for j in range(len(__i2.vale_x)-1,-1,-1) :
+ ariask = __i2.vale_y[j]*math.pi/NOCI_SEISME['PESANTEUR']/2.
+ if ariask<=valsup : break
+ dphfor = __i2.vale_x[j] - __i2.vale_x[i]
+ l_table.append(_F(LISTE_R=dphfor,PARA='DUREE_PHAS_FORT'))
+ C_out=CREA_TABLE(LISTE=l_table)
+
+ return ier
diff --git a/Aster/Cata/Macro/macr_ascouf_calc_ops.py b/Aster/Cata/Macro/macr_ascouf_calc_ops.py
index fda98363..4c7c9b96 100644
--- a/Aster/Cata/Macro/macr_ascouf_calc_ops.py
+++ b/Aster/Cata/Macro/macr_ascouf_calc_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_ascouf_calc_ops Macro DATE 22/11/2004 AUTEUR LEBOUVIE F.LEBOUVIER
+#@ MODIF macr_ascouf_calc_ops Macro DATE 08/02/2005 AUTEUR CIBHHLV L.VIVAN
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -358,6 +358,7 @@ def macr_ascouf_calc_ops(self,TYPE_MAILLAGE,CL_BOL_P2_GV,MAILLAGE,MODELE,CHAM_MA
# l epaisseur
#
l_grno=MAILLAGE.LIST_GROUP_NO()
+ tabprl=[None]*4
tablig=[None]*4
#
# prelevements des ligaments circonferentiels et longitudinaux
@@ -370,15 +371,20 @@ def macr_ascouf_calc_ops(self,TYPE_MAILLAGE,CL_BOL_P2_GV,MAILLAGE,MODELE,CHAM_MA
elif (tgrno[0][:4] in LIG) and (tgrno[0][4:6] not in ('GV','TU','MI')): lgrno.append(tgrno[0])
#
motscles={}
- motscles['SEGMENT']=[]
- for grno in lgrno : motscles['SEGMENT'].append(_F(INTITULE=grno,GROUP_NO=grno))
+ motscles['ACTION']=[]
+ for grno in lgrno :
+ motscles['ACTION'].append(_F(RESULTAT=nomres,
+ NOM_CHAM='SIEF_ELNO_ELGA',
+ TOUT_CMP='OUI',
+ INTITULE=grno,
+ GROUP_NO=grno,
+ OPERATION='EXTRACTION',))
motscles['TITRE']='TABLE DE POST-TRAITEMENT SECTION SOUS-EPAISSEUR'
+ tabprl[1]=POST_RELEVE_T(**motscles)
tablig[1]=POST_RCCM(MATER = rccmat,
- MAILLAGE = MAILLAGE,
TYPE_RESU_MECA = 'EVOLUTION',
OPTION = 'PM_PB',
- TRANSITOIRE=_F(RESULTAT=nomres,
- NOM_CHAM='SIEF_ELNO_ELGA',),**motscles)
+ TRANSITOIRE=_F(TABL_RESU_MECA = tabprl[1],),)
#
motscles={}
motscles['ACTION']=[]
@@ -436,6 +442,7 @@ def macr_ascouf_calc_ops(self,TYPE_MAILLAGE,CL_BOL_P2_GV,MAILLAGE,MODELE,CHAM_MA
# les 8 ligaments sont tous les 45 degres
#
ACOUR = mc_IMPR_TABLE['ANGLE']*pi/180.0
+ secprl=[None]*3
secrcm=[None]*3
secinv=[None]*3
secmoy=[None]*3
@@ -450,15 +457,21 @@ def macr_ascouf_calc_ops(self,TYPE_MAILLAGE,CL_BOL_P2_GV,MAILLAGE,MODELE,CHAM_MA
#
# moyenne RCCM sur les sections MI,TU et GV
#
- motscles['SEGMENT']=[]
- for j in range(8) : motscles['SEGMENT'].append(_F(INTITULE=LIG[j]+SECT[i],
- GROUP_NO=LIG[j]+SECT[i]))
- secrcm[i] = POST_RCCM( MAILLAGE = MAILLAGE ,
- MATER = rccmat ,
- TYPE_RESU_MECA = 'EVOLUTION' ,
- OPTION = 'PM_PB' ,
- TRANSITOIRE = _F(RESULTAT = nomres,NOM_CHAM='SIEF_ELNO_ELGA'),
- **motscles)
+ motscles={}
+ motscles['ACTION']=[]
+ for j in range(8) :
+ motscles['ACTION'].append(_F(RESULTAT=nomres,
+ NOM_CHAM='SIEF_ELNO_ELGA',
+ TOUT_CMP='OUI',
+ INTITULE=LIG[j]+SECT[i],
+ GROUP_NO=LIG[j]+SECT[i],
+ OPERATION='EXTRACTION',))
+ motscles['TITRE']='TABLE DE POST-TRAITEMENT MOYENNE RCCM SECTION '+SECT[i]
+ secprl[i]=POST_RELEVE_T(**motscles)
+ secrcm[i]=POST_RCCM(MATER = rccmat,
+ TYPE_RESU_MECA = 'EVOLUTION',
+ OPTION = 'PM_PB',
+ TRANSITOIRE=_F(TABL_RESU_MECA = secprl[i],),)
#
# invariants sur les sections MI,TU et GV
#
diff --git a/Aster/Cata/Macro/macr_ascouf_mail_ops.py b/Aster/Cata/Macro/macr_ascouf_mail_ops.py
index f7b95acf..fe02927a 100644
--- a/Aster/Cata/Macro/macr_ascouf_mail_ops.py
+++ b/Aster/Cata/Macro/macr_ascouf_mail_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_ascouf_mail_ops Macro DATE 30/11/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF macr_ascouf_mail_ops Macro DATE 09/05/2005 AUTEUR LEBOUVIE F.LEBOUVIER
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -2339,8 +2339,8 @@ def macr_ascouf_mail_ops(self,EXEC_MAILLAGE,TYPE_ELEM,COUDE,
# coude fissure
#
if FISS_COUDE!=None:
- if (RM/EP1)<5. or (RM/EP1)>12.:
- print ' valeur hors domaine de validite (5,12)'
+ if (RM/EP1)<5. or (RM/EP1)>50.:
+ print ' valeur hors domaine de validite (5,50)'
print ' rapport RM/EP1 :',(RM/EP1)
self.cr.fatal(" erreur donnees ")
ier = ier+1
diff --git a/Aster/Cata/Macro/macr_aspic_calc_ops.py b/Aster/Cata/Macro/macr_aspic_calc_ops.py
index b6d91b36..5426c395 100644
--- a/Aster/Cata/Macro/macr_aspic_calc_ops.py
+++ b/Aster/Cata/Macro/macr_aspic_calc_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_aspic_calc_ops Macro DATE 22/11/2004 AUTEUR LEBOUVIE F.LEBOUVIER
+#@ MODIF macr_aspic_calc_ops Macro DATE 08/02/2005 AUTEUR CIBHHLV L.VIVAN
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -427,18 +427,21 @@ def macr_aspic_calc_ops(self,TYPE_MAILLAGE,TUBULURE,MAILLAGE,MODELE,CHAM_MATER,C
if i<10 : NUME = '0'+str(i)
else : NUME = str(i)
mcsimp={}
- mcsimp['PRECISION']=55.E-1
- mcsimp['GROUP_NO' ]='LD'+str(i)
+ mcsimp['INTITULE' ]='LD'+str(i)
+ mcsimp['GROUP_NO' ]='LD'+str(i)
+ mcsimp['RESULTAT' ]=nomres
+ mcsimp['TOUT_ORDRE' ]='OUI'
+ mcsimp['NOM_CHAM' ]='SIEF_ELNO_ELGA'
+ mcsimp['PRECISION' ]=55.E-1
+ mcsimp['TOUT_CMP' ]='OUI'
+ mcsimp['OPERATION' ]='EXTRACTION'
mcfact.append( _F(**mcsimp) )
- __pmpbsd=POST_RCCM(MATER = MRCCM,
- MAILLAGE = MAILLAGE,
+ __prelsd=POST_RELEVE_T(ACTION=mcfact)
+ __pmpbsd=POST_RCCM(OPTION = 'PM_PB',
TYPE_RESU_MECA = 'EVOLUTION',
- TYPE_RESU = 'VALE_MAX',
- OPTION = 'PM_PB',
- SEGMENT = mcfact,
- TRANSITOIRE = _F(RESULTAT =nomres,
- NOM_CHAM ='SIEF_ELNO_ELGA',
- TOUT_ORDRE='OUI',),
+ TYPE_RESU = 'VALE_MAX',
+ MATER = MRCCM,
+ TRANSITOIRE = _F(TABL_RESU_MECA = __prelsd,),
TITRE = '-- TRAITEMENT DES AZIMUTS DROITS --',)
IMPR_TABLE(TABLE = __pmpbsd, )
#
@@ -514,18 +517,21 @@ def macr_aspic_calc_ops(self,TYPE_MAILLAGE,TUBULURE,MAILLAGE,MODELE,CHAM_MATER,C
if i<10 : NUME = '0'+str(i)
else : NUME = str(i)
mcsimp={}
- mcsimp['PRECISION']=55.E-1
- mcsimp['GROUP_NO' ]='LI'+str(i)
+ mcsimp['INTITULE' ]='LI'+str(i)
+ mcsimp['GROUP_NO' ]='LI'+str(i)
+ mcsimp['RESULTAT' ]=nomres
+ mcsimp['TOUT_ORDRE' ]='OUI'
+ mcsimp['NOM_CHAM' ]='SIEF_ELNO_ELGA'
+ mcsimp['PRECISION' ]=55.E-1
+ mcsimp['TOUT_CMP' ]='OUI'
+ mcsimp['OPERATION' ]='EXTRACTION'
mcfact.append( _F(**mcsimp) )
- __pmpbsi=POST_RCCM(MATER = MRCCM,
- MAILLAGE = MAILLAGE,
+ __prelsi=POST_RELEVE_T(ACTION=mcfact)
+ __pmpbsi=POST_RCCM(OPTION = 'PM_PB',
TYPE_RESU_MECA = 'EVOLUTION',
- TYPE_RESU = 'VALE_MAX',
- OPTION = 'PM_PB',
- SEGMENT = mcfact,
- TRANSITOIRE = _F(RESULTAT =nomres,
- NOM_CHAM ='SIEF_ELNO_ELGA',
- TOUT_ORDRE='OUI',),
+ TYPE_RESU = 'VALE_MAX',
+ MATER = MRCCM,
+ TRANSITOIRE = _F(TABL_RESU_MECA = __prelsi,),
TITRE = '-- TRAITEMENT DES AZIMUTS INCLINES --',)
IMPR_TABLE(TABLE = __pmpbsi, )
#
diff --git a/Aster/Cata/Macro/macr_cabri_mail_ops.py b/Aster/Cata/Macro/macr_cabri_mail_ops.py
index d5ad388f..92154545 100644
--- a/Aster/Cata/Macro/macr_cabri_mail_ops.py
+++ b/Aster/Cata/Macro/macr_cabri_mail_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_cabri_mail_ops Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF macr_cabri_mail_ops Macro DATE 07/02/2005 AUTEUR MABBAS M.ABBAS
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -72,11 +72,11 @@ def macr_cabri_mail_ops(self,EXEC_MAILLAGE,RAFF_MAILLAGE,VERI_MAIL,GEOM_BRID,
imp_formF = 1
else:
imp_formF = 0
- if IMPRESSION['FICHIER']!=None:
- imp_fich = IMPRESSION['FICHIER']
- imp_fichF = 1
- else:
- imp_fichF = 0
+# if IMPRESSION['FICHIER']!=None:
+# imp_fich = IMPRESSION['FICHIER']
+# imp_fichF = 1
+# else:
+# imp_fichF = 0
# Maillage
nrad = RAFF_MAILLAGE['NB_RADIAL']
@@ -141,8 +141,8 @@ def macr_cabri_mail_ops(self,EXEC_MAILLAGE,RAFF_MAILLAGE,VERI_MAIL,GEOM_BRID,
nomres = LIRE_MAILLAGE(VERI_MAIL=_F(APLAT = ver_apla,
VERIF = ver_veri ),)
- if (imp_fichF == 1):
- print imp_fich
+# if (imp_fichF == 1):
+# print imp_fich
if (imp_formF == 1):
print imp_form
if (imp_unitF == 1):
diff --git a/Aster/Cata/Macro/macr_fiab_impr_ops.py b/Aster/Cata/Macro/macr_fiab_impr_ops.py
index 3b338c77..08ac8d10 100644
--- a/Aster/Cata/Macro/macr_fiab_impr_ops.py
+++ b/Aster/Cata/Macro/macr_fiab_impr_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_fiab_impr_ops Macro DATE 07/10/2004 AUTEUR GNICOLAS G.NICOLAS
+#@ MODIF macr_fiab_impr_ops Macro DATE 24/01/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -17,8 +17,6 @@
# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
# ======================================================================
-
-
# RESPONSABLE GNICOLAS G.NICOLAS
#
def macr_fiab_impr_ops(self, INFO,
@@ -86,14 +84,16 @@ def macr_fiab_impr_ops(self, INFO,
# 5. Ecritures des gradients
#____________________________________________________________________
#
- for val in GRADIENTS :
+ if GRADIENTS is not None :
#
- IMPR_TABLE ( TABLE = val["TABLE"],
- SENSIBILITE = val["PARA_SENSI"],
- NOM_PARA = (val["NOM_PARA"]),
- UNITE = Unite_Fichier_ASTER_vers_FIABILITE,
- FORMAT_R = FORMAT_R,
- INFO = INFO )
+ for val in GRADIENTS :
+#
+ IMPR_TABLE ( TABLE = val["TABLE"],
+ SENSIBILITE = val["PARA_SENSI"],
+ NOM_PARA = (val["NOM_PARA"]),
+ UNITE = Unite_Fichier_ASTER_vers_FIABILITE,
+ FORMAT_R = FORMAT_R,
+ INFO = INFO )
#____________________________________________________________________
#
# 6. Libération du fichier d'échange
diff --git a/Aster/Cata/Macro/macr_lign_coupe_ops.py b/Aster/Cata/Macro/macr_lign_coupe_ops.py
index 0d57da06..107ec4a2 100644
--- a/Aster/Cata/Macro/macr_lign_coupe_ops.py
+++ b/Aster/Cata/Macro/macr_lign_coupe_ops.py
@@ -1,21 +1,21 @@
-#@ MODIF macr_lign_coupe_ops Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF macr_lign_coupe_ops Macro DATE 14/02/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
-# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
-# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
-# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
-# (AT YOUR OPTION) ANY LATER VERSION.
-#
-# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
-# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
-# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
-#
-# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
-# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
-# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
# ======================================================================
@@ -23,81 +23,104 @@
########################################################################
# script PYTHON de creation d un maillage de ligne de coupe
-def crea_mail_lig_coup(lignes):
+def crea_mail_lig_coup(dimension,lignes,groups):
import os,sys,copy
- try:
# construction du maillage au format Aster des segments de lignes de coupe
- nblig=len(lignes)
- dimension=len(lignes[0][0])
+ nblig=len(lignes)
+ nbngr=len(groups)
- resu='TITRE\n'
- titre='Maillage ligne de coupe'+'\n'
- resu=resu+'FINSF\n'
- resu=resu+'COOR_'+str(dimension)+'D\n'
+ resu='TITRE\n'
+ titre='Maillage ligne de coupe'+'\n'
+ resu=resu+'FINSF\n'
+ resu=resu+'COOR_'+str(dimension)+'D\n'
# creation des noeuds
- nbno=0
- for i in range(nblig):
- pt1 = lignes[i][0]
- pt2 = lignes[i][1]
- nbp_lig_coupe = lignes[i][2]
- for j in range(nbp_lig_coupe):
- if dimension==2:
- x=pt1[0]+j*(pt2[0]-pt1[0])/(nbp_lig_coupe-1)
- y=pt1[1]+j*(pt2[1]-pt1[1])/(nbp_lig_coupe-1)
- nbno=nbno+1
- noeud=' N'+str(nbno)+' '+str(x)+' '+str(y)+'\n'
- resu=resu+noeud
- elif dimension==3:
- x=pt1[0]+j*(pt2[0]-pt1[0])/(nbp_lig_coupe-1)
- y=pt1[1]+j*(pt2[1]-pt1[1])/(nbp_lig_coupe-1)
- z=pt1[2]+j*(pt2[2]-pt1[2])/(nbp_lig_coupe-1)
- nbno=nbno+1
- noeud=' N'+str(nbno)+' '+str(x)+' '+str(y)+' '+str(z)+'\n'
- resu=resu+noeud
- resu=resu+'FINSF\n'
+ nbno=0
+ for i in range(nblig):
+ pt1 = lignes[i][0]
+ pt2 = lignes[i][1]
+ nbp_lig_coupe = lignes[i][2]
+ for j in range(nbp_lig_coupe):
+ if dimension==2:
+ x=pt1[0]+j*(pt2[0]-pt1[0])/(nbp_lig_coupe-1)
+ y=pt1[1]+j*(pt2[1]-pt1[1])/(nbp_lig_coupe-1)
+ nbno=nbno+1
+ noeud=' N'+str(nbno)+' '+str(x)+' '+str(y)+'\n'
+ resu=resu+noeud
+ elif dimension==3:
+ x=pt1[0]+j*(pt2[0]-pt1[0])/(nbp_lig_coupe-1)
+ y=pt1[1]+j*(pt2[1]-pt1[1])/(nbp_lig_coupe-1)
+ z=pt1[2]+j*(pt2[2]-pt1[2])/(nbp_lig_coupe-1)
+ nbno=nbno+1
+ noeud=' N'+str(nbno)+' '+str(x)+' '+str(y)+' '+str(z)+'\n'
+ resu=resu+noeud
+ for i in range(nbngr):
+ for pt in groups[i][1:]:
+ if dimension==2:
+ nbno=nbno+1
+ noeud=' N'+str(nbno)+' '+str(pt[0])+' '+str(pt[1])+'\n'
+ resu=resu+noeud
+ elif dimension==3:
+ nbno=nbno+1
+ noeud=' N'+str(nbno)+' '+str(pt[0])+' '+str(pt[1])+' '+str(pt[2])+'\n'
+ resu=resu+noeud
+ resu=resu+'FINSF\n'
# creation des mailles
- nbma=0
- for i in range(nblig):
- nbp_lig_coupe = lignes[i][2]
- resu=resu+'SEG2\n'
- for j in range(nbp_lig_coupe-1):
- nbma=nbma+1
- maille=' M'+str(nbma)+' N'+str(nbma+i)+' N'+str(nbma+1+i)+'\n'
- resu=resu+maille
- resu=resu+'FINSF\n'
+ nbma=0
+ for i in range(nblig):
+ nbp_lig_coupe = lignes[i][2]
+ resu=resu+'SEG2\n'
+ for j in range(nbp_lig_coupe-1):
+ nbma=nbma+1
+ maille=' M'+str(nbma)+' N'+str(nbma+i)+' N'+str(nbma+1+i)+'\n'
+ resu=resu+maille
+ resu=resu+'FINSF\n'
+ for i in range(nbngr):
+ resu=resu+'SEG2\n'
+ for pt in groups[i][1:-1]:
+ nbma=nbma+1
+ maille=' M'+str(nbma)+' N'+str(nbma+nblig+i)+' N'+str(nbma+nblig+1+i)+'\n'
+ resu=resu+maille
+ resu=resu+'FINSF\n'
# creation des groupes de mailles (1 par ligne de coupe)
- nbma=0
- for i in range(nblig):
- resu=resu+'GROUP_MA\n'
- resu=resu+' LICOU'+str(i+1)
- nbp_lig_coupe = lignes[i][2]
- for j in range(nbp_lig_coupe-1):
- nbma=nbma+1
- resu=resu+' M'+str(nbma)+'\n'
- resu=resu+'\n'
- resu=resu+'FINSF\n'
- resu=resu+'FIN\n'
-
- return resu
-
- except :
- return 0
+ nbma=0
+ for i in range(nblig):
+ resu=resu+'GROUP_MA\n'
+ resu=resu+' LICOU'+str(i+1)
+ nbp_lig_coupe = lignes[i][2]
+ for j in range(nbp_lig_coupe-1):
+ nbma=nbma+1
+ resu=resu+' M'+str(nbma)+'\n'
+ resu=resu+'\n'
+ resu=resu+'FINSF\n'
+ for i in range(nbngr):
+ resu=resu+'GROUP_MA\n'
+ resu=resu+groups[i][0]
+ nbp_lig_coupe = len(groups[i])-1
+ for j in range(nbp_lig_coupe-1):
+ nbma=nbma+1
+ resu=resu+' M'+str(nbma)+'\n'
+ resu=resu+'\n'
+ resu=resu+'FINSF\n'
+ resu=resu+'FIN\n'
+
+ return resu
+
########################################################################
-def macr_lign_coupe_ops(self,RESULTAT,UNITE_MAILLAGE,LIGN_COUPE,MODELE,
- NOM_CHAM,**args):
+def macr_lign_coupe_ops(self,RESULTAT,UNITE_MAILLAGE,LIGN_COUPE,NOM_CHAM,MODELE,**args):
"""
Ecriture de la macro MACR_LIGN_COUPE
"""
- import os
+ import os,string,types
from Accas import _F
from Noyau.N_utils import AsType
+ import aster
ier=0
# On importe les definitions des commandes a utiliser dans la macro
@@ -106,20 +129,57 @@ def macr_lign_coupe_ops(self,RESULTAT,UNITE_MAILLAGE,LIGN_COUPE,MODELE,
AFFE_MODELE =self.get_cmd('AFFE_MODELE')
PROJ_CHAMP =self.get_cmd('PROJ_CHAMP')
POST_RELEVE_T =self.get_cmd('POST_RELEVE_T')
+ CREA_TABLE =self.get_cmd('CREA_TABLE')
# La macro compte pour 1 dans la numerotation des commandes
#self.icmd=1
self.set_icmd(1)
+
+ nomresu=RESULTAT.nom
+ l_modele=aster.getvectjev(nomresu.ljust(19)+'.MODL')
+ n_modele=string.strip(l_modele[0])
+ if n_modele=='' :
+ if MODELE==None:
+ ier=ier+1
+ self.cr.fatal(" nom du modele absent dans le concept resultat "+nomresu)
+ return ier
+ else : n_modele=MODELE.nom
+ l_mailla=aster.getvectjev(n_modele.ljust(8)+'.MODELE .NOMA')
+ n_mailla=string.strip(l_mailla[0])
+ dime=aster.getvectjev(n_mailla.ljust(8)+'.DIME')[5]
+ collgrno=aster.getcolljev(n_mailla.ljust(8)+'.GROUPENO')
lignes=[]
+ groups=[]
+ minidim=dime
for m in LIGN_COUPE :
- lignes.append((m['COOR_ORIG'],m['COOR_EXTR'],m['NB_POINTS']))
+ if m['NB_POINTS'] !=None :
+ lignes.append((m['COOR_ORIG'],m['COOR_EXTR'],m['NB_POINTS']))
+ minidim=min(minidim,len(m['COOR_ORIG']),len(m['COOR_EXTR']))
+ elif m['GROUP_NO']!=None :
+ ngrno=m['GROUP_NO'].ljust(8).upper()
+ if ngrno not in collgrno.keys() :
+ ier=ier+1
+ self.cr.fatal(" le group_no "+ngrno+" n est pas dans le maillage "+n_mailla)
+ return ier
+ grpn=collgrno[ngrno]
+ l_coor_group=[ngrno,]
+ for node in grpn:
+ l_coor_group.append(aster.getvectjev(n_mailla.ljust(8)+'.COORDO .VALE',3*(node-1),3))
+ groups.append(l_coor_group)
+
+ if minidim!=dime:
+ ier=ier+1
+ self.cr.fatal(" dimensions de maillage et de coordonnees incoherentes")
+ return ier
+
# Création du maillage des NB_POINTS segments entre COOR_ORIG et COOR_EXTR
+ # ainsi que des segments reliant les noeuds issus des group_no demandés
# par appel au script python crea_mail_lig_coup
# le maillage est ensuite recopié dans l unité logique UNITE_MAILLAGE
- resu_mail=crea_mail_lig_coup(lignes)
+ resu_mail=crea_mail_lig_coup(dime,lignes,groups)
cur_dir=os.getcwd()
nomFichierSortie =cur_dir+'/fort.'+str(UNITE_MAILLAGE)
fproc=open(nomFichierSortie,'w')
@@ -134,8 +194,11 @@ def macr_lign_coupe_ops(self,RESULTAT,UNITE_MAILLAGE,LIGN_COUPE,MODELE,
iocc=1
motscles['CREA_GROUP_NO']=[]
for m in LIGN_COUPE :
- motscles['CREA_GROUP_NO'].append(_F(GROUP_MA='LICOU'+str(iocc),) )
- iocc=iocc+1
+ if m['NB_POINTS'] !=None :
+ motscles['CREA_GROUP_NO'].append(_F(GROUP_MA='LICOU'+str(iocc),) )
+ iocc=iocc+1
+ elif m['GROUP_NO']!=None :
+ motscles['CREA_GROUP_NO'].append(_F(GROUP_MA=m['GROUP_NO'].ljust(8).upper(),) )
__macou=DEFI_GROUP( reuse =__macou , MAILLAGE=__macou , **motscles );
if AsType(RESULTAT).__name__ in ('evol_elas','evol_noli') :
@@ -151,23 +214,52 @@ def macr_lign_coupe_ops(self,RESULTAT,UNITE_MAILLAGE,LIGN_COUPE,MODELE,
__recou=PROJ_CHAMP(METHODE='ELEM',
RESULTAT=RESULTAT,
- MODELE_1=MODELE,
+ MODELE_1=self.jdc.current_context[n_modele],
MODELE_2=__mocou,
+ TYPE_CHAM='NOEU',
NOM_CHAM=NOM_CHAM,);
- # Production d'une table par ligne de coupe
- # Toutes les tables sont des concepts sortant de la macro définies
- # dans chaque occurence du mcfact lign_coupe
+ # Production d'une table pour toutes les lignes de coupe
- iocc=1
+ ioc2=0
+ mcACTION=[]
for m in LIGN_COUPE :
- self.DeclareOut('tt',m['TABLE'])
- tt=POST_RELEVE_T(ACTION=_F(INTITULE = 'lig.coupe'+str(iocc),
- RESULTAT = __recou,
- GROUP_NO = 'LICOU'+str(iocc),
- NOM_CHAM = NOM_CHAM,
- TOUT_CMP = 'OUI',
- OPERATION = 'EXTRACTION', ),);
- iocc=iocc+1
+ if m['NB_POINTS'] !=None :
+ ioc2=ioc2+1
+ groupe='LICOU'+str(ioc2)
+ if m['INTITULE'] !=None : intitl=m['INTITULE']
+ else : intitl='l.coupe'+str(ioc2)
+ elif m['GROUP_NO']!=None :
+ groupe=m['GROUP_NO'].ljust(8).upper()
+ if m['INTITULE'] !=None : intitl=m['INTITULE']
+ else : intitl=groupe
+ mcACTION.append( _F(INTITULE = intitl,
+ RESULTAT = __recou,
+ GROUP_NO = groupe,
+ NOM_CHAM = NOM_CHAM,
+ TOUT_CMP = 'OUI',
+ OPERATION = 'EXTRACTION', ) )
+
+ __tabitm=POST_RELEVE_T(ACTION=mcACTION,);
+
+ # on repasse par les tables python pour supprimer les paramètres inutiles
+ # NOEUD (car il est propre au maillage de la ligne) et RESU
+
+ self.DeclareOut('nomres',self.sd)
+ dictab=__tabitm.EXTR_TABLE()
+ listpara=dictab.para
+ listpara.remove('NOEUD')
+ listpara.remove('RESU')
+
+ coltab=[]
+ for key in listpara :
+ val=dictab[key].values()[key]
+ if type(val[0])==types.IntType :
+ coltab.append(_F(PARA=key,LISTE_I=val))
+ elif type(val[0])==types.FloatType :
+ coltab.append(_F(PARA=key,LISTE_R=val))
+ elif type(val[0])==types.StringType :
+ coltab.append(_F(PARA=key,LISTE_K=val,TYPE_K='K16'))
+ nomres=CREA_TABLE(LISTE=coltab)
return ier
diff --git a/Aster/Cata/Macro/macr_recal_ops.py b/Aster/Cata/Macro/macr_recal_ops.py
index 308846a5..17597e90 100644
--- a/Aster/Cata/Macro/macr_recal_ops.py
+++ b/Aster/Cata/Macro/macr_recal_ops.py
@@ -1,4 +1,4 @@
-#@ MODIF macr_recal_ops Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF macr_recal_ops Macro DATE 14/03/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -45,7 +45,7 @@ def macr_recal_ops(self,UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, RESU_CALC,
import Macro
from Cata import cata
from Cata.cata import DEFI_LIST_REEL
- from Macro.recal import gestion,transforme_list_Num,EXTRACT,calcul_F,graphique
+ from Macro.recal import gestion,transforme_list_Num,calcul_F,graphique
from Macro import reca_message
from Macro import reca_algo
from Macro import reca_interp
@@ -82,7 +82,6 @@ def macr_recal_ops(self,UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, RESU_CALC,
if v.__class__.__name__ in ('OPER','MACRO'):
self.current_context[k]= v
self.current_context['_F']=cata.__dict__['_F']
- self.g_context['EXTRACT']=EXTRACT
#_____________________________________________
#
diff --git a/Aster/Cata/Macro/macro_cara_poutre_ops.py b/Aster/Cata/Macro/macro_cara_poutre_ops.py
deleted file mode 100644
index a98d3d6f..00000000
--- a/Aster/Cata/Macro/macro_cara_poutre_ops.py
+++ /dev/null
@@ -1,684 +0,0 @@
-# -*- coding: utf-8 -*-
-#@ MODIF macro_cara_poutre_ops Macro DATE 25/06/2002 AUTEUR JMBHH01 J.M.PROIX
-# CONFIGURATION MANAGEMENT OF EDF VERSION
-# ======================================================================
-# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
-# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
-# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
-# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
-# (AT YOUR OPTION) ANY LATER VERSION.
-#
-# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
-# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
-# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
-#
-# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
-# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
-# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
-# ======================================================================
-# RESPONSABLE JMBHH01 J.M.PROIX
-def macro_cara_poutre_ops(self,UNITE_MAILLAGE,SYME_X,SYME_Y,GROUP_MA_BORD,
- GROUP_MA,ORIG_INER,NOEUD,GROUP_MA_INTE,
- LONGUEUR,MATERIAU,LIAISON,
- **args):
- """
- Ecriture de la macro MACRO_CARA_POUTRE
- """
- import types
- from Accas import _F
- ier=0
- # On importe les definitions des commandes a utiliser dans la macro
- # Le nom de la variable doit etre obligatoirement le nom de la commande
- LIRE_MAILLAGE =self.get_cmd('LIRE_MAILLAGE')
- DEFI_GROUP =self.get_cmd('DEFI_GROUP')
- CREA_MAILLAGE =self.get_cmd('CREA_MAILLAGE')
- AFFE_MODELE =self.get_cmd('AFFE_MODELE')
- DEFI_MATERIAU =self.get_cmd('DEFI_MATERIAU')
- AFFE_MATERIAU =self.get_cmd('AFFE_MATERIAU')
- DEFI_FONCTION =self.get_cmd('DEFI_FONCTION')
- DEFI_CONSTANTE =self.get_cmd('DEFI_CONSTANTE')
- AFFE_CHAR_THER =self.get_cmd('AFFE_CHAR_THER')
- AFFE_CHAR_THER_F=self.get_cmd('AFFE_CHAR_THER_F')
- THER_LINEAIRE =self.get_cmd('THER_LINEAIRE')
- CALC_VECT_ELEM =self.get_cmd('CALC_VECT_ELEM')
- CALC_MATR_ELEM =self.get_cmd('CALC_MATR_ELEM')
- NUME_DDL =self.get_cmd('NUME_DDL')
- ASSE_VECTEUR =self.get_cmd('ASSE_VECTEUR')
- POST_ELEM =self.get_cmd('POST_ELEM')
- # La macro compte pour 1 dans la numerotation des commandes
- self.icmd=1
-
- # Le concept sortant (de type tabl_cara_geom) est nommé 'nomres' dans
- # le contexte de la macro
-
- self.DeclareOut('nomres',self.sd)
-
- if GROUP_MA_BORD and GROUP_MA:
- if not LIAISON:
- ier=ier+1
- self.cr.fatal("Avec GROUP_MA, il faut obligatoirement preciser LIAISON, LONGUEUR ET MATERIAU")
- return ier
-
- __nomlma=LIRE_MAILLAGE(UNITE=UNITE_MAILLAGE,)
-
- __nomamo=AFFE_MODELE(MAILLAGE=__nomlma,
- AFFE=_F(TOUT='OUI',
- PHENOMENE='MECANIQUE',
- MODELISATION='D_PLAN',), )
-
- __nomdma=DEFI_MATERIAU(ELAS=_F(E=1.0,NU=0.,RHO=1.0),)
-
-
- __nomama=AFFE_MATERIAU(MAILLAGE=__nomlma,
- AFFE=_F(TOUT='OUI',
- MATER=__nomdma,), )
-
-# --- CALCUL DES CARACTERISTIQUES GEOMETRIQUES DE LA SECTION :
-# ------------------------------------------------------
-
- motsimps={}
- if GROUP_MA : motsimps['GROUP_MA'] = GROUP_MA
- if SYME_X : motsimps['SYME_X'] = SYME_X
- if SYME_Y : motsimps['SYME_Y'] = SYME_Y
- motsimps['ORIG_INER'] = ORIG_INER
- mfact=_F(TOUT='OUI',**motsimps)
- nomres=POST_ELEM(MODELE=__nomamo,
- CHAM_MATER=__nomama,
- CARA_GEOM=mfact )
-
-# nb : si GROUP_MA n existe pas : le mot clé est ignoré
-
-#
-# ==================================================================
-# --- = CALCUL DE LA CONSTANTE DE TORSION SUR TOUT LE MAILLAGE =
-# --- = OU DU CENTRE DE TORSION/CISAILLEMENT =
-# --- = DES COEFFICIENTS DE CISAILLEMENT =
-# --- = ET DE L INERTIE DE GAUCHISSEMENT =
-# --- = ON CREE UN MODELE PLAN 2D THERMIQUE REPRESENTANT LA SECTION =
-# --- = DE LA POUTRE CAR ON A A RESOUDRE DES E.D.P. AVEC DES LAPLACIENS=
-# ==================================================================
-
- if GROUP_MA_BORD and not GROUP_MA:
-
-# --- TRANSFORMATION DES GROUP_MA EN GROUP_NO SUR-LESQUELS
-# --- ON POURRA APPLIQUER DES CONDITIONS DE TEMPERATURE IMPOSEE :
-# ---------------------------------------------------------
- motscles={}
- if type(GROUP_MA_BORD)==types.StringType:
- motscles['CREA_GROUP_NO']=_F(GROUP_MA=GROUP_MA_BORD,)
- else:
- motscles['CREA_GROUP_NO']=[]
- for grma in GROUP_MA_BORD:
- motscles['CREA_GROUP_NO'].append(_F(GROUP_MA=grma,))
- __nomlma=DEFI_GROUP(reuse=__nomlma,
- MAILLAGE=__nomlma,
- **motscles)
-
-
-# --- CREATION D UN MAILLAGE IDENTIQUE AU PREMIER A CECI PRES
-# --- QUE LES COORDONNEES SONT EXPRIMEES DANS LE REPERE PRINCIPAL
-# --- D INERTIE DONT L ORIGINE EST LE CENTRE DE GRAVITE DE LA SECTION :
-# ---------------------------------------------------------------
-
- __nomapi=CREA_MAILLAGE(MAILLAGE=__nomlma,
- REPERE=_F(TABLE=nomres,
- NOM_ORIG='CDG', ), )
-
-# --- AFFECTATION DU PHENOMENE 'THERMIQUE' AU MODELE EN VUE DE
-# --- LA CONSTRUCTION D UN OPERATEUR LAPLACIEN SUR CE MODELE :
-# ------------------------------------------------------
-
- __nomoth=AFFE_MODELE(MAILLAGE=__nomapi,
- AFFE=_F(TOUT='OUI',
- PHENOMENE='THERMIQUE',
- MODELISATION='PLAN',), )
-
-# --- POUR LA CONSTRUCTION DU LAPLACIEN, ON DEFINIT UN
-# --- PSEUDO-MATERIAU DONT LES CARACTERISTIQUES THERMIQUES SONT :
-# --- LAMBDA = 1, RHO*CP = 0 :
-# ----------------------
-
- __nomath=DEFI_MATERIAU(THER=_F(LAMBDA=1.0,RHO_CP=0.,),)
-
-# --- DEFINITION D UN CHAM_MATER A PARTIR DU MATERIAU PRECEDENT :
-# ---------------------------------------------------------
-
- __chmath=AFFE_MATERIAU(MAILLAGE=__nomapi,
- AFFE=_F(TOUT='OUI',
- MATER=__nomath,), )
-
-#
-# ------------------------------------------------------------
-# --- - CALCUL DE LA CONSTANTE DE TORSION PAR RESOLUTION -
-# --- - D UN LAPLACIEN AVEC UN TERME SOURCE EGAL A -2 -
-# --- - L INCONNUE ETANT NULLE SUR LE CONTOUR DE LA SECTION : -
-# --- - LAPLACIEN(PHI) = -2 DANS LA SECTION -
-# --- - PHI = 0 SUR LE CONTOUR : -
-# ------------------------------------------------------------
-#
-# --- ON IMPOSE LA VALEUR 0 A L INCONNUE SCALAIRE SUR LE CONTOUR
-# --- DE LA SECTION
-# --- ET ON A UN TERME SOURCE EGAL A -2 DANS TOUTE LA SECTION :
-# -------------------------------------------------------
-
- motscles={}
- if GROUP_MA_INTE:
- motscles['LIAISON_UNIF']=_F(GROUP_MA=GROUP_MA_INTE,DDL='TEMP'),
- __chart1=AFFE_CHAR_THER(MODELE=__nomoth,
- TEMP_IMPO =_F(GROUP_NO=GROUP_MA_BORD,
- TEMP=0. ),
- SOURCE =_F(TOUT='OUI',
- SOUR=2.0),
- **motscles )
-
-# --- POUR CHAQUE TROU DE LA SECTION :
-# --- .ON A IMPOSE QUE PHI EST CONSTANT SUR LE CONTOUR INTERIEUR
-# --- EN FAISANT LE LIAISON_UNIF DANS LE AFFE_CHAR_THER PRECEDENT
-# --- .ON IMPOSE EN PLUS D(PHI)/DN = 2*AIRE(TROU)/L(TROU)
-# --- OU D/DN DESIGNE LA DERIVEE PAR RAPPORT A LA
-# --- NORMALE ET L DESIGNE LA LONGUEUR DU BORD DU TROU :
-# -------------------------------------------------------
-
- if GROUP_MA_INTE:
- __tbaire=POST_ELEM(MODELE=__nomoth,
- AIRE_INTERNE=_F(GROUP_MA_BORD=GROUP_MA_INTE,), )
-
- motscles={}
- motscles['FLUX_REP']=[]
- if type(GROUP_MA_INTE)==types.StringType:
- motscles['FLUX_REP']=_F(GROUP_MA=GROUP_MA_INTE,CARA_TORSION=__tbaire)
- else:
- motscles['FLUX_REP']=[]
- for grma in GROUP_MA_INTE:
- motscles['FLUX_REP'].append(_F(GROUP_MA=grma,CARA_TORSION=__tbaire),)
- __chart2=AFFE_CHAR_THER(MODELE=__nomoth,**motscles)
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -2
-# --- AVEC PHI = 0 SUR LE CONTOUR :
-# ----------------------------------------
-
- motscles={}
- motscles['EXCIT']=[_F(CHARGE=__chart1,),]
- if GROUP_MA_INTE:
- motscles['EXCIT'].append(_F(CHARGE=__chart2,))
- __tempe1=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- SOLVEUR=_F(STOP_SINGULIER='NON',),
- **motscles )
-
-#
-# ----------------------------------------------
-# --- - CALCUL DU CENTRE DE TORSION/CISAILLEMENT -
-# --- - ET DES COEFFICIENTS DE CISAILLEMENT : -
-# ----------------------------------------------
-#
-# --- POUR LE CALCUL DES CONSTANTES DE CISAILLEMENT, ON VA DEFINIR
-# --- UN PREMIER TERME SOURCE, SECOND MEMBRE DE L EQUATION DE LAPLACE
-# --- PAR UNE FONCTION EGALE A Y :
-# --------------------------
-
- __fnsec1=DEFI_FONCTION(NOM_PARA='X',
- VALE=(0.,0.,10.,10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE',
- )
-
- __fnsec0=DEFI_CONSTANTE(VALE=0.,)
-
-# --- LE TERME SOURCE CONSTITUANT LE SECOND MEMBRE DE L EQUATION
-# --- DE LAPLACE EST PRIS EGAL A Y DANS TOUTE LA SECTION :
-# --------------------------------------------------
-
-
- motscles={}
- if NOEUD:
- motscles['TEMP_IMPO']=(_F(NOEUD=NOEUD,TEMP=__fnsec0))
- __chart2=AFFE_CHAR_THER_F(MODELE=__nomoth,
- SOURCE=_F(TOUT='OUI',
- SOUR=__fnsec1,),
- **motscles )
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -Y
-# --- AVEC D(PHI)/D(N) = 0 SUR LE CONTOUR :
-# ------------------------------------------------
-
- __tempe2=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- EXCIT=_F(CHARGE=__chart2,),
- SOLVEUR=_F(STOP_SINGULIER='NON',),
- )
-
-# --- POUR LE CALCUL DES CONSTANTES DE CISAILLEMENT, ON VA DEFINIR
-# --- UN PREMIER TERME SOURCE, SECOND MEMBRE DE L EQUATION DE LAPLACE
-# --- PAR UNE FONCTION EGALE A Z :
-# --------------------------
-
- __fnsec2=DEFI_FONCTION(NOM_PARA='Y',
- VALE=(0.,0.,10.,10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE',
- )
-
-# --- LE TERME SOURCE CONSTITUANT LE SECOND MEMBRE DE L EQUATION
-# --- DE LAPLACE EST PRIS EGAL A Z DANS TOUTE LA SECTION :
-# --------------------------------------------------
-
- motscles={}
- if NOEUD:
- motscles['TEMP_IMPO']=_F(NOEUD=NOEUD,TEMP=__fnsec0)
- __chart3=AFFE_CHAR_THER_F(MODELE=__nomoth,
- SOURCE=_F(TOUT='OUI',
- SOUR=__fnsec2,),
- **motscles)
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -Z
-# --- AVEC D(PHI)/D(N) = 0 SUR LE CONTOUR :
-# ------------------------------------------------
-
- __tempe3=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- EXCIT=_F(CHARGE=__chart3,),
- SOLVEUR=_F(STOP_SINGULIER='NON',),
- )
-
-# --- CALCUL DE LA CONSTANTE DE TORSION :
-# ---------------------------------
-
- motscles={}
- if GROUP_MA_INTE:
- motscles['CARA_POUTRE']=_F(CARA_GEOM=nomres,
- LAPL_PHI=__tempe1,
- TOUT='OUI',
- OPTION='CARA_TORSION',
- GROUP_MA_INTE=GROUP_MA_INTE,)
- else:
- motscles['CARA_POUTRE']=_F(CARA_GEOM=nomres,
- LAPL_PHI=__tempe1,
- TOUT='OUI',
- OPTION='CARA_TORSION', )
- nomres=POST_ELEM(reuse=nomres,
- MODELE=__nomoth,
- CHAM_MATER=__chmath,
- **motscles )
-
-# --- CALCUL DES COEFFICIENTS DE CISAILLEMENT ET DES COORDONNEES DU
-# --- CENTRE DE CISAILLEMENT/TORSION :
-# ------------------------------
-
- nomres=POST_ELEM(reuse=nomres,
- MODELE=__nomoth,
- CHAM_MATER=__chmath,
- CARA_POUTRE=_F(CARA_GEOM=nomres,
- LAPL_PHI_Y=__tempe2,
- LAPL_PHI_Z=__tempe3,
- TOUT='OUI',
- OPTION='CARA_CISAILLEMENT',), )
-
-#
-# ------------------------------------------------------------
-# --- - CALCUL DE L INERTIE DE GAUCHISSEMENT PAR RESOLUTION DE -
-# --- - LAPLACIEN(OMEGA) = 0 DANS LA SECTION -
-# --- - AVEC D(OMEGA)/D(N) = Z*NY-Y*NZ SUR LE -
-# --- - CONTOUR DE LA SECTION -
-# --- - NY ET NZ SONT LES COMPOSANTES DU VECTEUR N NORMAL -
-# --- - A CE CONTOUR -
-# --- - ET SOMME_S(OMEGA.DS) = 0 -
-# --- - OMEGA EST LA FONCTION DE GAUCHISSEMENT -
-# --- - L INERTIE DE GAUCHISSEMENT EST SOMME_S(OMEGA**2.DS) -
-# ------------------------------------------------------------
-#
-# --- CREATION D UN MAILLAGE DONT LES COORDONNEES SONT EXPRIMEES
-# --- DANS LE REPERE PRINCIPAL D INERTIE MAIS AVEC COMME ORIGINE
-# --- LE CENTRE DE TORSION DE LA SECTION, ON VA DONC UTILISER
-# --- LE MAILLAGE DE NOM NOMAPI DONT LES COORDONNEES SONT
-# --- EXPRIMEES DANS LE REPERE PRINCIPAL D'INERTIE, L'ORIGINE
-# --- ETANT LE CENTRE DE GRAVITE DE LA SECTION (QUI EST DONC
-# --- A CHANGER) :
-# ----------
-
- __nomapt=CREA_MAILLAGE(MAILLAGE=__nomapi,
- REPERE=_F(TABLE=nomres,
- NOM_ORIG='TORSION',) )
-
-# --- AFFECTATION DU PHENOMENE 'THERMIQUE' AU MODELE EN VUE DE
-# --- LA CONSTRUCTION D UN OPERATEUR LAPLACIEN SUR CE MODELE :
-# ------------------------------------------------------
-
- __nomot2=AFFE_MODELE(MAILLAGE=__nomapt,
- AFFE=_F(TOUT='OUI',
- PHENOMENE='THERMIQUE',
- MODELISATION='PLAN', ) )
-
-# --- DEFINITION D UN CHAM_MATER A PARTIR DU MATERIAU PRECEDENT :
-# ---------------------------------------------------------
-
- __chmat2=AFFE_MATERIAU(MAILLAGE=__nomapt,
- AFFE=_F(TOUT='OUI',
- MATER=__nomath, ), )
-
-# --- POUR LE CALCUL DE L INERTIE DE GAUCHISSEMENT, ON VA DEFINIR
-# --- LA COMPOSANTE SELON Y DU FLUX A IMPOSER SUR LE CONTOUR
-# --- PAR UNE FONCTION EGALE A -X :
-# ---------------------------
-
- __fnsec3=DEFI_FONCTION(NOM_PARA='X',
- VALE=(0.,0.,10.,-10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE',
- )
-
-# --- POUR LE CALCUL DE L INERTIE DE GAUCHISSEMENT, ON VA DEFINIR
-# --- LA COMPOSANTE SELON X DU FLUX A IMPOSER SUR LE CONTOUR
-# --- PAR UNE FONCTION EGALE A Y :
-# --------------------------
-
- __fnsec4=DEFI_FONCTION(NOM_PARA='Y',
- VALE=(0.,0.,10.,10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE',
- )
-
-# --- DANS LE BUT D IMPOSER LA RELATION LINEAIRE ENTRE DDLS
-# --- SOMME_SECTION(OMEGA.DS) = 0 ( CETTE CONDITION
-# --- VENANT DE L EQUATION D EQUILIBRE SELON L AXE DE LA POUTRE
-# --- N = 0, N ETANT L EFFORT NORMAL)
-# --- ON CALCULE LE VECTEUR DE CHARGEMENT DU A UN TERME SOURCE EGAL
-# --- A 1., LES TERMES DE CE VECTEUR SONT EGAUX A
-# --- SOMME_SECTION(NI.DS) ET SONT DONC LES COEFFICIENTS DE
-# --- LA RELATION LINEAIRE A IMPOSER.
-# --- ON DEFINIT DONC UN CHARGEMENT DU A UN TERME SOURCE EGAL A 1 :
-# -----------------------------------------------------------
-
- __chart4=AFFE_CHAR_THER(MODELE=__nomot2,
- SOURCE=_F(TOUT='OUI',
- SOUR=1.0), )
-
-# --- ON CALCULE LE VECT_ELEM DU AU CHARGEMENT PRECEDENT
-# --- IL S AGIT DES VECTEURS ELEMENTAIRES DONT LE TERME
-# --- AU NOEUD COURANT I EST EGAL A SOMME_SECTION(NI.DS) :
-# --------------------------------------------------
-
- __vecel=CALC_VECT_ELEM(CHARGE=__chart4,
- OPTION='CHAR_THER'
- )
-
-# --- ON CALCULE LE MATR_ELEM DES MATRICES ELEMENTAIRES
-# --- DE CONDUCTIVITE UNIQUEMENT POUR GENERER LE NUME_DDL
-# --- SUR-LEQUEL S APPUIERA LE CHAMNO UTILISE POUR ECRIRE LA
-# --- RELATION LINEAIRE ENTRE DDLS :
-# ----------------------------
-
- __matel=CALC_MATR_ELEM(MODELE=__nomot2,
- CHAM_MATER=__chmat2,
- CHARGE=__chart4,
- OPTION='RIGI_THER',)
-
-# --- ON DEFINIT LE NUME_DDL ASSOCIE AU MATR_ELEM DEFINI
-# --- PRECEDEMMENT POUR CONSTRUIRE LE CHAMNO UTILISE POUR ECRIRE LA
-# --- RELATION LINEAIRE ENTRE DDLS :
-# ----------------------------
-
- __numddl=NUME_DDL(MATR_RIGI=__matel,
- METHODE='LDLT', )
-
-# --- ON CONSTRUIT LE CHAMNO QUI VA ETRE UTILISE POUR ECRIRE LA
-# --- RELATION LINEAIRE ENTRE DDLS :
-# ----------------------------
-
- __chamno=ASSE_VECTEUR(VECT_ELEM=__vecel,
- NUME_DDL=__numddl, )
-
-# --- ON IMPOSE LA RELATION LINEAIRE ENTRE DDLS
-# --- SOMME_SECTION(OMEGA.DS) = 0 ( CETTE CONDITION
-# --- VENANT DE L EQUATION D EQUILIBRE SELON L AXE DE LA POUTRE
-# --- N = 0, N ETANT L EFFORT NORMAL)
-# --- POUR IMPOSER CETTE RELATION ON PASSE PAR LIAISON_CHAMNO,
-# --- LES TERMES DU CHAMNO (I.E. SOMME_SECTION(NI.DS))
-# --- SONT LES COEFFICIENTS DE LA RELATION LINEAIRE :
-# ---------------------------------------------
-
- __chart5=AFFE_CHAR_THER(MODELE=__nomot2,
- LIAISON_CHAMNO=_F(CHAM_NO=__chamno,
- COEF_IMPO=0.), )
-
-# --- LE CHARGEMENT EST UN FLUX REPARTI NORMAL AU CONTOUR
-# --- DONT LES COMPOSANTES SONT +Z (I.E. +Y) ET -Y (I.E. -X)
-# --- SELON LA DIRECTION NORMALE AU CONTOUR :
-# -------------------------------------
-
- __chart6=AFFE_CHAR_THER_F(MODELE=__nomot2,
- FLUX_REP=_F(GROUP_MA=GROUP_MA_BORD,
- FLUX_X =__fnsec4,
- FLUX_Y =__fnsec3,), )
-
-# --- RESOLUTION DE LAPLACIEN(OMEGA) = 0
-# --- AVEC D(OMEGA)/D(N) = Z*NY-Y*NZ SUR LE CONTOUR DE LA SECTION
-# --- ET SOMME_SECTION(OMEGA.DS) = 0 ( CETTE CONDITION
-# --- VENANT DE L EQUATION D EQUILIBRE SELON L AXE DE LA POUTRE
-# --- N = 0, N ETANT L EFFORT NORMAL) :
-# -------------------------------
-
- __tempe4=THER_LINEAIRE(MODELE=__nomot2,
- CHAM_MATER=__chmat2,
- EXCIT=(_F(CHARGE=__chart5,),
- _F(CHARGE=__chart6,),),
- SOLVEUR=_F(METHODE='LDLT',
- RENUM='SANS',
- STOP_SINGULIER='NON',), )
-
-# --- CALCUL DE L INERTIE DE GAUCHISSEMENT :
-# -------------------------------------
-
- nomres=POST_ELEM(reuse=nomres,
- MODELE=__nomot2,
- CHAM_MATER=__chmat2,
- CARA_POUTRE=_F(CARA_GEOM=nomres,
- LAPL_PHI=__tempe4,
- TOUT='OUI',
- OPTION='CARA_GAUCHI'), )
-
-#
-# ==================================================================
-# --- = CALCUL DE LA CONSTANTE DE TORSION SUR CHAQUE GROUPE =
-# --- = ET DU CENTRE DE TORSION/CISAILLEMENT =
-# --- = DES COEFFICIENTS DE CISAILLEMENT =
-# ==================================================================
-#
-
-
- if GROUP_MA_BORD and GROUP_MA:
-
- if type(GROUP_MA_BORD)==types.StringType :
- l_group_ma_bord=[GROUP_MA_BORD,]
- else:
- l_group_ma_bord= GROUP_MA_BORD
- if type(GROUP_MA)==types.StringType :
- l_group_ma=[GROUP_MA,]
- else:
- l_group_ma= GROUP_MA
-
- if NOEUD:
- if type(NOEUD)==types.StringType :
- l_noeud=[NOEUD,]
- else:
- l_noeud= NOEUD
-
- if len(l_group_ma)!=len(l_group_ma_bord):
- ier=ier+1
- self.cr.fatal("GROUP_MA et GROUP_MA_BORD incoherents")
- return ier
- if NOEUD and (len(l_group_ma)!=len(l_noeud)):
- ier=ier+1
- self.cr.fatal("GROUP_MA et NOEUD incoherents")
- return ier
-
- for i in range(0,len(l_group_ma_bord)):
-
-# --- TRANSFORMATION DES GROUP_MA EN GROUP_NO SUR-LESQUELS
-# --- ON POURRA APPLIQUER DES CONDITIONS DE TEMPERATURE IMPOSEE :
-# ---------------------------------------------------------
-
- __nomlma=DEFI_GROUP(reuse=__nomlma,
- MAILLAGE=__nomlma,
- CREA_GROUP_NO=_F(GROUP_MA=l_group_ma_bord[i],) )
-
-
-# --- CREATION D UN MAILLAGE IDENTIQUE AU PREMIER A CECI PRES
-# --- QUE LES COORDONNEES SONT EXPRIMEES DANS LE REPERE PRINCIPAL
-# --- D INERTIE DONT L ORIGINE EST LE CENTRE DE GRAVITE DE LA SECTION :
-# ---------------------------------------------------------------
-
- __nomapi=CREA_MAILLAGE(MAILLAGE=__nomlma,
- REPERE=_F(TABLE=nomres,
- NOM_ORIG='CDG',
- GROUP_MA=l_group_ma[i], ), )
-
-# --- AFFECTATION DU PHENOMENE 'THERMIQUE' AU MODELE EN VUE DE
-# --- LA CONSTRUCTION D UN OPERATEUR LAPLACIEN SUR CE MODELE :
-# ------------------------------------------------------
-
- __nomoth=AFFE_MODELE(MAILLAGE=__nomapi,
- AFFE=_F(GROUP_MA=l_group_ma[i],
- PHENOMENE='THERMIQUE',
- MODELISATION='PLAN', ) )
-
-# --- POUR LA CONSTRUCTION DU LAPLACIEN, ON DEFINIT UN
-# --- PSEUDO-MATERIAU DONT LES CARACTERISTIQUES THERMIQUES SONT :
-# --- LAMBDA = 1, RHO*CP = 0 :
-# ----------------------
-
- __nomath=DEFI_MATERIAU(THER=_F(LAMBDA=1.0,
- RHO_CP=0.0, ), )
-
-# --- DEFINITION D UN CHAM_MATER A PARTIR DU MATERIAU PRECEDENT :
-# ---------------------------------------------------------
-
- __chmath=AFFE_MATERIAU(MAILLAGE=__nomapi,
- AFFE=_F(TOUT='OUI',
- MATER=__nomath ), )
-
-#
-# ------------------------------------------------------------
-# --- - CALCUL DE LA CONSTANTE DE TORSION PAR RESOLUTION -
-# --- - D UN LAPLACIEN AVEC UN TERME SOURCE EGAL A -2 -
-# --- - L INCONNUE ETANT NULLE SUR LE CONTOUR DE LA SECTION : -
-# --- - LAPLACIEN(PHI) = -2 DANS LA SECTION -
-# --- - PHI = 0 SUR LE CONTOUR : -
-# ------------------------------------------------------------
-#
-# --- ON IMPOSE LA VALEUR 0 A L INCONNUE SCALAIRE SUR LE CONTOUR
-# --- DE LA SECTION
-# --- ET ON A UN TERME SOURCE EGAL A -2 DANS TOUTE LA SECTION :
-# -------------------------------------------------------
-
- __chart1=AFFE_CHAR_THER(MODELE=__nomoth,
- TEMP_IMPO=_F(GROUP_NO=l_group_ma_bord[i],
- TEMP=0.0 ),
- SOURCE=_F(TOUT='OUI',
- SOUR=2.0 ) )
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -2
-# --- AVEC PHI = 0 SUR LE CONTOUR :
-# ----------------------------------------
-
- __tempe1=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- EXCIT=_F(CHARGE=__chart1, ),
- SOLVEUR=_F(STOP_SINGULIER='NON',) )
-
-#
-# ----------------------------------------------
-# --- - CALCUL DU CENTRE DE TORSION/CISAILLEMENT -
-# --- - ET DES COEFFICIENTS DE CISAILLEMENT : -
-# ----------------------------------------------
-#
-# --- POUR LE CALCUL DES CONSTANTES DE CISAILLEMENT, ON VA DEFINIR
-# --- UN PREMIER TERME SOURCE, SECOND MEMBRE DE L EQUATION DE LAPLACE
-# --- PAR UNE FONCTION EGALE A Y :
-# --------------------------
-
- __fnsec1=DEFI_FONCTION(NOM_PARA='X',
- VALE=(0.,0.,10.,10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE', )
-
- __fnsec0=DEFI_CONSTANTE(VALE=0.,)
-
-# --- LE TERME SOURCE CONSTITUANT LE SECOND MEMBRE DE L EQUATION
-# --- DE LAPLACE EST PRIS EGAL A Y DANS TOUTE LA SECTION :
-# --------------------------------------------------
-
- __chart2=AFFE_CHAR_THER_F(MODELE=__nomoth,
- TEMP_IMPO=_F(NOEUD=l_noeud[i],
- TEMP=__fnsec0),
- SOURCE=_F(TOUT='OUI',
- SOUR=__fnsec1) )
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -Y
-# --- AVEC D(PHI)/D(N) = 0 SUR LE CONTOUR :
-# ------------------------------------------------
-
- __tempe2=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- EXCIT=_F(CHARGE=__chart2, ),
- SOLVEUR=_F(STOP_SINGULIER='NON',) )
-
-# --- POUR LE CALCUL DES CONSTANTES DE CISAILLEMENT, ON VA DEFINIR
-# --- UN PREMIER TERME SOURCE, SECOND MEMBRE DE L EQUATION DE LAPLACE
-# --- PAR UNE FONCTION EGALE A Z :
-# --------------------------
-
- __fnsec2=DEFI_FONCTION(NOM_PARA='Y',
- VALE=(0.,0.,10.,10.),
- PROL_DROITE='LINEAIRE',
- PROL_GAUCHE='LINEAIRE', )
-
-# --- LE TERME SOURCE CONSTITUANT LE SECOND MEMBRE DE L EQUATION
-# --- DE LAPLACE EST PRIS EGAL A Z DANS TOUTE LA SECTION :
-# --------------------------------------------------
-
- __chart3=AFFE_CHAR_THER_F(MODELE=__nomoth,
- TEMP_IMPO=_F(NOEUD=l_noeud[i],
- TEMP=__fnsec0),
- SOURCE=_F(TOUT='OUI',
- SOUR=__fnsec2) )
-
-# --- RESOLUTION DE LAPLACIEN(PHI) = -Z
-# --- AVEC D(PHI)/D(N) = 0 SUR LE CONTOUR :
-# ------------------------------------------------
-
- __tempe3=THER_LINEAIRE(MODELE=__nomoth,
- CHAM_MATER=__chmath,
- EXCIT=_F(CHARGE=__chart3, ),
- SOLVEUR=_F(STOP_SINGULIER='NON',) )
-
-# --- CALCUL DE LA CONSTANTE DE TORSION :
-# ---------------------------------
-
- nomres=POST_ELEM(reuse=nomres,
- MODELE=__nomoth,
- CHAM_MATER=__chmath,
- CARA_POUTRE=_F(CARA_GEOM=nomres,
- LAPL_PHI=__tempe1,
- GROUP_MA=l_group_ma[i],
- OPTION='CARA_TORSION' ), )
-
-# --- CALCUL DES COEFFICIENTS DE CISAILLEMENT ET DES COORDONNEES DU
-# --- CENTRE DE CISAILLEMENT/TORSION :
-# ------------------------------
-
- nomres=POST_ELEM(reuse=nomres,
- MODELE=__nomoth,
- CHAM_MATER=__chmath,
- CARA_POUTRE=_F(CARA_GEOM=nomres,
- LAPL_PHI_Y=__tempe2,
- LAPL_PHI_Z=__tempe3,
- GROUP_MA=l_group_ma[i],
- LONGUEUR=LONGUEUR,
- MATERIAU=MATERIAU,
- LIAISON =LIAISON,
- OPTION='CARA_CISAILLEMENT' ), )
-
- return ier
-
diff --git a/Aster/Cata/Macro/macro_matr_asse_ops.py b/Aster/Cata/Macro/macro_matr_asse_ops.py
index 5466b685..4c7f99f1 100644
--- a/Aster/Cata/Macro/macro_matr_asse_ops.py
+++ b/Aster/Cata/Macro/macro_matr_asse_ops.py
@@ -1,21 +1,21 @@
-#@ MODIF macro_matr_asse_ops Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF macro_matr_asse_ops Macro DATE 01/04/2005 AUTEUR VABHHTS J.PELLET
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
-# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
-# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
-# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
-# (AT YOUR OPTION) ANY LATER VERSION.
-#
-# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
-# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
-# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
-#
-# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
-# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
-# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
# ======================================================================
@@ -58,6 +58,15 @@ def macro_matr_asse_ops(self,MODELE,CHAM_MATER,CARA_ELEM,MATR_ASSE,
ier=ier+1
self.cr.fatal(" Avec methode MULT_FRONT, RENUM doit etre MDA, MD ou RCMK.")
return ier
+ elif methode=='MUMPS':
+ if SOLVEUR['RENUM']:
+ renum=SOLVEUR['RENUM']
+ else:
+ renum='SANS'
+ if renum not in ('SANS',):
+ ier=ier+1
+ self.cr.fatal(" Avec methode MUMPS, RENUM doit etre SANS.")
+ return ier
elif methode=='GCPC':
if SOLVEUR['RENUM']:
renum=SOLVEUR['RENUM']
@@ -81,7 +90,7 @@ def macro_matr_asse_ops(self,MODELE,CHAM_MATER,CARA_ELEM,MATR_ASSE,
lrigel = 0
lmasel = 0
-# decalage eventuel en premiere position dans la liste de l occurence de MATR_ASSE contenant
+# decalage eventuel en premiere position dans la liste de l occurence de MATR_ASSE contenant
# l option de rigidite
try :
for m in MATR_ASSE:
@@ -103,20 +112,6 @@ def macro_matr_asse_ops(self,MODELE,CHAM_MATER,CARA_ELEM,MATR_ASSE,
self.cr.fatal(" UNE DES OPTIONS DOIT ETRE RIGI_MECA OU RIGI_THER OU RIGI_ACOU OU RIGI_MECA_LAGR")
return ier
- if m['SIEF_ELGA']!=None and option!='RIGI_GEOM':
- ier=ier+1
- self.cr.fatal(" SIEF_ELGA N EST ADMIS QU AVEC L OPTION RIGI_GEOM")
- return ier
-
- if m['MODE_FOURIER']!=None and option not in ('RIGI_MECA','RIGI_FLUI_STRU','RIGI_THER'):
- ier=ier+1
- self.cr.fatal(" MODE_FOURIER N EST ADMIS QU AVEC UNE DES OPTIONS RIGI_MECA RIGI_FLUI_STRU RIGI_THER")
- return ier
-
- if (m['THETA']!=None or m['PROPAGATION']!=None) and option!='RIGI_MECA_LAGR':
- ier=ier+1
- self.cr.fatal(" PROPAGATION ET,OU THETA NE SONT ADMIS QU AVEC L OPTION RIGI_MECA_LAGR")
- return ier
motscles={'OPTION':option}
if option == 'AMOR_MECA':
@@ -134,11 +129,19 @@ def macro_matr_asse_ops(self,MODELE,CHAM_MATER,CARA_ELEM,MATR_ASSE,
if CHAM_MATER != None: motscles['CHAM_MATER'] =CHAM_MATER
if CARA_ELEM != None: motscles['CARA_ELEM'] =CARA_ELEM
if INST != None: motscles['INST'] =INST
- if m['SIEF_ELGA'] : motscles['SIEF_ELGA'] =m['SIEF_ELGA']
- if m['MODE_FOURIER']: motscles['MODE_FOURIER']=m['MODE_FOURIER']
- if m['THETA'] : motscles['THETA'] =m['THETA']
- if m['PROPAGATION'] : motscles['PROPAGATION'] =m['PROPAGATION']
+ try : motscles['SIEF_ELGA'] =m['SIEF_ELGA']
+ except IndexError : pass
+
+ try : motscles['MODE_FOURIER'] =m['MODE_FOURIER']
+ except IndexError : pass
+
+ try : motscles['THETA'] =m['THETA']
+ except IndexError : pass
+
+ try : motscles['PROPAGATION'] =m['PROPAGATION']
+ except IndexError : pass
+ print motscles
__a=CALC_MATR_ELEM(MODELE=MODELE,**motscles)
if option == 'RIGI_MECA':
diff --git a/Aster/Cata/Macro/pre_gmsh_ops.py b/Aster/Cata/Macro/pre_gmsh_ops.py
deleted file mode 100644
index 8ff4170e..00000000
--- a/Aster/Cata/Macro/pre_gmsh_ops.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# -*- coding: utf-8 -*-
-#@ MODIF pre_gmsh_ops Macro DATE 11/06/2002 AUTEUR DURAND C.DURAND
-# CONFIGURATION MANAGEMENT OF EDF VERSION
-# ======================================================================
-# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
-# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
-# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
-# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
-# (AT YOUR OPTION) ANY LATER VERSION.
-#
-# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
-# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
-# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
-# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
-#
-# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
-# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
-# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
-# ======================================================================
-
-def pre_gmsh_ops(self,UNITE_MAILLAGE,UNITE_GMSH,MODI_QUAD,**args):
- """
- Ecriture de la macro PRE_GMSH
- """
- import os
- from Macro.ajout_quad_gmsh import ajout_quad_gmsh
- ier=0
-
- PRE_GMSH_LECT =self.get_cmd('PRE_GMSH_LECT')
-
- # La macro compte pour 1 dans la numerotation des commandes
- self.icmd=1
-
- if MODI_QUAD=='OUI':
- cur_dir=os.getcwd()
- unit = str(UNITE_GMSH)
- nomFichierGmsh = cur_dir+'/fort.'+unit
- nomFichierMail = cur_dir+'/sortie'
-
-# récupération du fichier .msh complet mis dans la string 'texte'
-
- fproc=open(nomFichierGmsh,'r')
- texte=fproc.read()
- fproc.close()
-
- resu=ajout_quad_gmsh(texte)
- if not resu:
- ier=ier+1
- self.cr.fatal("Erreur dans la methode python de transformation mailles lineaires-quadratiques")
- return ier
-
- fsort=open(nomFichierMail,'w')
- fsort.write(resu)
- fsort.close()
- os.system('cp '+nomFichierMail+' '+nomFichierGmsh)
-
- PRE_GMSH_LECT(UNITE_MAILLAGE = UNITE_MAILLAGE,
- UNITE_GMSH = UNITE_GMSH )
-
- return ier
-
diff --git a/Aster/Cata/Macro/reca_algo.py b/Aster/Cata/Macro/reca_algo.py
index 319d6d67..65e02bd1 100644
--- a/Aster/Cata/Macro/reca_algo.py
+++ b/Aster/Cata/Macro/reca_algo.py
@@ -1,4 +1,4 @@
-#@ MODIF reca_algo Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF reca_algo Macro DATE 14/03/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -26,7 +26,6 @@ import copy,os
import LinearAlgebra
from Cata.cata import INFO_EXEC_ASTER
from Cata.cata import DETRUIRE
-from Macro.recal import EXTRACT
from Accas import _F
diff --git a/Aster/Cata/Macro/recal.py b/Aster/Cata/Macro/recal.py
index cb2d4778..591614c8 100644
--- a/Aster/Cata/Macro/recal.py
+++ b/Aster/Cata/Macro/recal.py
@@ -1,4 +1,4 @@
-#@ MODIF recal Macro DATE 14/09/2004 AUTEUR MCOURTOI M.COURTOIS
+#@ MODIF recal Macro DATE 14/03/2005 AUTEUR DURAND C.DURAND
# -*- coding: iso-8859-1 -*-
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
@@ -29,7 +29,6 @@ import Gnuplot
import Cata
from Cata.cata import INCLUDE,DETRUIRE
from Accas import _F
-from Utilitai.extract import EXTRACT
import os
@@ -151,13 +150,14 @@ def calcul_F(self,UL,para,val,reponses):
Fichier_Resu.append(post_bloc)
#--------------------------------------------------------------------------------
- #on va ajouter la fonction EXTRACT
+ #on va ajouter la fonction d'extraction du numarray de la table par la méthode Array
#et on stocke les réponses calculées dans la liste Lrep
#qui va etre retournée par la fonction calcul_F
self.g_context['Lrep'] = []
Fichier_Resu.append('Lrep=[]'+'\n')
for i in range(len(reponses)):
- Fichier_Resu.append('F = EXTRACT('+str(reponses[i][0])+','+"'"+str(reponses[i][1])+"'"+','+"'"+str(reponses[i][2])+"'"+')'+'\n')
+ Fichier_Resu.append('t'+str(reponses[i][0])+'='+str(reponses[i][0])+'.EXTR_TABLE()'+'\n')
+ Fichier_Resu.append('F = '+'t'+str(reponses[i][0])+'.Array('+"'"+str(reponses[i][1])+"'"+','+"'"+str(reponses[i][2])+"'"+')'+'\n')
Fichier_Resu.append('Lrep.append(F)'+'\n')
#ouverture du fichier fort.3 et mise a jour de celui ci
diff --git a/Pmw/Alpha_99_9_example/__init__.py b/Pmw/Alpha_99_9_example/__init__.py
new file mode 100644
index 00000000..83d04e76
--- /dev/null
+++ b/Pmw/Alpha_99_9_example/__init__.py
@@ -0,0 +1 @@
+# File to allow this directory to be treated as a python package.
diff --git a/Pmw/Alpha_99_9_example/lib/Pmw.def b/Pmw/Alpha_99_9_example/lib/Pmw.def
new file mode 100644
index 00000000..358a2b46
--- /dev/null
+++ b/Pmw/Alpha_99_9_example/lib/Pmw.def
@@ -0,0 +1,9 @@
+# Widgets whose name is the same as its module.
+_widgets = ('AlphaExample',)
+
+# Widgets whose name is not the same as its module.
+_extraWidgets = {}
+
+_functions = {}
+
+_modules = ()
diff --git a/Pmw/Alpha_99_9_example/lib/PmwAlphaExample.py b/Pmw/Alpha_99_9_example/lib/PmwAlphaExample.py
new file mode 100644
index 00000000..5e4f88c1
--- /dev/null
+++ b/Pmw/Alpha_99_9_example/lib/PmwAlphaExample.py
@@ -0,0 +1,24 @@
+import string
+import Pmw
+
+_default_text = "AlphaExample example alpha Pmw megawidget.\nPmw version: " + \
+ Pmw.version() + '\nPmw Alpha versions: ' + \
+ string.join(Pmw.version(alpha = 1), ' ')
+
+class AlphaExample(Pmw.MessageDialog):
+ # Dummy widget for illustrating use of Pmw alpha version directory
+
+ def __init__(self, parent = None, **kw):
+
+ # Define the megawidget options.
+ INITOPT = Pmw.INITOPT
+ optiondefs = (
+ ('message_text', _default_text, None),
+ )
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MessageDialog.__init__(self, parent)
+
+ # Check keywords and initialise options.
+ self.initialiseoptions(AlphaExample)
diff --git a/Pmw/Alpha_99_9_example/lib/__init__.py b/Pmw/Alpha_99_9_example/lib/__init__.py
new file mode 100644
index 00000000..83d04e76
--- /dev/null
+++ b/Pmw/Alpha_99_9_example/lib/__init__.py
@@ -0,0 +1 @@
+# File to allow this directory to be treated as a python package.
diff --git a/Pmw/Pmw_1_2/__init__.py b/Pmw/Pmw_1_2/__init__.py
new file mode 100644
index 00000000..83d04e76
--- /dev/null
+++ b/Pmw/Pmw_1_2/__init__.py
@@ -0,0 +1 @@
+# File to allow this directory to be treated as a python package.
diff --git a/Pmw/Pmw_1_2/bin/bundlepmw.py b/Pmw/Pmw_1_2/bin/bundlepmw.py
new file mode 100755
index 00000000..fdb7dc00
--- /dev/null
+++ b/Pmw/Pmw_1_2/bin/bundlepmw.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+
+# Helper script when freezing Pmw applications. It concatenates all
+# Pmw megawidget files into a single file, 'Pmw.py', in the current
+# directory. The script must be called with one argument, being the
+# path to the 'lib' directory of the required version of Pmw.
+# To freeze a Pmw application, you will also need to copy the
+# following files to the application directory before freezing:
+#
+# PmwBlt.py PmwColor.py
+
+import os
+import regsub
+import string
+import sys
+
+# The order of these files is significant. Files which reference
+# other files must appear later. Files may be deleted if they are not
+# used.
+files = [
+ 'Dialog', 'TimeFuncs', 'Balloon', 'ButtonBox', 'EntryField',
+ 'Group', 'LabeledWidget', 'MainMenuBar', 'MenuBar', 'MessageBar',
+ 'MessageDialog', 'NoteBook', 'OptionMenu', 'PanedWidget', 'PromptDialog',
+ 'RadioSelect', 'ScrolledCanvas', 'ScrolledField', 'ScrolledFrame',
+ 'ScrolledListBox', 'ScrolledText', 'HistoryText', 'SelectionDialog',
+ 'TextDialog', 'TimeCounter', 'AboutDialog', 'ComboBox', 'ComboBoxDialog',
+ 'Counter', 'CounterDialog',
+]
+
+# Set this to 0 if you do not use any of the Pmw.Color functions:
+needColor = 1
+
+# Set this to 0 if you do not use any of the Pmw.Blt functions:
+needBlt = 1
+
+def expandLinks(path):
+ if not os.path.isabs(path):
+ path = os.path.join(os.getcwd(), path)
+ while 1:
+ if not os.path.islink(path):
+ break
+ dir = os.path.dirname(path)
+ path = os.path.join(dir, os.readlink(path))
+
+ return path
+
+def mungeFile(file):
+ # Read the file and modify it so that it can be bundled with the
+ # other Pmw files.
+ file = 'Pmw' + file + '.py'
+ text = open(os.path.join(srcdir, file)).read()
+ text = regsub.gsub('import Pmw\>', '', text)
+ text = regsub.gsub('INITOPT = Pmw.INITOPT', '', text)
+ text = regsub.gsub('\
+#
+# Copyright 2001 MontaVista Software Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+
+import os
+import Tkinter
+import Pmw
+
+
+class DirBrowserDialog(Pmw.MegaToplevel):
+ def __init__(self, parent = None, **kw):
+ cwd = os.getcwd()
+ # Define the megawidget options.
+ INITOPT = Pmw.INITOPT
+ optiondefs = (
+ ('path', cwd, None),
+ ('hidedotfiles', 1, INITOPT),
+ ('label', None, INITOPT),
+ #('labelmargin', 0, INITOPT),
+ #('labelpos', None, INITOPT),
+ ('borderx', 20, INITOPT),
+ ('bordery', 20, INITOPT),
+ )
+
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MegaToplevel.__init__(self, parent)
+
+ interior = self.interior()
+
+ self.childframe = self.createcomponent('childframe', (), None,
+ Tkinter.Frame,
+ (interior,),
+ borderwidth = 1,
+ relief = 'raised',
+ )
+ self.childframe.pack(expand = 1,
+ fill = 'both',
+ )
+
+ self.labelframe = self.createcomponent('labelframe', (), None,
+ Tkinter.Frame,
+ (self.childframe,),
+ borderwidth = 2,
+ relief = 'groove',
+ )
+ self.labelframe.pack(padx = 10, pady = 10, expand = 1, fill = 'both')
+
+ if self['label']:
+ self.label = self.createcomponent('label', (), None,
+ Tkinter.Label,
+ (self.childframe,),
+ text = self['label'],
+ )
+ self.label.place(x = (10 + self['borderx']), y = 10, anchor = 'w')
+
+
+ self.workframe = self.createcomponent('workframe', (), None,
+ Tkinter.Frame,
+ (self.labelframe,),
+ #borderwidth = 2,
+ #relief = 'groove',
+ )
+ self.workframe.pack(padx = self['borderx'],
+ pady = self['bordery'],
+ expand = 1,
+ fill = 'both',
+ )
+
+ self.buttonframe = self.createcomponent('buttonframe', (), None,
+ Tkinter.Frame,
+ (interior,),
+ borderwidth = 1,
+ relief = 'raised',
+ )
+ self.buttonframe.pack(expand = 0,
+ fill = 'x',
+ )
+
+ self.optbox = self.createcomponent('optbox', (), None,
+ Pmw.OptionMenu,
+ (self.workframe,),
+ command = self.setpath,
+ )
+ self.optbox.bind('', self._setMinimumSize)
+
+ self.listbox = self.createcomponent('listbox', (), None,
+ Pmw.ScrolledListBox,
+ (self.workframe,),
+ dblclickcommand = self._select,
+ )
+
+ path = self['path']
+ self.entry = self.createcomponent('entryfield', (), None,
+ Pmw.EntryField,
+ (self.workframe,),
+ value = path,
+ command = self.enteredpath,
+ labelpos = 'nw',
+ label_text = 'Current Path:',
+ )
+
+ #self.createlabel(self.workframe, childCols = 1, childRows = 3)
+
+ self.buttonbox = self.createcomponent('buttonbox', (), None,
+ Pmw.ButtonBox,
+ (self.buttonframe,),
+ )
+ self.buttonbox.add('OK', text = 'OK',
+ command = self.okbutton)
+ self.buttonbox.add('Cancel', text = 'Cancel',
+ command = self.cancelbutton)
+ self.buttonbox.add('New Directory', text = 'New Directory',
+ command = self.newdirbutton)
+
+ self.buttonbox.alignbuttons()
+ self.buttonbox.pack(expand = 1, fill = 'x')
+
+ self.optbox.grid(row = 2, column = 2, sticky = 'ew')
+ self.listbox.grid(row = 3, column = 2, sticky = 'news')
+ self.entry.grid(row = 5, column = 2, sticky = 'ew')
+ self.workframe.grid_rowconfigure(3, weight = 1)
+ self.workframe.grid_rowconfigure(4, minsize = 20)
+ self.workframe.grid_columnconfigure(2, weight = 1)
+
+
+ self.setpath(self['path'])
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+ def setpath(self, path):
+ path = os.path.abspath(os.path.expanduser(path))
+
+ if os.path.isfile(path):
+ path = os.path.dirname(path)
+
+ dirlist = []
+ hidedotfiles = self['hidedotfiles']
+ try:
+ posix = (os.name == 'posix')
+ for entry in os.listdir(path):
+ entryPath = path + '/' + entry
+ if hidedotfiles and entry[0] == '.':
+ # skip dot files if desired
+ continue
+ if not os.path.isdir(entryPath):
+ # skip files
+ continue
+ if not os.access(entryPath, os.R_OK | os.X_OK):
+ # skip directories we can't enter any way
+ continue
+ dirlist.append(entry)
+
+ except:
+ self.entry.setentry(self['path'])
+ return
+
+ self.entry.setentry(path)
+
+ self['path'] = path
+
+ dirlist.sort()
+ if path != '/':
+ dirlist.insert(0, '..')
+
+ self.listbox.setlist(dirlist)
+ pathlist = []
+ while path != '/':
+ pathlist.append(path)
+ path = os.path.dirname(path)
+ pathlist.append('/')
+ self.optbox.setitems(pathlist, 0)
+
+ def _setMinimumSize(self, event):
+ # If the optionmenu changes width, make sure it does not
+ # shrink later.
+ owidth = self.optbox.winfo_width()
+ self.workframe.grid_columnconfigure(2, minsize = owidth)
+
+ def _select(self):
+ sel = self.listbox.getcurselection()
+ if self['path'] == '/':
+ self['path'] = ''
+ if len(sel) > 0:
+ if sel[0] == '..':
+ self.setpath(os.path.dirname(self['path']))
+ else:
+ self.setpath(self['path'] + '/' + sel[0])
+
+
+ def getcurpath(self):
+ return self['path']
+
+ def enteredpath(self):
+ self.setpath(self.entry.get())
+
+ def okbutton(self):
+ self.deactivate(self['path'])
+
+ def cancelbutton(self):
+ self.deactivate(None)
+
+ def newdirbutton(self):
+ CreateDirectoryPopup(self.interior(), self['path'])
+ self.setpath(self['path'])
+
+
+
+class CreateDirectoryPopup:
+ def __init__(self, parent, path):
+ self.path = path
+ self.parent = parent
+ self.newdirpopup = Pmw.PromptDialog(parent,
+ buttons = ('OK', 'Cancel'),
+ defaultbutton = 'OK',
+ title = 'New Directory',
+ entryfield_labelpos = 'nw',
+ label_text = 'Enter new directory name for:\n%s'%self.path,
+ command = self._buttonpress
+ )
+
+ self.newdirpopup.activate()
+
+ def _buttonpress(self, button):
+ if button == 'OK':
+ newdirname = self.newdirpopup.get()
+ dirlist = os.listdir(self.path)
+ if newdirname in dirlist:
+ ErrorPopup(self.parent,
+ 'Error: "%s", already exists as a file or directory.'%newdirname)
+ else:
+ try:
+ os.mkdir(self.path + '/' + newdirname)
+ except:
+ ErrorPopup(self.parent,
+ 'Error: Could not create directory: "%s"'%newdirname)
+ else:
+ self.newdirpopup.deactivate()
+ else:
+ self.newdirpopup.deactivate()
+
+
+def ErrorPopup(parent, message):
+ error = Pmw.MessageDialog(parent, title = 'Error',
+ message_text = message,
+ defaultbutton = 0,
+ )
+ error.activate()
+
+if __name__ == '__main__':
+
+ rootWin = Tkinter.Tk()
+
+ Pmw.initialise()
+
+ rootWin.title('Directory Browser Dialog Demo')
+
+ def buildBrowser():
+ # Create the hierarchical directory browser widget
+ dirBrowserDialog = DirBrowserDialog(rootWin,
+ #labelpos = 'nw',
+ label = 'Select a directory',
+ title = 'Directory Selector',
+ #path = '~',
+ #hidedotfiles = 0,
+ )
+ dir = dirBrowserDialog.activate()
+ print 'Selected Directory:', dir
+
+ dirButton = Tkinter.Button(rootWin, text="Browser", command=buildBrowser)
+ dirButton.pack(side = 'left', padx = 10, pady = 10)
+
+ exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit)
+ exitButton.pack(side = 'left', padx = 10, pady = 10)
+
+ rootWin.mainloop()
diff --git a/Pmw/Pmw_1_2/contrib/MCListbox.py b/Pmw/Pmw_1_2/contrib/MCListbox.py
new file mode 100644
index 00000000..166b8a04
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/MCListbox.py
@@ -0,0 +1,706 @@
+#
+# FILE: MCListbox.py
+#
+# DESCRIPTION:
+# This file provides a generic Multi-Column Listbox widget. It is derived
+# from a heavily hacked version of Pmw.ScrolledFrame
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import string
+import Tkinter
+import Pmw
+
+class MultiColumnListbox(Pmw.MegaWidget):
+ def __init__(self, parent = None, **kw):
+ colors = Pmw.Color.getdefaultpalette(parent)
+
+ # Define the megawidget options.
+ INITOPT = Pmw.INITOPT
+ optiondefs = (
+ #('borderframe', 1, INITOPT),
+ ('horizflex', 'fixed', self._horizflex),
+ ('horizfraction', 0.05, INITOPT),
+ ('hscrollmode', 'dynamic', self._hscrollMode),
+ ('labelmargin', 0, INITOPT),
+ ('labelpos', None, INITOPT),
+ ('scrollmargin', 2, INITOPT),
+ ('usehullsize', 0, INITOPT),
+ ('vertflex', 'fixed', self._vertflex),
+ ('vertfraction', 0.05, INITOPT),
+ ('vscrollmode', 'dynamic', self._vscrollMode),
+ ('labellist', None, INITOPT),
+ ('selectbackground', colors['selectBackground'], INITOPT),
+ ('selectforeground', colors['selectForeground'], INITOPT),
+ ('background', colors['background'], INITOPT),
+ ('foreground', colors['foreground'], INITOPT),
+ ('command', None, None),
+ ('dblclickcommand', None, None),
+ )
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MegaWidget.__init__(self, parent)
+
+ self._numcolumns = len(self['labellist'])
+ self._columnlabels = self['labellist']
+ self._lineid = 0
+ self._numrows = 0
+ self._lineitemframes = []
+ self._lineitems = []
+ self._lineitemdata = {}
+ self._labelframe = {}
+ self._cursel = []
+
+ # Create the components.
+ self.origInterior = Pmw.MegaWidget.interior(self)
+
+ if self['usehullsize']:
+ self.origInterior.grid_propagate(0)
+
+ # Create a frame widget to act as the border of the clipper.
+ self._borderframe = self.createcomponent('borderframe',
+ (), None,
+ Tkinter.Frame,
+ (self.origInterior,),
+ relief = 'sunken',
+ borderwidth = 2,
+ )
+ self._borderframe.grid(row = 2, column = 2,
+ rowspan = 2, sticky = 'news')
+
+ # Create the clipping windows.
+ self._hclipper = self.createcomponent('hclipper',
+ (), None,
+ Tkinter.Frame,
+ (self._borderframe,),
+ width = 400,
+ height = 300,
+ )
+ self._hclipper.pack(fill = 'both', expand = 1)
+
+ self._hsframe = self.createcomponent('hsframe', (), None,
+ Tkinter.Frame,
+ (self._hclipper,),
+ )
+
+
+ self._vclipper = self.createcomponent('vclipper',
+ (), None,
+ Tkinter.Frame,
+ (self._hsframe,),
+ #width = 400,
+ #height = 300,
+ highlightthickness = 0,
+ borderwidth = 0,
+ )
+
+ self._vclipper.grid(row = 1, column = 0,
+ columnspan = self._numcolumns,
+ sticky = 'news')#, expand = 1)
+ self._hsframe.grid_rowconfigure(1, weight = 1)#, minsize = 300)
+
+
+ gridcolumn = 0
+ for labeltext in self._columnlabels:
+ lframe = self.createcomponent(labeltext+'frame', (), None,
+ Tkinter.Frame,
+ (self._hsframe,),
+ borderwidth = 1,
+ relief = 'raised',
+ )
+ label = self.createcomponent(labeltext, (), None,
+ Tkinter.Label,
+ (lframe,),
+ text = labeltext,
+ )
+ label.pack(expand = 0, fill = 'y', side = 'left')
+ lframe.grid(row = 0, column = gridcolumn, sticky = 'ews')
+ self._labelframe[labeltext] = lframe
+ #lframe.update()
+ #print lframe.winfo_reqwidth()
+ self._hsframe.grid_columnconfigure(gridcolumn, weight = 1)
+ gridcolumn = gridcolumn + 1
+
+ lframe.update()
+ self._labelheight = lframe.winfo_reqheight()
+ self.origInterior.grid_rowconfigure(2, minsize = self._labelheight + 2)
+
+ self.origInterior.grid_rowconfigure(3, weight = 1, minsize = 0)
+ self.origInterior.grid_columnconfigure(2, weight = 1, minsize = 0)
+
+ # Create the horizontal scrollbar
+ self._horizScrollbar = self.createcomponent('horizscrollbar',
+ (), 'Scrollbar',
+ Tkinter.Scrollbar,
+ (self.origInterior,),
+ orient='horizontal',
+ command=self._xview
+ )
+
+ # Create the vertical scrollbar
+ self._vertScrollbar = self.createcomponent('vertscrollbar',
+ (), 'Scrollbar',
+ Tkinter.Scrollbar,
+ (self.origInterior,),
+ #(self._hclipper,),
+ orient='vertical',
+ command=self._yview
+ )
+
+ self.createlabel(self.origInterior, childCols = 3, childRows = 4)
+
+ # Initialise instance variables.
+ self._horizScrollbarOn = 0
+ self._vertScrollbarOn = 0
+ self.scrollTimer = None
+ self._scrollRecurse = 0
+ self._horizScrollbarNeeded = 0
+ self._vertScrollbarNeeded = 0
+ self.startX = 0
+ self.startY = 0
+ self._flexoptions = ('fixed', 'expand', 'shrink', 'elastic')
+
+ # Create a frame in the clipper to contain the widgets to be
+ # scrolled.
+ self._vsframe = self.createcomponent('vsframe',
+ (), None,
+ Tkinter.Frame,
+ (self._vclipper,),
+ #height = 300,
+ #borderwidth = 4,
+ #relief = 'groove',
+ )
+
+ # Whenever the clipping window or scrolled frame change size,
+ # update the scrollbars.
+ self._hsframe.bind('', self._reposition)
+ self._vsframe.bind('', self._reposition)
+ self._hclipper.bind('', self._reposition)
+ self._vclipper.bind('', self._reposition)
+
+ #elf._vsframe.bind('', self._vsframeselect)
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+ def destroy(self):
+ if self.scrollTimer is not None:
+ self.after_cancel(self.scrollTimer)
+ self.scrollTimer = None
+ Pmw.MegaWidget.destroy(self)
+
+ # ======================================================================
+
+ # Public methods.
+
+ def interior(self):
+ return self._vsframe
+
+ # Set timer to call real reposition method, so that it is not
+ # called multiple times when many things are reconfigured at the
+ # same time.
+ def reposition(self):
+ if self.scrollTimer is None:
+ self.scrollTimer = self.after_idle(self._scrollBothNow)
+
+
+
+ def insertrow(self, index, rowdata):
+ #if len(rowdata) != self._numcolumns:
+ # raise ValueError, 'Number of items in rowdata does not match number of columns.'
+ if index > self._numrows:
+ index = self._numrows
+
+ rowframes = {}
+ for columnlabel in self._columnlabels:
+ celldata = rowdata.get(columnlabel)
+ cellframe = self.createcomponent(('cellframeid.%d.%s'%(self._lineid,
+ columnlabel)),
+ (), ('Cellframerowid.%d'%self._lineid),
+ Tkinter.Frame,
+ (self._vsframe,),
+ background = self['background'],
+ #borderwidth = 1,
+ #relief = 'flat'
+ )
+
+ cellframe.bind('', self._cellframedblclick)
+ cellframe.bind('', self._cellframeselect)
+
+ if celldata:
+ cell = self.createcomponent(('cellid.%d.%s'%(self._lineid,
+ columnlabel)),
+ (), ('Cellrowid.%d'%self._lineid),
+ Tkinter.Label,
+ (cellframe,),
+ background = self['background'],
+ foreground = self['foreground'],
+ text = celldata,
+ )
+
+ cell.bind('', self._celldblclick)
+ cell.bind('', self._cellselect)
+
+ cell.pack(expand = 0, fill = 'y', side = 'left', padx = 1, pady = 1)
+ rowframes[columnlabel] = cellframe
+
+ self._lineitemdata[self._lineid] = rowdata
+ self._lineitems.insert(index, self._lineid)
+ self._lineitemframes.insert(index, rowframes)
+ self._numrows = self._numrows + 1
+ self._lineid = self._lineid + 1
+
+ self._placedata(index)
+
+ def _placedata(self, index = 0):
+ gridy = index
+ for rowframes in self._lineitemframes[index:]:
+ gridx = 0
+ for columnlabel in self._columnlabels:
+ rowframes[columnlabel].grid(row = gridy,
+ column = gridx,
+ sticky = 'news')
+ gridx = gridx + 1
+ gridy = gridy + 1
+
+
+
+ def addrow(self, rowdata):
+ self.insertrow(self._numrows, rowdata)
+
+ def delrow(self, index):
+ rowframes = self._lineitemframes.pop(index)
+ for columnlabel in self._columnlabels:
+ rowframes[columnlabel].destroy()
+ self._placedata(index)
+ self._numrows = self._numrows - 1
+ del self._lineitems[index]
+ if index in self._cursel:
+ self._cursel.remove(index)
+
+
+ def curselection(self):
+ # Return a tuple of just one element as this will probably be the
+ # interface used in a future implementation when multiple rows can
+ # be selected at once.
+ return tuple(self._cursel)
+
+ def getcurselection(self):
+ # Return a tuple of just one row as this will probably be the
+ # interface used in a future implementation when multiple rows can
+ # be selected at once.
+ sellist = []
+ for sel in self._cursel:
+ sellist.append(self._lineitemdata[self._lineitems[sel]])
+ return tuple(sellist)
+
+ # ======================================================================
+
+ # Configuration methods.
+
+ def _hscrollMode(self):
+ # The horizontal scroll mode has been configured.
+
+ mode = self['hscrollmode']
+
+
+ if mode == 'static':
+ if not self._horizScrollbarOn:
+ self._toggleHorizScrollbar()
+ elif mode == 'dynamic':
+ if self._horizScrollbarNeeded != self._horizScrollbarOn:
+ self._toggleHorizScrollbar()
+ elif mode == 'none':
+ if self._horizScrollbarOn:
+ self._toggleHorizScrollbar()
+ else:
+ message = 'bad hscrollmode option "%s": should be static, dynamic, or none' % mode
+ raise ValueError, message
+
+ def _vscrollMode(self):
+ # The vertical scroll mode has been configured.
+
+ mode = self['vscrollmode']
+
+ if mode == 'static':
+ if not self._vertScrollbarOn:
+ self._toggleVertScrollbar()
+ elif mode == 'dynamic':
+ if self._vertScrollbarNeeded != self._vertScrollbarOn:
+ self._toggleVertScrollbar()
+ elif mode == 'none':
+ if self._vertScrollbarOn:
+ self._toggleVertScrollbar()
+ else:
+ message = 'bad vscrollmode option "%s": should be static, dynamic, or none' % mode
+ raise ValueError, message
+
+ def _horizflex(self):
+ # The horizontal flex mode has been configured.
+
+ flex = self['horizflex']
+
+ if flex not in self._flexoptions:
+ message = 'bad horizflex option "%s": should be one of %s' % \
+ mode, str(self._flexoptions)
+ raise ValueError, message
+
+ self.reposition()
+
+ def _vertflex(self):
+ # The vertical flex mode has been configured.
+
+ flex = self['vertflex']
+
+ if flex not in self._flexoptions:
+ message = 'bad vertflex option "%s": should be one of %s' % \
+ mode, str(self._flexoptions)
+ raise ValueError, message
+
+ self.reposition()
+
+
+
+ # ======================================================================
+
+ # Private methods.
+
+ def _reposition(self, event):
+ gridx = 0
+ for col in self._columnlabels:
+ maxwidth = self._labelframe[col].winfo_reqwidth()
+ for row in self._lineitemframes:
+ cellwidth = row[col].winfo_reqwidth()
+ if cellwidth > maxwidth:
+ maxwidth = cellwidth
+ self._hsframe.grid_columnconfigure(gridx, minsize = maxwidth)
+ gridwidth = self._hsframe.grid_bbox(column = gridx, row = 0)[2]
+ if self['horizflex'] in ('expand', 'elastic') and gridwidth > maxwidth:
+ maxwidth = gridwidth
+ self._vsframe.grid_columnconfigure(gridx, minsize = maxwidth)
+ gridx = gridx + 1
+
+
+
+ self._vclipper.configure(height = self._hclipper.winfo_height() - self._labelheight)
+
+ self.reposition()
+
+ # Called when the user clicks in the horizontal scrollbar.
+ # Calculates new position of frame then calls reposition() to
+ # update the frame and the scrollbar.
+ def _xview(self, mode, value, units = None):
+
+ if mode == 'moveto':
+ frameWidth = self._hsframe.winfo_reqwidth()
+ self.startX = string.atof(value) * float(frameWidth)
+ else:
+ clipperWidth = self._hclipper.winfo_width()
+ if units == 'units':
+ jump = int(clipperWidth * self['horizfraction'])
+ else:
+ jump = clipperWidth
+
+ if value == '1':
+ self.startX = self.startX + jump
+ else:
+ self.startX = self.startX - jump
+
+ self.reposition()
+
+ # Called when the user clicks in the vertical scrollbar.
+ # Calculates new position of frame then calls reposition() to
+ # update the frame and the scrollbar.
+ def _yview(self, mode, value, units = None):
+
+ if mode == 'moveto':
+ frameHeight = self._vsframe.winfo_reqheight()
+ self.startY = string.atof(value) * float(frameHeight)
+ else:
+ clipperHeight = self._vclipper.winfo_height()
+ if units == 'units':
+ jump = int(clipperHeight * self['vertfraction'])
+ else:
+ jump = clipperHeight
+
+ if value == '1':
+ self.startY = self.startY + jump
+ else:
+ self.startY = self.startY - jump
+
+ self.reposition()
+
+ def _getxview(self):
+
+ # Horizontal dimension.
+ clipperWidth = self._hclipper.winfo_width()
+ frameWidth = self._hsframe.winfo_reqwidth()
+ if frameWidth <= clipperWidth:
+ # The scrolled frame is smaller than the clipping window.
+
+ self.startX = 0
+ endScrollX = 1.0
+
+ if self['horizflex'] in ('expand', 'elastic'):
+ relwidth = 1
+ else:
+ relwidth = ''
+ else:
+ # The scrolled frame is larger than the clipping window.
+
+ if self['horizflex'] in ('shrink', 'elastic'):
+ self.startX = 0
+ endScrollX = 1.0
+ relwidth = 1
+ else:
+ if self.startX + clipperWidth > frameWidth:
+ self.startX = frameWidth - clipperWidth
+ endScrollX = 1.0
+ else:
+ if self.startX < 0:
+ self.startX = 0
+ endScrollX = (self.startX + clipperWidth) / float(frameWidth)
+ relwidth = ''
+
+ # Position frame relative to clipper.
+ self._hsframe.place(x = -self.startX, relwidth = relwidth)
+ return (self.startX / float(frameWidth), endScrollX)
+
+ def _getyview(self):
+
+ # Vertical dimension.
+ clipperHeight = self._vclipper.winfo_height()
+ frameHeight = self._vsframe.winfo_reqheight()
+ if frameHeight <= clipperHeight:
+ # The scrolled frame is smaller than the clipping window.
+
+ self.startY = 0
+ endScrollY = 1.0
+
+ if self['vertflex'] in ('expand', 'elastic'):
+ relheight = 1
+ else:
+ relheight = ''
+ else:
+ # The scrolled frame is larger than the clipping window.
+
+ if self['vertflex'] in ('shrink', 'elastic'):
+ self.startY = 0
+ endScrollY = 1.0
+ relheight = 1
+ else:
+ if self.startY + clipperHeight > frameHeight:
+ self.startY = frameHeight - clipperHeight
+ endScrollY = 1.0
+ else:
+ if self.startY < 0:
+ self.startY = 0
+ endScrollY = (self.startY + clipperHeight) / float(frameHeight)
+ relheight = ''
+
+ # Position frame relative to clipper.
+ self._vsframe.place(y = -self.startY, relheight = relheight)
+ return (self.startY / float(frameHeight), endScrollY)
+
+ # According to the relative geometries of the frame and the
+ # clipper, reposition the frame within the clipper and reset the
+ # scrollbars.
+ def _scrollBothNow(self):
+ self.scrollTimer = None
+
+ # Call update_idletasks to make sure that the containing frame
+ # has been resized before we attempt to set the scrollbars.
+ # Otherwise the scrollbars may be mapped/unmapped continuously.
+ self._scrollRecurse = self._scrollRecurse + 1
+ self.update_idletasks()
+ self._scrollRecurse = self._scrollRecurse - 1
+ if self._scrollRecurse != 0:
+ return
+
+ xview = self._getxview()
+ yview = self._getyview()
+ self._horizScrollbar.set(xview[0], xview[1])
+ self._vertScrollbar.set(yview[0], yview[1])
+
+ self._horizScrollbarNeeded = (xview != (0.0, 1.0))
+ self._vertScrollbarNeeded = (yview != (0.0, 1.0))
+
+ # If both horizontal and vertical scrollmodes are dynamic and
+ # currently only one scrollbar is mapped and both should be
+ # toggled, then unmap the mapped scrollbar. This prevents a
+ # continuous mapping and unmapping of the scrollbars.
+ if (self['hscrollmode'] == self['vscrollmode'] == 'dynamic' and
+ self._horizScrollbarNeeded != self._horizScrollbarOn and
+ self._vertScrollbarNeeded != self._vertScrollbarOn and
+ self._vertScrollbarOn != self._horizScrollbarOn):
+ if self._horizScrollbarOn:
+ self._toggleHorizScrollbar()
+ else:
+ self._toggleVertScrollbar()
+ return
+
+ if self['hscrollmode'] == 'dynamic':
+ if self._horizScrollbarNeeded != self._horizScrollbarOn:
+ self._toggleHorizScrollbar()
+
+ if self['vscrollmode'] == 'dynamic':
+ if self._vertScrollbarNeeded != self._vertScrollbarOn:
+ self._toggleVertScrollbar()
+
+ def _toggleHorizScrollbar(self):
+
+ self._horizScrollbarOn = not self._horizScrollbarOn
+
+ interior = self.origInterior
+ if self._horizScrollbarOn:
+ self._horizScrollbar.grid(row = 5, column = 2, sticky = 'news')
+ interior.grid_rowconfigure(4, minsize = self['scrollmargin'])
+ else:
+ self._horizScrollbar.grid_forget()
+ interior.grid_rowconfigure(4, minsize = 0)
+
+ def _toggleVertScrollbar(self):
+
+ self._vertScrollbarOn = not self._vertScrollbarOn
+
+ interior = self.origInterior
+ if self._vertScrollbarOn:
+ self._vertScrollbar.grid(row = 3, column = 4, sticky = 'news')
+ interior.grid_columnconfigure(3, minsize = self['scrollmargin'])
+ else:
+ self._vertScrollbar.grid_forget()
+ interior.grid_columnconfigure(3, minsize = 0)
+
+ # ======================================================================
+
+ # Selection methods.
+
+ #def _vsframeselect(self, event):
+ # print 'vsframe event x: %d y: %d'%(event.x, event.y)
+ # col, row = self._vsframe.grid_location(event.x, event.y)
+ # self._select(col, row)
+
+ def _cellframeselect(self, event):
+ #print 'cellframe event x: %d y: %d'%(event.x, event.y)
+ x = event.widget.winfo_x()
+ y = event.widget.winfo_y()
+ #col, row = self._vsframe.grid_location(x + event.x, y + event.y)
+ self._select(x + event.x, y + event.y)#(col, row)
+
+ def _cellselect(self, event):
+ #print 'cell event x: %d y: %d'%(event.x, event.y)
+ lx = event.widget.winfo_x()
+ ly = event.widget.winfo_y()
+ parent = event.widget.pack_info()['in']
+ fx = parent.winfo_x()
+ fy = parent.winfo_y()
+ #col, row = self._vsframe.grid_location(fx + lx + event.x, fy + ly + event.y)
+ self._select(fx + lx + event.x, fy + ly + event.y)#(col, row)
+
+ def _select(self, x, y):
+ col, row = self._vsframe.grid_location(x, y)
+ #print 'Clicked on col: %d row: %d'%(col,row)
+ cfg = {}
+ lineid = self._lineitems[row]
+ cfg['Cellrowid.%d_foreground'%lineid] = self['selectforeground']
+ cfg['Cellrowid.%d_background'%lineid] = self['selectbackground']
+ cfg['Cellframerowid.%d_background'%lineid] = self['selectbackground']
+ #cfg['Cellframerowid%d_relief'%row] = 'raised'
+
+ if self._cursel != []:
+ cursel = self._cursel[0]
+ lineid = self._lineitems[cursel]
+ if cursel != None and cursel != row:
+ cfg['Cellrowid.%d_foreground'%lineid] = self['foreground']
+ cfg['Cellrowid.%d_background'%lineid] = self['background']
+ cfg['Cellframerowid.%d_background'%lineid] = self['background']
+ #cfg['Cellframerowid%d_relief'%cursel] = 'flat'
+
+ apply(self.configure, (), cfg)
+ self._cursel = [row]
+
+ cmd = self['command']
+ if callable(cmd):
+ cmd()
+
+
+
+ def _cellframedblclick(self, event):
+ #print 'double click cell frame'
+ cmd = self['dblclickcommand']
+ if callable(cmd):
+ cmd()
+
+ def _celldblclick(self, event):
+ #print 'double click cell'
+ cmd = self['dblclickcommand']
+ if callable(cmd):
+ cmd()
+
+if __name__ == '__main__':
+
+ rootWin = Tkinter.Tk()
+
+ Pmw.initialise()
+
+ rootWin.title('MultiColumnListbox Demo')
+ rootWin.configure(width = 500, height = 300)
+ rootWin.update()
+
+ def dbl():
+ print listbox.getcurselection()
+
+ listbox = MultiColumnListbox(rootWin,
+ #usehullsize = 1,
+ labellist = ('Column 0',
+ 'Column 1',
+ 'Column 2',
+ 'Column 3',
+ 'Column 4',
+ #'Column 5',
+ #'Column 6',
+ #'Column 7',
+ #'Column 8',
+ #'Column 9',
+ ),
+ horizflex = 'expand',
+ #vertflex = 'elastic',
+ dblclickcommand = dbl,
+ )
+
+
+ #print 'start adding item'
+ for i in range(20):
+ r = {}
+ for j in range(5):
+ r[('Column %d'%j)] = 'Really long item name %d'%i
+ listbox.addrow(r)
+ #print 'items added'
+
+ listbox.pack(expand = 1, fill = 'both', padx = 10, pady = 10)
+
+
+ exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit)
+ exitButton.pack(side = 'left', padx = 10, pady = 10)
+
+ rootWin.mainloop()
diff --git a/Pmw/Pmw_1_2/contrib/PmwFileDialog.py b/Pmw/Pmw_1_2/contrib/PmwFileDialog.py
new file mode 100644
index 00000000..dc7b4616
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/PmwFileDialog.py
@@ -0,0 +1,498 @@
+#
+__version__ = '$Id: PmwFileDialog.py,v 1.2 2002/08/23 15:03:35 gregm Exp $'
+#
+# Filename dialogs using Pmw
+#
+# (C) Rob W.W. Hooft, Nonius BV, 1998
+#
+# Modifications:
+#
+# J. Willem M. Nissink, Cambridge Crystallographic Data Centre, 8/2002
+# Added optional information pane at top of dialog; if option
+# 'info' is specified, the text given will be shown (in blue).
+# Modified example to show both file and directory-type dialog
+#
+# No Guarantees. Distribute Freely.
+# Please send bug-fixes/patches/features to
+#
+################################################################################
+import os,fnmatch,time
+import Tkinter,Pmw
+#Pmw.setversion("0.8.5")
+
+def _errorpop(master,text):
+ d=Pmw.MessageDialog(master,
+ title="Error",
+ message_text=text,
+ buttons=("OK",))
+ d.component('message').pack(ipadx=15,ipady=15)
+ d.activate()
+ d.destroy()
+
+class PmwFileDialog(Pmw.Dialog):
+ """File Dialog using Pmw"""
+ def __init__(self, parent = None, **kw):
+ # Define the megawidget options.
+ optiondefs = (
+ ('filter', '*', self.newfilter),
+ ('directory', os.getcwd(), self.newdir),
+ ('filename', '', self.newfilename),
+ ('historylen',10, None),
+ ('command', None, None),
+ ('info', None, None),
+ )
+ self.defineoptions(kw, optiondefs)
+ # Initialise base class (after defining options).
+ Pmw.Dialog.__init__(self, parent)
+
+ self.withdraw()
+
+ # Create the components.
+ interior = self.interior()
+
+ if self['info'] is not None:
+ rowoffset=1
+ dn = self.infotxt()
+ dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3)
+ else:
+ rowoffset=0
+
+ dn = self.mkdn()
+ dn.grid(row=0+rowoffset,column=0,columnspan=2,padx=3,pady=3)
+ del dn
+
+ # Create the directory list component.
+ dnb = self.mkdnb()
+ dnb.grid(row=1+rowoffset,column=0,sticky='news',padx=3,pady=3)
+ del dnb
+
+ # Create the filename list component.
+ fnb = self.mkfnb()
+ fnb.grid(row=1+rowoffset,column=1,sticky='news',padx=3,pady=3)
+ del fnb
+
+ # Create the filter entry
+ ft = self.mkft()
+ ft.grid(row=2+rowoffset,column=0,columnspan=2,padx=3,pady=3)
+ del ft
+
+ # Create the filename entry
+ fn = self.mkfn()
+ fn.grid(row=3+rowoffset,column=0,columnspan=2,padx=3,pady=3)
+ fn.bind('',self.okbutton)
+ del fn
+
+ # Buttonbox already exists
+ bb=self.component('buttonbox')
+ bb.add('OK',command=self.okbutton)
+ bb.add('Cancel',command=self.cancelbutton)
+ del bb
+
+ Pmw.alignlabels([self.component('filename'),
+ self.component('filter'),
+ self.component('dirname')])
+
+ def infotxt(self):
+ """ Make information block component at the top """
+ return self.createcomponent(
+ 'infobox',
+ (), None,
+ Tkinter.Label, (self.interior(),),
+ width=51,
+ relief='groove',
+ foreground='darkblue',
+ justify='left',
+ text=self['info']
+ )
+
+ def mkdn(self):
+ """Make directory name component"""
+ return self.createcomponent(
+ 'dirname',
+ (), None,
+ Pmw.ComboBox, (self.interior(),),
+ entryfield_value=self['directory'],
+ entryfield_entry_width=40,
+ entryfield_validate=self.dirvalidate,
+ selectioncommand=self.setdir,
+ labelpos='w',
+ label_text='Directory:')
+
+ def mkdnb(self):
+ """Make directory name box"""
+ return self.createcomponent(
+ 'dirnamebox',
+ (), None,
+ Pmw.ScrolledListBox, (self.interior(),),
+ label_text='directories',
+ labelpos='n',
+ hscrollmode='none',
+ dblclickcommand=self.selectdir)
+
+ def mkft(self):
+ """Make filter"""
+ return self.createcomponent(
+ 'filter',
+ (), None,
+ Pmw.ComboBox, (self.interior(),),
+ entryfield_value=self['filter'],
+ entryfield_entry_width=40,
+ selectioncommand=self.setfilter,
+ labelpos='w',
+ label_text='Filter:')
+
+ def mkfnb(self):
+ """Make filename list box"""
+ return self.createcomponent(
+ 'filenamebox',
+ (), None,
+ Pmw.ScrolledListBox, (self.interior(),),
+ label_text='files',
+ labelpos='n',
+ hscrollmode='none',
+ selectioncommand=self.singleselectfile,
+ dblclickcommand=self.selectfile)
+
+ def mkfn(self):
+ """Make file name entry"""
+ return self.createcomponent(
+ 'filename',
+ (), None,
+ Pmw.ComboBox, (self.interior(),),
+ entryfield_value=self['filename'],
+ entryfield_entry_width=40,
+ entryfield_validate=self.filevalidate,
+ selectioncommand=self.setfilename,
+ labelpos='w',
+ label_text='Filename:')
+
+ def dirvalidate(self,string):
+ if os.path.isdir(string):
+ return Pmw.OK
+ else:
+ return Pmw.PARTIAL
+
+ def filevalidate(self,string):
+ if string=='':
+ return Pmw.PARTIAL
+ elif os.path.isfile(string):
+ return Pmw.OK
+ elif os.path.exists(string):
+ return Pmw.PARTIAL
+ else:
+ return Pmw.OK
+
+ def okbutton(self):
+ """OK action: user thinks he has input valid data and wants to
+ proceed. This is also called by in the filename entry"""
+ fn=self.component('filename').get()
+ self.setfilename(fn)
+ if self.validate(fn):
+ self.canceled=0
+ self.deactivate()
+
+ def cancelbutton(self):
+ """Cancel the operation"""
+ self.canceled=1
+ self.deactivate()
+
+ def tidy(self,w,v):
+ """Insert text v into the entry and at the top of the list of
+ the combobox w, remove duplicates"""
+ if not v:
+ return
+ entry=w.component('entry')
+ entry.delete(0,'end')
+ entry.insert(0,v)
+ list=w.component('scrolledlist')
+ list.insert(0,v)
+ index=1
+ while indexself['historylen']:
+ list.delete(index)
+ else:
+ index=index+1
+ w.checkentry()
+
+ def setfilename(self,value):
+ if not value:
+ return
+ value=os.path.join(self['directory'],value)
+ dir,fil=os.path.split(value)
+ self.configure(directory=dir,filename=value)
+
+ c=self['command']
+ if callable(c):
+ c()
+
+ def newfilename(self):
+ """Make sure a newly set filename makes it into the combobox list"""
+ self.tidy(self.component('filename'),self['filename'])
+
+ def setfilter(self,value):
+ self.configure(filter=value)
+
+ def newfilter(self):
+ """Make sure a newly set filter makes it into the combobox list"""
+ self.tidy(self.component('filter'),self['filter'])
+ self.fillit()
+
+ def setdir(self,value):
+ self.configure(directory=value)
+
+ def newdir(self):
+ """Make sure a newly set dirname makes it into the combobox list"""
+ self.tidy(self.component('dirname'),self['directory'])
+ self.fillit()
+
+ def singleselectfile(self):
+ """Single click in file listbox. Move file to "filename" combobox"""
+ cs=self.component('filenamebox').curselection()
+ if cs!=():
+ value=self.component('filenamebox').get(cs)
+ self.setfilename(value)
+
+ def selectfile(self):
+ """Take the selected file from the filename, normalize it, and OK"""
+ self.singleselectfile()
+ value=self.component('filename').get()
+ self.setfilename(value)
+ if value:
+ self.okbutton()
+
+ def selectdir(self):
+ """Take selected directory from the dirnamebox into the dirname"""
+ cs=self.component('dirnamebox').curselection()
+ if cs!=():
+ value=self.component('dirnamebox').get(cs)
+ dir=self['directory']
+ if not dir:
+ dir=os.getcwd()
+ if value:
+ if value=='..':
+ dir=os.path.split(dir)[0]
+ else:
+ dir=os.path.join(dir,value)
+ self.configure(directory=dir)
+ self.fillit()
+
+ def askfilename(self,directory=None,filter=None):
+ """The actual client function. Activates the dialog, and
+ returns only after a valid filename has been entered
+ (return value is that filename) or when canceled (return
+ value is None)"""
+ if directory!=None:
+ self.configure(directory=directory)
+ if filter!=None:
+ self.configure(filter=filter)
+ self.fillit()
+ self.canceled=1 # Needed for when user kills dialog window
+ self.activate()
+ if self.canceled:
+ return None
+ else:
+ return self.component('filename').get()
+
+ lastdir=""
+ lastfilter=None
+ lasttime=0
+ def fillit(self):
+ """Get the directory list and show it in the two listboxes"""
+ # Do not run unnecesarily
+ if self.lastdir==self['directory'] and self.lastfilter==self['filter'] and self.lasttime>os.stat(self.lastdir)[8]:
+ return
+ self.lastdir=self['directory']
+ self.lastfilter=self['filter']
+ self.lasttime=time.time()
+ dir=self['directory']
+ if not dir:
+ dir=os.getcwd()
+ dirs=['..']
+ files=[]
+ try:
+ fl=os.listdir(dir)
+ fl.sort()
+ except os.error,arg:
+ if arg[0] in (2,20):
+ return
+ raise
+ for f in fl:
+ if os.path.isdir(os.path.join(dir,f)):
+ dirs.append(f)
+ else:
+ filter=self['filter']
+ if not filter:
+ filter='*'
+ if fnmatch.fnmatch(f,filter):
+ files.append(f)
+ self.component('filenamebox').setlist(files)
+ self.component('dirnamebox').setlist(dirs)
+
+ def validate(self,filename):
+ """Validation function. Should return 1 if the filename is valid,
+ 0 if invalid. May pop up dialogs to tell user why. Especially
+ suited to subclasses: i.e. only return 1 if the file does/doesn't
+ exist"""
+ return 1
+
+class PmwDirDialog(PmwFileDialog):
+ """Directory Dialog using Pmw"""
+ def __init__(self, parent = None, **kw):
+ # Define the megawidget options.
+ optiondefs = (
+ ('directory', os.getcwd(), self.newdir),
+ ('historylen',10, None),
+ ('command', None, None),
+ ('info', None, None),
+ )
+ self.defineoptions(kw, optiondefs)
+ # Initialise base class (after defining options).
+ Pmw.Dialog.__init__(self, parent)
+
+ self.withdraw()
+
+ # Create the components.
+ interior = self.interior()
+
+ if self['info'] is not None:
+ rowoffset=1
+ dn = self.infotxt()
+ dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3)
+ else:
+ rowoffset=0
+
+ dn = self.mkdn()
+ dn.grid(row=1+rowoffset,column=0,columnspan=2,padx=3,pady=3)
+ dn.bind('',self.okbutton)
+ del dn
+
+ # Create the directory list component.
+ dnb = self.mkdnb()
+ dnb.grid(row=0+rowoffset,column=0,columnspan=2,sticky='news',padx=3,pady=3)
+ del dnb
+
+ # Buttonbox already exists
+ bb=self.component('buttonbox')
+ bb.add('OK',command=self.okbutton)
+ bb.add('Cancel',command=self.cancelbutton)
+ del bb
+
+ lastdir=""
+ def fillit(self):
+ """Get the directory list and show it in the two listboxes"""
+ # Do not run unnecesarily
+ if self.lastdir==self['directory']:
+ return
+ self.lastdir=self['directory']
+ dir=self['directory']
+ if not dir:
+ dir=os.getcwd()
+ dirs=['..']
+ try:
+ fl=os.listdir(dir)
+ fl.sort()
+ except os.error,arg:
+ if arg[0] in (2,20):
+ return
+ raise
+ for f in fl:
+ if os.path.isdir(os.path.join(dir,f)):
+ dirs.append(f)
+ self.component('dirnamebox').setlist(dirs)
+
+ def okbutton(self):
+ """OK action: user thinks he has input valid data and wants to
+ proceed. This is also called by in the dirname entry"""
+ fn=self.component('dirname').get()
+ self.configure(directory=fn)
+ if self.validate(fn):
+ self.canceled=0
+ self.deactivate()
+
+ def askfilename(self,directory=None):
+ """The actual client function. Activates the dialog, and
+ returns only after a valid filename has been entered
+ (return value is that filename) or when canceled (return
+ value is None)"""
+ if directory!=None:
+ self.configure(directory=directory)
+ self.fillit()
+ self.activate()
+ if self.canceled:
+ return None
+ else:
+ return self.component('dirname').get()
+
+ def dirvalidate(self,string):
+ if os.path.isdir(string):
+ return Pmw.OK
+ elif os.path.exists(string):
+ return Pmw.PARTIAL
+ else:
+ return Pmw.OK
+
+ def validate(self,filename):
+ """Validation function. Should return 1 if the filename is valid,
+ 0 if invalid. May pop up dialogs to tell user why. Especially
+ suited to subclasses: i.e. only return 1 if the file does/doesn't
+ exist"""
+ if filename=='':
+ _errorpop(self.interior(),"Empty filename")
+ return 0
+ if os.path.isdir(filename) or not os.path.exists(filename):
+ return 1
+ else:
+ _errorpop(self.interior(),"This is not a directory")
+ return 0
+
+class PmwExistingFileDialog(PmwFileDialog):
+ def filevalidate(self,string):
+ if os.path.isfile(string):
+ return Pmw.OK
+ else:
+ return Pmw.PARTIAL
+
+ def validate(self,filename):
+ if os.path.isfile(filename):
+ return 1
+ elif os.path.exists(filename):
+ _errorpop(self.interior(),"This is not a plain file")
+ return 0
+ else:
+ _errorpop(self.interior(),"Please select an existing file")
+ return 0
+
+class PmwExistingDirDialog(PmwDirDialog):
+ def dirvalidate(self,string):
+ if os.path.isdir(string):
+ return Pmw.OK
+ else:
+ return Pmw.PARTIAL
+
+ def validate(self,filename):
+ if os.path.isdir(filename):
+ return 1
+ elif os.path.exists(filename):
+ _errorpop(self.interior(),"This is not a directory")
+ return 0
+ else:
+ _errorpop(self.interior(),"Please select an existing directory")
+
+if __name__=="__main__":
+ root=Tkinter.Tk()
+ root.withdraw()
+ Pmw.initialise()
+
+ f0=PmwFileDialog(root)
+ f0.title('File name dialog')
+ n=f0.askfilename()
+ print '\nFilename : ',repr(n),'\n'
+
+ f1=PmwDirDialog(root,info='This is a directory dialog')
+ f1.title('Directory name dialog')
+ while 1:
+ n=f1.askfilename()
+ if n is None:
+ break
+ print "Dirname : ",repr(n)
diff --git a/Pmw/Pmw_1_2/contrib/PmwFullTimeCounter.py b/Pmw/Pmw_1_2/contrib/PmwFullTimeCounter.py
new file mode 100644
index 00000000..84e605a3
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/PmwFullTimeCounter.py
@@ -0,0 +1,492 @@
+# Authors: Joe VanAndel, Greg McFarlane and Daniel Michelson
+
+import string
+import sys
+import time
+import Tkinter
+import Pmw
+
+class FullTimeCounter(Pmw.MegaWidget):
+ """Up-down counter
+
+ A TimeCounter is a single-line entry widget with Up and Down arrows
+ which increment and decrement the Time value in the entry.
+ """
+
+ def __init__(self, parent = None, **kw):
+
+ # Define the megawidget options.
+ INITOPT = Pmw.INITOPT
+ optiondefs = (
+ ('autorepeat', 1, INITOPT),
+ ('buttonaspect', 1.0, INITOPT),
+ ('initwait', 300, INITOPT),
+ ('labelmargin', 0, INITOPT),
+ ('labelpos', None, INITOPT),
+ ('max', '', self._max),
+ ('min', '', self._min),
+ ('padx', 0, INITOPT),
+ ('pady', 0, INITOPT),
+ ('repeatrate', 50, INITOPT),
+ ('value', '', INITOPT),
+ )
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MegaWidget.__init__(self, parent)
+
+ self.arrowDirection = {}
+ self._flag = 'stopped'
+ self._timerId = None
+
+ self._createComponents()
+
+ value = self['value']
+ if value is None or value == '':
+ now = time.time()
+ value = time.strftime('%Y:%m:%d:%H:%M',time.gmtime(now))
+ self._setTimeFromStr(value)
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+ def _createComponents(self):
+
+ # Create the components.
+ interior = self.interior()
+
+ # If there is no label, put the arrows and the entry directly
+ # into the interior, otherwise create a frame for them. In
+ # either case the border around the arrows and the entry will
+ # be raised (but not around the label).
+ if self['labelpos'] is None:
+ frame = interior
+ else:
+ frame = self.createcomponent('frame',
+ (), None,
+ Tkinter.Frame, (interior,))
+ frame.grid(column=2, row=2, sticky='nsew')
+ interior.grid_columnconfigure(2, weight=1)
+ interior.grid_rowconfigure(2, weight=1)
+
+ frame.configure(relief = 'raised', borderwidth = 1)
+
+ # Create the down arrow buttons.
+
+ # Create the year down arrow.
+ self._downYearArrowBtn = self.createcomponent('downyeararrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._downYearArrowBtn] = 0
+ self._downYearArrowBtn.grid(column = 0, row = 2)
+
+ # Create the month down arrow.
+ self._downMonthArrowBtn = self.createcomponent('downmontharrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._downMonthArrowBtn] = 0
+ self._downMonthArrowBtn.grid(column = 1, row = 2)
+
+ # Create the day down arrow.
+ self._downDayArrowBtn = self.createcomponent('downdayarrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._downDayArrowBtn] = 0
+ self._downDayArrowBtn.grid(column = 2, row = 2)
+
+ # Create the hour down arrow.
+ self._downHourArrowBtn = self.createcomponent('downhourarrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._downHourArrowBtn] = 0
+ self._downHourArrowBtn.grid(column = 3, row = 2)
+
+ # Create the minute down arrow.
+ self._downMinuteArrowBtn = self.createcomponent('downminutearrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._downMinuteArrowBtn] = 0
+ self._downMinuteArrowBtn.grid(column = 4, row = 2)
+
+ # Create the entry fields.
+
+ # Create the year entry field.
+ self._yearCounterEntry = self.createcomponent('yearentryfield',
+ (('yearentry', 'yearentryfield_entry'),), None,
+ Pmw.EntryField, (frame,), validate='integer', entry_width = 4)
+ self._yearCounterEntry.grid(column = 0, row = 1, sticky = 'news')
+
+ # Create the month entry field.
+ self._monthCounterEntry = self.createcomponent('monthentryfield',
+ (('monthentry', 'monthentryfield_entry'),), None,
+ Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
+ self._monthCounterEntry.grid(column = 1, row = 1, sticky = 'news')
+
+ # Create the day entry field.
+ self._dayCounterEntry = self.createcomponent('dayentryfield',
+ (('dayentry', 'dayentryfield_entry'),), None,
+ Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
+ self._dayCounterEntry.grid(column = 2, row = 1, sticky = 'news')
+
+ # Create the hour entry field.
+ self._hourCounterEntry = self.createcomponent('hourentryfield',
+ (('hourentry', 'hourentryfield_entry'),), None,
+ Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
+ self._hourCounterEntry.grid(column = 3, row = 1, sticky = 'news')
+
+ # Create the minute entry field.
+ self._minuteCounterEntry = self.createcomponent('minuteentryfield',
+ (('minuteentry', 'minuteentryfield_entry'),), None,
+ Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
+ self._minuteCounterEntry.grid(column = 4, row = 1, sticky = 'news')
+
+ # Create the up arrow buttons.
+
+ # Create the year up arrow.
+ self._upYearArrowBtn = self.createcomponent('upyeararrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._upYearArrowBtn] = 1
+ self._upYearArrowBtn.grid(column = 0, row = 0)
+
+ # Create the month up arrow.
+ self._upMonthArrowBtn = self.createcomponent('upmontharrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._upMonthArrowBtn] = 1
+ self._upMonthArrowBtn.grid(column = 1, row = 0)
+
+ # Create the day up arrow.
+ self._upDayArrowBtn = self.createcomponent('updayarrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._upDayArrowBtn] = 1
+ self._upDayArrowBtn.grid(column = 2, row = 0)
+
+ # Create the hour up arrow.
+ self._upHourArrowBtn = self.createcomponent('uphourarrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._upHourArrowBtn] = 1
+ self._upHourArrowBtn.grid(column = 3, row = 0)
+
+ # Create the minute up arrow.
+ self._upMinuteArrowBtn = self.createcomponent('upminutearrow',
+ (), 'Arrow',
+ Tkinter.Canvas, (frame,),
+ width = 16, height = 16, relief = 'raised', borderwidth = 2)
+ self.arrowDirection[self._upMinuteArrowBtn] = 1
+ self._upMinuteArrowBtn.grid(column = 4, row = 0)
+
+ # Make it resize nicely.
+ padx = self['padx']
+ pady = self['pady']
+ for col in range(5): # YY, MM, DD, HH, mm
+ frame.grid_columnconfigure(col, weight = 1, pad = padx)
+ frame.grid_rowconfigure(0, pad = pady)
+ frame.grid_rowconfigure(2, pad = pady)
+
+ frame.grid_rowconfigure(1, weight = 1)
+
+ # Create the label.
+ self.createlabel(interior)
+
+ # Set bindings.
+
+ # Up year
+ self._upYearArrowBtn.bind('',
+ lambda event, s=self,button=self._upYearArrowBtn:
+ s._drawArrow(button, 1))
+ self._upYearArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._upYearArrowBtn:
+ s._countUp(button))
+ self._upYearArrowBtn.bind('',
+ lambda event, s=self, button=self._upYearArrowBtn:
+ s._stopUpDown(button))
+
+ # Up month
+ self._upMonthArrowBtn.bind('',
+ lambda event, s=self,button=self._upMonthArrowBtn:
+ s._drawArrow(button, 1))
+ self._upMonthArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._upMonthArrowBtn:
+ s._countUp(button))
+ self._upMonthArrowBtn.bind('',
+ lambda event, s=self, button=self._upMonthArrowBtn:
+ s._stopUpDown(button))
+
+ # Up day
+ self._upDayArrowBtn.bind('',
+ lambda event, s=self,button=self._upDayArrowBtn:
+ s._drawArrow(button, 1))
+ self._upDayArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._upDayArrowBtn:
+ s._countUp(button))
+ self._upDayArrowBtn.bind('',
+ lambda event, s=self, button=self._upDayArrowBtn:
+ s._stopUpDown(button))
+
+ # Up hour
+ self._upHourArrowBtn.bind('',
+ lambda event, s=self,button=self._upHourArrowBtn:
+ s._drawArrow(button, 1))
+ self._upHourArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._upHourArrowBtn:
+ s._countUp(button))
+ self._upHourArrowBtn.bind('',
+ lambda event, s=self, button=self._upHourArrowBtn:
+ s._stopUpDown(button))
+
+ # Up minute
+ self._upMinuteArrowBtn.bind('',
+ lambda event, s=self,button=self._upMinuteArrowBtn:
+ s._drawArrow(button, 1))
+ self._upMinuteArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._upMinuteArrowBtn:
+ s._countUp(button))
+ self._upMinuteArrowBtn.bind('',
+ lambda event, s=self, button=self._upMinuteArrowBtn:
+ s._stopUpDown(button))
+
+
+ # Down year
+ self._downYearArrowBtn.bind('',
+ lambda event, s=self,button=self._downYearArrowBtn:
+ s._drawArrow(button, 0))
+ self._downYearArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._downYearArrowBtn:
+ s._countDown(button))
+ self._downYearArrowBtn.bind('',
+ lambda event, s=self, button=self._downYearArrowBtn:
+ s._stopUpDown(button))
+
+ # Down month
+ self._downMonthArrowBtn.bind('',
+ lambda event, s=self,button=self._downMonthArrowBtn:
+ s._drawArrow(button, 0))
+ self._downMonthArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._downMonthArrowBtn:
+ s._countDown(button))
+ self._downMonthArrowBtn.bind('',
+ lambda event, s=self, button=self._downMonthArrowBtn:
+ s._stopUpDown(button))
+
+ # Down day
+ self._downDayArrowBtn.bind('',
+ lambda event, s=self,button=self._downDayArrowBtn:
+ s._drawArrow(button, 0))
+ self._downDayArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._downDayArrowBtn:
+ s._countDown(button))
+ self._downDayArrowBtn.bind('',
+ lambda event, s=self, button=self._downDayArrowBtn:
+ s._stopUpDown(button))
+
+ # Down hour
+ self._downHourArrowBtn.bind('',
+ lambda event, s=self,button=self._downHourArrowBtn:
+ s._drawArrow(button, 0))
+ self._downHourArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._downHourArrowBtn:
+ s._countDown(button))
+ self._downHourArrowBtn.bind('',
+ lambda event, s=self, button=self._downHourArrowBtn:
+ s._stopUpDown(button))
+
+ # Down minute
+ self._downMinuteArrowBtn.bind('',
+ lambda event, s=self,button=self._downMinuteArrowBtn:
+ s._drawArrow(button, 0))
+ self._downMinuteArrowBtn.bind('<1>',
+ lambda event, s=self,button=self._downMinuteArrowBtn: s._countDown(button))
+ self._downMinuteArrowBtn.bind('',
+ lambda event, s=self, button=self._downMinuteArrowBtn:
+ s._stopUpDown(button))
+
+
+ self._yearCounterEntry.bind('', self.invoke)
+ self._monthCounterEntry.bind('', self.invoke)
+ self._dayCounterEntry.bind('', self.invoke)
+ self._hourCounterEntry.bind('', self.invoke)
+ self._minuteCounterEntry.bind('', self.invoke)
+
+ self._yearCounterEntry.bind('', self._resizeArrow)
+ self._monthCounterEntry.bind('', self._resizeArrow)
+ self._dayCounterEntry.bind('', self._resizeArrow)
+ self._hourCounterEntry.bind('', self._resizeArrow)
+ self._minuteCounterEntry.bind('', self._resizeArrow)
+
+ def _drawArrow(self, arrow, direction):
+ arrow.delete('arrow')
+
+ fg = self._yearCounterEntry.cget('entry_foreground')
+
+ bw = (string.atoi(arrow['borderwidth']) +
+ string.atoi(arrow['highlightthickness'])) / 2
+ h = string.atoi(arrow['height']) + 2 * bw
+ w = string.atoi(arrow['width']) + 2 * bw
+
+ if direction == 0:
+ # down arrow
+ arrow.create_polygon(
+ 0.25 * w + bw, 0.25 * h + bw,
+ 0.50 * w + bw, 0.75 * h + bw,
+ 0.75 * w + bw, 0.25 * h + bw,
+ fill=fg, tag='arrow')
+ else:
+ arrow.create_polygon(
+ 0.25 * w + bw, 0.75 * h + bw,
+ 0.50 * w + bw, 0.25 * h + bw,
+ 0.75 * w + bw, 0.75 * h + bw,
+ fill=fg, tag='arrow')
+
+ def _resizeArrow(self, event = None):
+ for btn in (self._upYearArrowBtn, self._upMonthArrowBtn,
+ self._upDayArrowBtn, self._upHourArrowBtn,
+ self._upMinuteArrowBtn, self._downYearArrowBtn,
+ self._downMonthArrowBtn, self._downDayArrowBtn,
+ self._downHourArrowBtn, self._downMinuteArrowBtn):
+ bw = (string.atoi(btn['borderwidth']) + \
+ string.atoi(btn['highlightthickness']))
+ newHeight = self._yearCounterEntry.winfo_reqheight() - 2 * bw
+ newWidth = newHeight * self['buttonaspect']
+ btn.configure(width=newWidth, height=newHeight)
+ self._drawArrow(btn, self.arrowDirection[btn])
+
+ def _min(self):
+ self._minVal = None
+
+ def _max(self):
+ self._maxVal = None
+
+ def _setTimeFromStr(self, str):
+ list = string.split(str, ':')
+ if len(list) != 5:
+ raise ValueError, 'invalid value: ' + str
+
+ self._year = string.atoi(list[0])
+ self._month = string.atoi(list[1])
+ self._day = string.atoi(list[2])
+ self._hour = string.atoi(list[3])
+ self._minute = string.atoi(list[4])
+
+ self._setHMS()
+
+ def getstring(self):
+ return '%04d:%02d:%02d:%02d:%02d' % (self._year, self._month,
+ self._day, self._hour,
+ self._minute)
+
+ def getint(self):
+ pass
+
+ def _countUp(self, button):
+ self._relief = self._upYearArrowBtn.cget('relief')
+ button.configure(relief='sunken')
+ if button == self._upYearArrowBtn: datetype = "year"
+ elif button == self._upMonthArrowBtn: datetype = "month"
+ elif button == self._upDayArrowBtn: datetype = "day"
+ elif button == self._upHourArrowBtn: datetype = "hour"
+ elif button == self._upMinuteArrowBtn: datetype = "minute"
+ self._count(1, datetype, 'start')
+
+ def _countDown(self, button):
+ self._relief = self._downYearArrowBtn.cget('relief')
+ button.configure(relief='sunken')
+ if button == self._downYearArrowBtn: datetype = "year"
+ elif button == self._downMonthArrowBtn: datetype = "month"
+ elif button == self._downDayArrowBtn: datetype = "day"
+ elif button == self._downHourArrowBtn: datetype = "hour"
+ elif button == self._downMinuteArrowBtn: datetype = "minute"
+ self._count(-1, datetype, 'start')
+
+ def _count(self, factor, datetype, newFlag=None):
+ if newFlag != 'force':
+ if newFlag is not None:
+ self._flag = newFlag
+
+ if self._flag == 'stopped':
+ return
+
+ if datetype == "year": self._year = self._year + factor
+ elif datetype == "month": self._month = self._month + factor
+ elif datetype == "day": self._day = self._day + factor
+ elif datetype == "hour": self._hour = self._hour + factor
+ elif datetype == "minute": self._minute = self._minute + factor
+ secs = time.mktime((self._year, self._month, self._day, self._hour,
+ self._minute, 0, 0, 0, -1))
+ tt = time.localtime(secs) # NOT gmtime!
+
+ self._year = tt[0]
+ self._month = tt[1]
+ self._day = tt[2]
+ self._hour = tt[3]
+ self._minute = tt[4]
+ self._setHMS()
+
+ if newFlag != 'force':
+ if self['autorepeat']:
+ if self._flag == 'start':
+ delay = self['initwait']
+ self._flag = 'running'
+ else:
+ delay = self['repeatrate']
+ self._timerId = self.after(
+ delay, lambda self=self, factor=factor, datetype=datetype:
+ self._count(factor, datetype, 'running'))
+
+ def _setHMS(self):
+ self._yearCounterEntry.setentry('%04d' % self._year)
+ self._monthCounterEntry.setentry('%02d' % self._month)
+ self._dayCounterEntry.setentry('%02d' % self._day)
+ self._hourCounterEntry.setentry('%02d' % self._hour)
+ self._minuteCounterEntry.setentry('%02d' % self._minute)
+
+ def _stopUpDown(self, button):
+ if self._timerId is not None:
+ self.after_cancel(self._timerId)
+ self._timerId = None
+ button.configure(relief=self._relief)
+ self._flag = 'stopped'
+
+ def invoke(self, event = None):
+ cmd = self['command']
+ if callable(cmd):
+ cmd()
+
+ def destroy(self):
+ if self._timerId is not None:
+ self.after_cancel(self._timerId)
+ self._timerId = None
+ Pmw.MegaWidget.destroy(self)
+
+if __name__=="__main__":
+
+ def showString():
+ stringVal = _time.getstring()
+ print stringVal
+
+ root = Tkinter.Tk()
+ Pmw.initialise(root)
+ root.title('FullTimeCounter')
+
+ exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy)
+ exitButton.pack(side = 'bottom')
+
+ _time = FullTimeCounter(root,
+ labelpos = 'n',
+ label_text = 'YYYY:MM:DD:HH:mm')
+ _time.pack(fill = 'both', expand = 1, padx=10, pady=5)
+
+ button = Tkinter.Button(root, text = 'Show', command = showString)
+ button.pack()
+ root.mainloop()
diff --git a/Pmw/Pmw_1_2/contrib/PmwVerticalGauge.py b/Pmw/Pmw_1_2/contrib/PmwVerticalGauge.py
new file mode 100644
index 00000000..b413f937
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/PmwVerticalGauge.py
@@ -0,0 +1,253 @@
+"""
+I needed a simple gauge, so I've made on with Pmw.
+It might be useful for others to use as a base to develop more comples
+gauges with.
+
+Is it worth cleaning up and submitting?
+
+cheers and thanks
+
+chris
+
+Dr. Chris Wright
+Intensive Care Unit
+Monash Medical Centre
+Clayton. VIC Australia
+"""
+
+import sys
+import Tkinter
+import Pmw
+import time
+
+
+if sys.platform == 'win32':
+ # MS-Windows specific fonts
+ label_font = "-family Ariel -size 12"
+ value_font = "-family Ariel -size 12"
+ small_font = "-family {MS Sans Serif} -size 9 -weight bold"
+ header_font = "-family {MS Sans Serif} -weight bold"
+else:
+ # X-Windows specific fonts
+ label_font = "-*-helvetica-*-r-*-*-*-160-*-*-*-*-*-*"
+ value_font = "-*-courier-*-r-*-*-*-160-*-*-*-*-*-*"
+ small_font = "-*-helvetica-*-r-*-*-*-130-*-*-*-*-*-*"
+ header_font = "-*-helvetica-bold-r-*-*-*-150-*-*-*-*-*-*"
+
+class VerticalGauge(Pmw.MegaWidget):
+ """Vertical gauge with actual and desired settings"""
+
+ def __init__(self, parent = None, **kw):
+ optiondefs = (
+ ('min', 0, None),
+ ('max', 100, None),
+ ('majortickinterval', 10, None),
+ ('minortickinterval', 5, None),
+ ('units', '', None),
+ ('bg', 'grey', self._backgroundSet),
+ ('actualvalue', 50, self._actualSet),
+ ('desiredvalue', 50, self._desiredSet),
+ ('actualcolour', 'yellow1', None),
+ ('desiredcolour', 'turquoise1', None),
+ ('label', 'Label', None),
+ )
+ self.defineoptions(kw, optiondefs)
+ Pmw.MegaWidget.__init__(self, parent)
+
+ interior = self.interior()
+ interior.grid_rowconfigure(1, weight = 1)
+ for r in range(3):
+ interior.grid_columnconfigure(r, weight = 1)
+
+ self.actuallabel = self.createcomponent('actualLabel',
+ (), None,
+ Tkinter.Label, (interior,),
+ text = '',
+ width = 3,
+ relief = 'sunken',
+ bd = 1,
+ fg = self['actualcolour'],
+ font = value_font)
+ self.actuallabel.grid(sticky = "nswe", row = 0, column = 0)
+
+ self.label = self.createcomponent('label',
+ (), None,
+ Tkinter.Label, (interior,),
+ text = self['label'],
+ relief = 'raised',
+ font = label_font,
+ fg = 'navy',
+ bd = 2)
+ self.label.grid(sticky = "nsew", row = 0, column = 1)
+
+ self.desiredlabel = self.createcomponent('desiredLabel',
+ (), None,
+ Tkinter.Label, (interior,),
+ text = '',
+ width = 3,
+ relief = 'sunken',
+ bd = 1,
+ fg = self['desiredcolour'],
+ font = value_font)
+ self.desiredlabel.grid(sticky = "nswe", row = 0, column = 2)
+
+ self.canvas = self.createcomponent('canvas',
+ (), None,
+ Tkinter.Canvas, (interior,),
+ width = 100,
+ height = 300,
+ bg = 'grey')
+
+ self.canvas.grid(sticky = "nsew", columnspan = 3, pady = 1)
+ self.canvas.bind("", self._createGaugeAxes)
+
+ self._createGaugeAxes()
+
+ self.initialiseoptions()
+
+ def _createGaugeAxes(self, event = None):
+ min = self['min']
+ max = self['max']
+ units = self['units']
+ majortickinterval = self['majortickinterval']
+
+ gauge_range = max - min
+
+ c = self.canvas
+ c.delete("all")
+ if event:
+ h, w = event.height, event.width
+ else:
+ h = int(c.configure("height")[4])
+ w = int(c.configure("width")[4])
+
+ self.lower = h - 15
+ self.upper = 15
+ self.middle = w / 2
+ c.create_line(self.middle, self.lower, self.middle, self.upper)
+
+ majortickcount = int((max - min) / majortickinterval)
+ self.axislength = self.lower - self.upper
+ self.majortickdistance = float(self.axislength) / majortickcount
+ self.majortickwidth = w / 5
+ labeloffset = (w / 4) + 10
+
+ for i in range(majortickcount + 1):
+ v = min + i * majortickinterval
+ d = self.lower - i * self.majortickdistance
+ c.create_line(self.middle, d, self.middle + self.majortickwidth, d)
+ c.create_text(self.middle + labeloffset, d, font = small_font, text = str(v))
+
+ self._desiredSet(event)
+ self._actualSet(event)
+
+ def _backgroundSet(self):
+ self.canvas.configure(bg = self['bg'])
+
+ def _desiredSet(self, event = None):
+ c = self.canvas
+ desired = self['desiredvalue']
+ desiredcolour = self['desiredcolour']
+
+ min = self['min']
+ max = self['max']
+
+ if desired > max: desired = max
+ if desired < min: desired = min
+ gauge_range = max - min
+
+ c = self.canvas
+ if event:
+ h, w = event.height, event.width
+ else:
+ h = int(c.configure("height")[4])
+ w = int(c.configure("width")[4])
+
+
+ desired_y = self.lower - (float(desired - min) / gauge_range) * self.axislength
+
+ try:
+ c.delete('desiredBar')
+ except:
+ pass
+
+ c.create_line(self.middle - self.majortickwidth, desired_y,
+ self.middle + self.majortickwidth, desired_y,
+ fill = desiredcolour, stipple = 'gray50',
+ width = 10, tag = 'desiredBar')
+ self.desiredlabel.configure(text = desired)
+
+ def setActual(self, value):
+ self.configure(actualvalue = value)
+
+ def getActual(self):
+ return self.cget('actualvalue')
+
+ def _actualSet(self, event = None):
+ c = self.canvas
+ actual = self['actualvalue']
+ actualcolour = self['actualcolour']
+
+ min = self['min']
+ max = self['max']
+
+ if actual > max: actual = max
+ if actual < min: actual = min
+ gauge_range = max - min
+
+ c = self.canvas
+ if event:
+ h, w = event.height, event.width
+ else:
+ h = int(c.configure("height")[4])
+ w = int(c.configure("width")[4])
+
+ actual_y = self.lower - (float(actual - min) / gauge_range) * self.axislength
+
+ try:
+ c.delete('actualPointer')
+ except:
+ pass
+
+ triangle = ((self.middle, actual_y),
+ (self.middle - 1.4 * self.majortickwidth, actual_y - self.majortickwidth / 2),
+ (self.middle - 1.4 * self.majortickwidth, actual_y + self.majortickwidth / 2))
+
+ c.create_polygon(triangle, fill = actualcolour, tag = 'actualPointer')
+ self.actuallabel.configure(text = actual)
+
+
+Pmw.forwardmethods(VerticalGauge, Tkinter.Canvas, 'canvas')
+
+if __name__ == '__main__':
+
+
+ # Initialise Tkinter and Pmw.
+ root = Pmw.initialise()
+ root.title('Pmw VerticalGauge demonstration')
+
+
+ def increase():
+ av = g1.getActual()
+ g1.setActual(av + 1)
+
+ def decrease():
+ av = g1.getActual()
+ g1.setActual(av - 1)
+
+ g1 = VerticalGauge(min = 0,
+ max = 30,
+ actualvalue = 15,
+ desiredvalue = 22,
+ majortickinterval = 2,
+ label = "Pms")
+ g1.grid(sticky = "nsew")
+ root.grid_rowconfigure(0, weight = 1)
+ root.grid_columnconfigure(0, weight = 1)
+ b1 = Tkinter.Button(text = "Increase", command = increase)
+ b1.grid()
+ b2 = Tkinter.Button(text = "Decrease", command = decrease)
+ b2.grid()
+
+ # Let's go.
+ root.mainloop()
diff --git a/Pmw/Pmw_1_2/contrib/README b/Pmw/Pmw_1_2/contrib/README
new file mode 100644
index 00000000..2662f77e
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/README
@@ -0,0 +1,10 @@
+This directory contains contributed Pmw megawidgets.
+
+DirBrowser.py directory selection dialog
+MCListbox.py multi-column selectable listbox
+PmwFileDialog.py file selection dialog
+PmwFullTimeCounter.py time counter which includes year, month and day
+PmwVerticalGauge.py a simple gauge indicating a value and a threshold
+TreeBrowser.py generic hierarchical tree browser
+
+Each file can be executed and will display a demo of its megawidget.
diff --git a/Pmw/Pmw_1_2/contrib/TreeBrowser.py b/Pmw/Pmw_1_2/contrib/TreeBrowser.py
new file mode 100644
index 00000000..6d9fe89a
--- /dev/null
+++ b/Pmw/Pmw_1_2/contrib/TreeBrowser.py
@@ -0,0 +1,732 @@
+#
+# FILE: TreeBrowser.py
+#
+# DESCRIPTION:
+# This file provides a generic hierarchical tree browser widget.
+#
+# AUTHOR: Steve Kinneberg ,
+# MontaVista Software, Inc.
+
+
+
+
+
applicationname
+
+Initialisation option. The name of application, to be dispayed in the dialog body and in
+ the window title if the title option is not given. The default is ''.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the text message and icon. The default is 20.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the text message and icon. The default is 20.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('Close',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is 0.
+
+
+
+
+
iconmargin
+
+Initialisation option. The padding between the text message and icon. The default is 20.
+
+
+
+
+
iconpos
+
+Initialisation option. Specifies on which side of the text message to place the icon.
+ Must be one of 'n', 's', 'e' or 'w'. The default is 'w'.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
icon
+
+If the iconpos option is not None, this component is created
+ to contain the icon label for the dialog. To display a bitmap as
+ an icon, set the icon_bitmap component option to any of the
+ forms acceptable to Tk, such as 'warning' or 'error'. By default, this component is a Tkinter.Label.
+
+
+
+
+
message
+
+The label to contain the text message for the dialog. To set
+ the text, use the message_text component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
+
Methods
+This megawidget has no methods of its own.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MessageDialog.
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create dialog.
+ Pmw.aboutversion('9.9')
+ Pmw.aboutcopyright('Copyright My Company 1999\nAll rights reserved')
+ Pmw.aboutcontact(
+ 'For information about this application contact:\n' +
+ ' My Help Desk\n' +
+ ' Phone: +61 2 9876 5432\n' +
+ ' email: help@my.company.com.au'
+ )
+ self.about = Pmw.AboutDialog(parent, applicationname = 'My Application')
+ self.about.withdraw()
+
+ # Create button to launch the dialog.
+ w = Tkinter.Button(parent, text = 'Show about dialog',
+ command = self.execute)
+ w.pack(padx = 8, pady = 8)
+
+ def execute(self):
+ self.about.show()
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ A balloon megawidget can be used to give short help messages to
+ the user when they place the mouse over a button or other widget
+ for a short time. It can also be used to display help messages
+ for canvas or text items.
+
+
One balloon megawidget can be used to display help for many
+ widgets or items. For each widget or item that requires balloon
+ help, the bind() or bindtag() method is used to specify the
+ help text that should be displayed.
+
+
The help message is displayed in a popup balloon window when the
+ mouse remains over the widget or item for a short time. The popup
+ balloon is withdrawn when the mouse leaves the widget or item, or
+ any mouse buttons are pressed.
+
+
The position of the popup balloon is configurable and may appear
+ either relative to the widget or item or relative to the position
+ of the mouse.
+
+
The popup balloon is displayed without any window manager
+ decorations.
+
+
The megawidget can cooperate with a Pmw.MessageBar to display a
+ single-line help message as well as the balloon help.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
initwait
+
+The number of milliseconds delay between when the mouse enters a
+ widget or item and when the popup balloon window should be
+ displayed. The default is 500.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
relmouse
+
+This may be one of 'both', 'x', 'y' or 'none' and
+ indicates that the top left corner of the popup balloon window
+ should be placed relative to the current position of the mouse
+ rather than relative to the bottom left corner of the widget or
+ item (the default). The positioning may be set for the horizontal
+ (x) and vertical (y) axes independently. The default is 'none'.
+
+
+
+
+
state
+
+This may be one of 'both', 'balloon', 'status' or 'none'
+ and indicates whether the help message should be displayed in the
+ popup balloon window, in an associated messagebar (via the
+ statuscommand option), or both. The default is 'both'.
+
+
+
+
+
statuscommand
+
+This specifies a function to call when the mouse enters a widget
+ or item bound to this balloon megawidget. To configure a
+ Pmw.MessageBar to display help, set this option to the helpmessage
+ method of the messagebar. The default is None.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
xoffset
+
+This specifies the horizontal offset of the position of the left
+ side of the popup balloon window relative the point determined by
+ the relmouse option. The default is 20.
+
+
+
+
+
yoffset
+
+This specifies the vertical offset of the position of the top of
+ the popup balloon window relative the point determined by the
+ relmouse option. The default is 1.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
label
+
+This component displays the text of the help message in the popup
+ balloon window. By default it is created with a 'lightyellow'
+ background, a 'black' foreground and is 'left' justified. By default, this component is a Tkinter.Label.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaToplevel.
+
+
+
bind(widget, balloonHelp, statusHelp = None)
+Create bindings for widget so that balloon help and/or status
+ help is displayed when the mouse enters the widget. The balloon
+ help message is given by balloonHelp and the status help message
+ is given by statusHelp. If balloonHelp is None, no balloon
+ is displayed. If statusHelp is not set, it defaults to
+ balloonHelp. Any previous bindings for this widget are removed.
+
+
+
+
+
clearstatus()
+Clear the text in the associated messagebar by passing None to
+ the statuscommand function.
+
+
+
+
+
showstatus(statusHelp)
+Set the text in the associated messagebar by passing statusHelp
+ to the statuscommand function.
+
+
+
+Create bindings for the tag or item specified by tagOrItem in
+ the text or canvas widget so that balloon help and/or status
+ help is displayed when the mouse enters the tag or item. The
+ balloon help message is given by balloonHelp and the status help
+ message is given by statusHelp. If balloonHelp is None, no
+ balloon is displayed. If statusHelp is not set, it defaults to
+ balloonHelp. Any previous bindings for this tag or item are
+ removed.
+
+
+
+
+
tagunbind(widget, tagOrItem)
+Remove the balloon help bindings from the tag or item specified by
+ tagOrItem in the text or canvas widget.
+
Note that tagunbind() must be called when deleting a canvas
+ item, so that the popup balloon window can be withdrawn if it was
+ triggered by the item. (Unfortunately this can not be automated
+ as is done for widgets since Tk does not support <Destroy>
+ bindings on canvas items, so there is no way that Pmw.Balloon can
+ be notified of the deletion of an item.)
+
+
+
+
+
+
unbind(widget)
+Remove the balloon help bindings from widget.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the Balloon.
+ self.balloon = Pmw.Balloon(parent)
+
+ # Create some widgets and megawidgets with balloon help.
+ frame = Tkinter.Frame(parent)
+ frame.pack(padx = 10, pady = 5)
+ field = Pmw.EntryField(frame,
+ labelpos = 'nw',
+ label_text = 'Command:')
+ field.setentry('mycommand -name foo')
+ field.pack(side = 'left', padx = 10)
+ self.balloon.bind(field, 'Command to\nstart/stop',
+ 'Enter the shell command to control')
+
+ start = Tkinter.Button(frame, text='Start')
+ start.pack(side='left', padx = 10)
+ self.balloon.bind(start, 'Start the command')
+
+ stop = Tkinter.Button(frame, text='Stop')
+ stop.pack(side='left', padx = 10)
+ self.balloon.bind(stop, 'Stop the command')
+
+ self.suicide = Tkinter.Button(frame, text='Kill me soon!',
+ command = self.killButton)
+ self.suicide.pack(side='left', padx = 10)
+ self.balloon.bind(self.suicide, 'Watch this button disappear!')
+
+ scrolledCanvas = Pmw.ScrolledCanvas(parent,
+ canvas_width = 300,
+ canvas_height = 115,
+ )
+ scrolledCanvas.pack()
+ canvas = scrolledCanvas.component('canvas')
+ self.canvas = canvas
+
+ # Create some canvas items and individual help.
+ item = canvas.create_arc(5, 5, 35, 35, fill = 'red', extent = 315)
+ self.balloon.tagbind(canvas, item, 'This is help for\nan arc item')
+ item = canvas.create_bitmap(20, 150, bitmap = 'question')
+ self.balloon.tagbind(canvas, item, 'This is help for\na bitmap')
+ item = canvas.create_line(50, 60, 70, 80, 85, 20, width = 5)
+ self.balloon.tagbind(canvas, item, 'This is help for\na line item')
+ item = canvas.create_text(10, 90, text = 'Canvas items with balloons',
+ anchor = 'nw', font = field.cget('entry_font'))
+ self.balloon.tagbind(canvas, item, 'This is help for\na text item')
+
+ # Create two canvas items which have the same tag and which use
+ # the same help.
+ canvas.create_rectangle(100, 10, 170, 50, fill = 'aliceblue',
+ tags = 'TAG1')
+ self.bluecircle = canvas.create_oval(110, 30, 160, 80, fill = 'blue',
+ tags = 'TAG1')
+ self.balloon.tagbind(canvas, 'TAG1',
+ 'This is help for the two blue items' + '\n' * 10 +
+ 'It is very, very big.',
+ 'This is help for the two blue items')
+ item = canvas.create_text(180, 10, text = 'Delete',
+ anchor = 'nw', font = field.cget('entry_font'))
+ self.balloon.tagbind(canvas, item,
+ 'After 2 seconds,\ndelete the blue circle')
+ canvas.tag_bind(item, '<ButtonPress>', self._canvasButtonpress)
+ scrolledCanvas.resizescrollregion()
+
+ scrolledText = Pmw.ScrolledText(parent,
+ text_width = 32,
+ text_height = 4,
+ text_wrap = 'none',
+ )
+ scrolledText.pack(pady = 5)
+ text = scrolledText.component('text')
+ self.text = text
+
+ text.insert('end',
+ 'This is a text widget with ', '',
+ ' balloon', 'TAG1',
+ '\nhelp. Find the ', '',
+ ' text ', 'TAG1',
+ ' tagged with', '',
+ ' help.', 'TAG2',
+ '\n', '',
+ 'Remove tag 1.', 'TAG3',
+ '\nAnother line.\nAnd another', '',
+ )
+ text.tag_configure('TAG1', borderwidth = 2, relief = 'sunken')
+ text.tag_configure('TAG3', borderwidth = 2, relief = 'raised')
+
+ self.balloon.tagbind(text, 'TAG1',
+ 'There is one secret\nballoon help.\nCan you find it?')
+ self.balloon.tagbind(text, 'TAG2',
+ 'Well done!\nYou found it!')
+ self.balloon.tagbind(text, 'TAG3',
+ 'After 2 seconds\ndelete the tag')
+ text.tag_bind('TAG3', '<ButtonPress>', self._textButtonpress)
+
+ frame = Tkinter.Frame(parent)
+ frame.pack(padx = 10)
+ self.toggleBalloonVar = Tkinter.IntVar()
+ self.toggleBalloonVar.set(1)
+ toggle = Tkinter.Checkbutton(frame,
+ variable = self.toggleBalloonVar,
+ text = 'Balloon help', command = self.toggle)
+ toggle.pack(side = 'left', padx = 10)
+ self.balloon.bind(toggle, 'Toggle balloon help\non and off')
+
+ self.toggleStatusVar = Tkinter.IntVar()
+ self.toggleStatusVar.set(1)
+ toggle = Tkinter.Checkbutton(frame,
+ variable = self.toggleStatusVar,
+ text = 'Status help', command = self.toggle)
+ toggle.pack(side = 'left', padx = 10)
+ self.balloon.bind(toggle,
+ 'Toggle status help on and off, on and off' + '\n' * 10 +
+ 'It is very, very big, too.',
+ 'Toggle status help on and off')
+
+ # Create and pack the MessageBar.
+ messageBar = Pmw.MessageBar(parent,
+ entry_width = 40,
+ entry_relief='groove',
+ labelpos = 'w',
+ label_text = 'Status:')
+ messageBar.pack(fill = 'x', expand = 1, padx = 10, pady = 5)
+
+ # Configure the balloon to display its status messages in the
+ # message bar.
+ self.balloon.configure(statuscommand = messageBar.helpmessage)
+
+ def toggle(self):
+ if self.toggleBalloonVar.get():
+ if self.toggleStatusVar.get():
+ self.balloon.configure(state = 'both')
+ else:
+ self.balloon.configure(state = 'balloon')
+ else:
+ if self.toggleStatusVar.get():
+ self.balloon.configure(state = 'status')
+ else:
+ self.balloon.configure(state = 'none')
+
+ def killButton(self):
+ # Test for old bug when destroying widgets 1) while the
+ # balloon was up and 2) during the initwait period.
+ print 'Destroying button in 2 seconds'
+ self.suicide.after(2000, self.suicide.destroy)
+
+ def _canvasButtonpress(self, event):
+ print 'Destroying blue circle in 2 seconds'
+ self.canvas.after(2000, self.deleteBlueCircle)
+
+ def deleteBlueCircle(self):
+ self.balloon.tagunbind(self.canvas, self.bluecircle)
+ self.canvas.delete(self.bluecircle)
+
+ def _textButtonpress(self, event):
+ print 'Deleting the text tag in 2 seconds'
+ self.text.after(2000, self.deleteTextTag)
+
+ def deleteTextTag(self):
+ self.balloon.tagunbind(self.text, 'TAG1')
+ self.text.tag_delete('TAG1')
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 20 May 2002
+
Pmw.Blt -
+ interface to some BLT widgets and commands
+
+
+
+
+
+
Description
+
+ This module contains function interfaces to the BLT busy command
+ as well as the classes Pmw.Blt.Vector, Pmw.Blt.Graph,
+ Pmw.Blt.Stripchart and Pmw.Blt.Tabset, which are interfaces to
+ the vector, graph, stripchart and tabset commands of version 2.4
+ of the BLT extension to Tk. The interfaces are complete except
+ for Pmw.Blt.Vector where several creation options, methods and
+ operations have not been implemented.
+
+
The blt graph and barchart widgets are essentially the same and so
+ only the graph widget has been ported. The element_create()
+ method is not implememted for Pmw.Blt.Graph, so instead:
+
to create a line element, use the line_create() method and
+
+
+
to create a bar element, use the bar_create() method.
+
+
+
+
To operate on elements, use the element_*() methods, such as
+ element_bind(), element_activate(), etc.
+
+
Note: Full documentation of Pmw.Blt.Graph is available in
+ A User's Guide to Pmw.Blt
+ written by Bjørn Ove Thue and Hans Petter Langtangen.
+ You can also download
+ the full HTML document
+ of the guide for local viewing.
+
+
+
+
+
+
Functions
+The following functions are available.
+
+
Pmw.Blt.busy_forget(window)
+
+ Interface to the BLT busy forget command.
+
+
+
+
+
+
Pmw.Blt.busy_hold(window, cursor = None)
+
+ Interface to the BLT busy hold command.
+
+
+
+
+
+
Pmw.Blt.busy_release(window)
+
+ Interface to the BLT busy release command.
+
+
+
+
+
+
Pmw.Blt.haveblt(window)
+
+ Return true if any commands in the BLT extension are available.
+
+
+
+
+
+
Pmw.Blt.havebltbusy(window)
+
+ Return true if the BLT busy command is available.
+
+
+
+
+
+
Pmw.Blt.vector_expr(expression)
+
+ Interface to the BLT vector expr command.
+
+
+
+
+
+
Pmw.Blt.vector_names(pattern = None)
+
+ Interface to the BLT vector names command.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 25 May 2002
+
+ A button box is a container megawidget which manages a number of
+ buttons. One of these buttons may be specified as the default and
+ it will be displayed with the platform specific appearance for a
+ default button. The buttons may be laid out either horizontally
+ or vertically.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
orient
+
+Initialisation option. Specifies the orientation of the button box. This may be
+ 'horizontal' or 'vertical'. The default is 'horizontal'.
+
+
+
+
+
padx
+
+Initialisation option. Specifies a padding distance to leave between each button in the x
+ direction and also between the buttons and the outer edge of the
+ button box. The default is 3.
+
+
+
+
+
pady
+
+Initialisation option. Specifies a padding distance to leave between each button in the y
+ direction and also between the buttons and the outer edge of the
+ button box. The default is 3.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
frame
+
+If the label component has been created (that is, the labelpos
+ option is not None), the frame component is created to act as
+ the container of the buttons created by the add() and
+ insert() methods. If there is no label component, then no
+ frame component is created and the hull component acts as the
+ container. By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
Dynamic components
+
+ Button components are created dynamically by the add() and
+ insert() methods. By default, the buttons are of type
+ Tkinter.Button and are created with a component group of
+ Button.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
add(componentName, **kw)
+Add a button to the end of the button box as a component named
+ componentName. Any keyword arguments present will be passed to the
+ constructor when creating the button. If the text keyword
+ argument is not given, the text option of the button defaults to
+ componentName. The method returns the component widget.
+
+
+
+
+
alignbuttons(when = 'later')
+Set the widths of all the buttons to be the same as the width of
+ the widest button. If when is 'later', this will occur when the
+ interpreter next becomes idle, otherwise the resizing will occur
+ immediately.
+
+
+
+
+
button(buttonIndex)
+Return the button specified by buttonIndex, which may have any
+ of the forms accepted by the index() method.
+
+
+
+
+
delete(index)
+Delete the button given by index from the button box. index
+ may have any of the forms accepted by the index() method.
+
+
+
+
+
index(index, forInsert = 0)
+Return the numerical index of the button corresponding to index.
+ This may be specified in any of the following forms:
+
name
Specifies the button named name.
+
+
+
number
Specifies the button numerically, where 0 corresponds to
+ the left (or top) button.
+
+
+
Pmw.END
Specifies the right (or bottom) button.
+
+
+
Pmw.DEFAULT
Specifies the current default button.
+
+
+
If forInsert is true, Pmw.END returns the number of buttons rather
+ than the index of the last button.
+
+
+
+
+
+
insert(componentName, beforeComponent = 0, **kw)
+Add a button to the button box as a component named
+ componentName. The button is added just before the button
+ specified by beforeComponent, which may have any of the forms
+ accepted by the index() method. Any keyword arguments present
+ will be passed to the constructor when creating the button. If
+ the text keyword argument is not given, the text option of the
+ button defaults to componentName. To add a button to the end of
+ the button box, use add(). The method returns the component
+ widget.
+
+
+
+
+
invoke(index = Pmw.DEFAULT, noFlash = 0)
+Invoke the callback command associated with the button specified
+ by index and return the value returned by the callback.
+ Unless noFlash is true, flash the button to
+ indicate to the user that something happened.
+ index may have any of the forms accepted by the index() method.
+
+
+
+
+
numbuttons()
+Return the number of buttons in the button box.
+
+
+
+
+
setdefault(index)
+Set the default button to the button given by index. This
+ causes the specified button to be displayed with the platform
+ specific appearance for a default button. If index is None,
+ there will be no default button. index may have any of the
+ forms accepted by the index() method.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack the ButtonBox.
+ self.buttonBox = Pmw.ButtonBox(parent,
+ labelpos = 'nw',
+ label_text = 'ButtonBox:',
+ frame_borderwidth = 2,
+ frame_relief = 'groove')
+ self.buttonBox.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
+
+ # Add some buttons to the ButtonBox.
+ self.buttonBox.add('OK', command = self.ok)
+ self.buttonBox.add('Apply', command = self.apply)
+ self.buttonBox.add('Cancel', command = self.cancel)
+
+ # Set the default button (the one executed when <Return> is hit).
+ self.buttonBox.setdefault('OK')
+ parent.bind('<Return>', self._processReturnKey)
+ parent.focus_set()
+
+ # Make all the buttons the same width.
+ self.buttonBox.alignbuttons()
+
+ def _processReturnKey(self, event):
+ self.buttonBox.invoke()
+
+ def ok(self):
+ print 'You clicked on OK'
+
+ def apply(self):
+ print 'You clicked on Apply'
+
+ def cancel(self):
+ print 'You clicked on Cancel'
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 24 May 1998
+
Pmw.Color -
+ contains functions for handling colors and color schemes
+
+
+
+
+
+
Description
+
+ This module is a set of functions for manipulating colors and for
+ modifying the color scheme of an application or a widget. Many of
+ the functions in this module take or return colors. These values
+ may represent colors in the following ways:
+
name
a standard color name, eg 'orange' or '#ffa500'
+
+
+
rgb
a 3-element sequence of red, green and blue intensities
+ each between 0.0 (dark) and 1.0 (light), eg [1.0, 0.6, 0.0].
+
+
+
hsi
a 3-element sequence (hue, saturation,
+ intensity). The value of hue is between 0.0 and 2pi
+ (6.28318) giving a range of colors covering, in order, red,
+ orange, yellow green, cyan, blue, magenta and back to red.
+ The value of saturation is between 0.0 (grey) and 1.0
+ (brilliant) and the value of intensity is between 0.0 (dark)
+ and 1.0 (bright).
+
+
+
+
As used in these functions, the brightness of a color is the
+ perceived grey level of the color as registered by the human eye.
+ For example, even though the colors red, blue and yellow have the
+ same intensity (1.0), they have different brightnesses, 0.299,
+ 0.114 and 0.886 respectively, reflecting the different way these
+ colors appear to the eye. The brightness of a color is a value
+ between 0.0 (dark) and 1.0 (bright).
+
+
A color scheme is a set of colors defined for each of the
+ default color options in the Tk option database. Color schemes
+ can be used in two ways. Firstly, using Pmw.Color.setscheme(),
+ the Tk option database can be set to the values in the color
+ scheme. This will not have any effect on currently existing
+ widgets, but any new widgets created after setting the options
+ will have these colors as their defaults. Secondly, using
+ Pmw.Color.changecolor() the color scheme can be used to change
+ the colors of a widget and all its child widgets.
+
+
A color scheme is specified by defining one or more color options
+ (one of the defined options must be background). Not all
+ options need be specified - if any options are not defined, they
+ are calculated from the other colors. These are the options used
+ by a color scheme, together with their values if not specified:
+
background: (must be specified)
+ foreground: black
+ activeForeground: same as foreground
+ insertBackground: same as foreground
+ selectForeground: same as foreground
+ highlightColor: same as foreground
+ disabledForeground: between fg and bg but closer to bg
+ highlightBackground: same as background
+ activeBackground: a little lighter that bg
+ selectBackground: a little darker that bg
+ troughColor: a little darker that bg
+ selectColor: yellow
+
+
+
There are many functions in this module. As well as
+ Pmw.Color.setscheme() and Pmw.Color.changecolor(), some of the
+ most useful are Pmw.Color.spectrum(),
+ Pmw.Color.changebrightness() and
+ Pmw.Color.getdefaultpalette().
+
+
+
+
+
+
Functions
+The following functions are available.
+
+
Pmw.Color.average(rgb1, rgb2, fraction)
+
+ Return an rgb color fraction of the way "between" the colors
+ rgb1 and rgb2, where fraction must be between 0.0 and
+ 1.0. If fraction is close to 0.0, then the color returned
+ will be close to rgb1. If it is close to 1.0, then the color
+ returned will be close to rgb2. If it is near 0.5, then the
+ color returned will be half way between the two colors.
+
+
+
+
+
+
+ Return the saturation of the color represented by brightness,
+ hue and intensity.
+
+
+
+
+
+
Pmw.Color.bordercolors(root, colorName)
+
+ Return a tuple (light, dark) of color names that can be used as
+ the light and dark border shadows on a widget where the background
+ is colorName. This is the same method that Tk uses for shadows
+ when drawing reliefs on widget borders. The root argument is
+ only used to query Tk for the rgb values of colorName.
+
+
+
+
+
+
+ Find the hue of the color colorName and return a color of this
+ hue with the required brightness. If brightness is None,
+ return the name of color with the given hue and with saturation
+ and intensity both 1.0. The root argument is only used to
+ query Tk for the rgb values of colorName.
+
+
+
+
+
+
+ Change the color of widget and all its child widgets according
+ to the color scheme specified by the other arguments. This is done
+ by modifying all of the color options of existing widgets that
+ have the default value. The color options are the lower case
+ versions of those described in the color scheme section. Any
+ options which are different to the previous color scheme (or the
+ defaults, if this is the first call) are not changed.
+
+
For example to change a widget to have a red color scheme with a
+ white foreground:
+
+ Return the "corrected" value of rgb. This can be used to
+ correct for dull monitors. If correction is less than 1.0,
+ the color is dulled. If correction is greater than 1.0, the
+ color is brightened.
+
+
+
+
+
+
Pmw.Color.getdefaultpalette(root)
+
+ Return a dictionary of the default values of the color options
+ described in the color scheme section.
+
+
To do this, a few widgets are created as children of root, their
+ defaults are queried, and then the widgets are destroyed. (Tk
+ supplies no other way to get widget default values.)
+
+
Note that root must be a Tk widget or toplevel. To use a Pmw
+ megawidget as the root, use it's hull component. For example:
+
+ Return the rgb representation of the color represented by hue,
+ saturation and intensity.
+
+
+
+
+
+
Pmw.Color.hue2name(hue, brightness = None)
+
+ Return the name of the color with the specified hue and
+ brightness. If hue is None, return a grey of the requested
+ brightness. Otherwise, the value of hue should be as described
+ above. If brightness is None, return the name of color with
+ the given hue and with saturation and intensity both 1.0.
+
+
+
+
+
+
Pmw.Color.name2rgb(root, colorName, asInt = 0)
+
+ Return colorName as an rgb value. If asInt is true, then
+ the elements of the return sequence are in the range 0 to
+ 65535 rather than 0.0 to 1.0. The root argument is only
+ used to query Tk for the rgb values of colorName.
+
+
+
+
+
+
Pmw.Color.rgb2brightness(rgb)
+
+ Return the brightness of the color represented by rgb.
+
+
+
+
+
+
Pmw.Color.rgb2hsi(rgb)
+
+ Return a tuple (hue, saturation, intensity) corresponding to
+ the color specified by the rgb sequence.
+
+
+
+
+
+
Pmw.Color.rgb2name(rgb)
+
+ Return the name of the color represented by rgb as a string of
+ the form '#RRGGBB' suitable for use with Tk color functions.
+
+
+
+
+
+
+ Set the color scheme for the application by setting default colors
+ (in the Tk option database of the root window of root) according
+ to the color scheme specified by the other arguments. This will
+ affect the initial colours of all widgets created after the call
+ to this function.
+
+
For example to initialise an application to have a red color
+ scheme with a white foreground:
This function does not modify the colors of already existing
+ widgets. Use Pmw.Color.changecolor() to do this.
+
+
Note that root must be a Tk widget or toplevel. To use the Tk
+ option database of the root window of a Pmw megawidget, use the
+ megawidget's hull component. For example:
+
+ Return a list of numColors different colors making up a
+ spectrum. If extraOrange is false, the colors are evenly
+ spaced by hue from one end of the spectrum (red) to the other
+ (magenta). If extraOrange is true, the hues are not quite
+ evenly spaced - the hues around orange are emphasised, thus
+ preventing the spectrum from appearing to have to many cool
+ hues.
+
+
If returnHues is false, the return values are the names of the
+ colors represented by the hues together with saturation and
+ intensity and corrected by correction.
+
+
If returnHues is true, the return values are hues.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 25 May 2002
+
+ A combobox contains an entry field and an associated scrolled
+ listbox. When an item in the listbox is selected, it is displayed
+ in the entry field. Optionally, the user may also edit the entry
+ field directly.
+
+
For a simple combobox, the scrolled listbox is displayed beneath
+ the entry field. For a dropdown combobox (the default), the
+ scrolled listbox is displayed in a window which pops up beneath
+ the entry field when the user clicks on an arrow button on the
+ right of the entry field. Either style allows an optional label.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
autoclear
+
+Initialisation option. If both autoclear and history are true, clear the entry field
+ whenever <Return> is pressed, after adding the value to the
+ history list. The default is 0.
+
+
+
+
+
buttonaspect
+
+Initialisation option. The width of the arrow button as a proportion of the height. The
+ height of the arrow button is set to the height of the entry
+ widget. The default is 1.0.
+
+
+
+
+
dropdown
+
+Initialisation option. Specifies whether the combobox should be dropdown or simple. The default is 1.
+
+
+
+
+
fliparrow
+
+Initialisation option. If true, the arrow button is draw upside down when the listbox is
+ being displayed. Used only in dropdown megawidgets. The default is 0.
+
+
+
+
+
history
+
+Initialisation option. When <Return> is pressed in the entry field, the current value
+ of the entry field is appended to the listbox if history is
+ true. The default is 1.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
listheight
+
+Initialisation option. The height, in pixels, of the dropdown listbox. The default is 200.
+
+
+
+
+
selectioncommand
+
+The function to call when an item is selected.
+ If this function takes a long time to run, and you want the entry
+ field to be updated quickly, call update_idletasks() at the
+ beginning of the function. Alternatively, wrap the function using
+ Pmw.busycallback(). The default is None.
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
unique
+
+Initialisation option. If both unique and history are true, the current value of the
+ entry field is not added to the listbox if it is already in the
+ list. The default is 1.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
arrowbutton
+
+In a dropdown combobox, the button to popup the listbox. By default, this component is a Tkinter.Canvas.
+
+
+
+
+
entryfield
+
+The entry field where the current selection is displayed. By default, this component is a Pmw.EntryField.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
popup
+
+In a dropdown combobox, the dropdown window. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
scrolledlist
+
+The scrolled listbox which displays the items to select. By default, this component is a Pmw.ScrolledListBox.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
entry
+
+Alias for entryfield_entry.
+
+
listbox
+
+Alias for scrolledlist_listbox.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the following classes
+are forwarded by this megawidget.
+Methods from Pmw.ScrolledListBox
+are forwarded to the
+scrolledlist component.
+Methods from Pmw.EntryField
+are forwarded to the
+entryfield component.
+Forwarded methods are searched in the order given.
+
+
+
bbox(index)
+This method is explicitly forwarded to the scrolledlist
+ component's bbox() method. Without this explicit forwarding,
+ the bbox() method (aliased to grid_bbox()) of the hull would
+ be invoked, which is probably not what the programmer intended.
+
+
+
+
+
clear()
+Delete all items from the scrolled listbox and delete all text
+ from the entry widget.
+
+
+
+
+
get(first = None, last = None)
+This is the same as the get() method of the scrolledlist
+ component, except that if first is None then
+ the value of the entry field is returned.
+
+
+
+
+
invoke()
+If a dropdown combobox, display the dropdown listbox. In a simple
+ combobox, select the currently selected item in the listbox,
+ call the selectioncommand and return the result.
+
+
+
+
+
selectitem(index, setentry = 1)
+Select the item in the listbox specified by index which may be
+ either one of the items in the listbox or the integer index of one
+ of the items in the listbox.
+
If setentry is true, also set the entry field to the selected
+ item.
+
+
+
+
+
+
size()
+This method is explicitly forwarded to the scrolledlist
+ component's size() method. Without this explicit forwarding,
+ the size() method (aliased to grid_size()) of the hull would
+ be invoked, which is probably not what the programmer intended.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A combobox dialog is a dialog window which displays a list and
+ an entry field which can be used to prompt the user for a value.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the combobox. The default is 10.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the combobox. The default is 10.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
combobox
+
+The combobox for the user to enter a value. By default it is
+ created using the option dropdown = 0. By default, this component is a Pmw.ComboBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
entry
+
+Alias for combobox_entry.
+
+
label
+
+Alias for combobox_label.
+
+
listbox
+
+Alias for combobox_listbox.
+
+
scrolledlist
+
+Alias for combobox_scrolledlist.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+In addition, methods from the
+Pmw.ComboBox class
+are forwarded by this megawidget to the
+combobox component.
+
+
+
bbox(index)
+This method is explicitly forwarded to the combobox component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
size()
+This method is explicitly forwarded to the combobox component's
+ size() method. Without this explicit forwarding, the size()
+ method (aliased to grid_size()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A counter contains an entry field and two arrow buttons to
+ increment and decrement the value in the entry field. Standard
+ counting types include numbers, times and dates. A user defined
+ counting function may also be supplied for specialised counting.
+ Counting can be used in combination with the entry field's
+ validation. The components may be laid out horizontally or
+ vertically.
+
+
Each time an arrow button is pressed the value displayed in the
+ entry field is incremented or decremented by the value of the
+ increment option. If the new value is invalid (according to the
+ entry field's validate option, perhaps due to exceeding minimum
+ or maximum limits), the old value is restored.
+
+
When an arrow button is pressed and the value displayed is not an
+ exact multiple of the increment, it is "truncated" up or down to
+ the nearest increment.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
autorepeat
+
+If true, the counter will continue to count up or down while an
+ arrow button is held pressed down. The default is 1.
+
+
+
+
+
buttonaspect
+
+Initialisation option. Specifies the width of the arrow buttons as a proportion of their
+ height. Values less than 1.0 will produce thin arrow buttons.
+ Values greater than 1.0 will produce fat arrow buttons. The default is 1.0.
+
+
+
+
+
datatype
+
+Specifies how the counter should count up and down.
+
The most general way to specify the datatype option is as a
+ dictionary. The kind of counting is specified by the 'counter'
+ dictionary field, which may be either a function or the name of
+ one of the standard counters described below. If the dictionary
+ does not have a 'counter' field, the field defaults to
+ 'numeric'.
+
+
Any other fields in the dictionary are passed on to the counter
+ function as keyword arguments.
+
+
If datatype is not a dictionary, then it is equivalent to
+ specifying it as a dictionary with a single 'counter' field.
+ For example, datatype = 'real' is equivalent to
+ datatype = {'counter' : 'real'}.
+
+
The standard counters are:
+
+
'numeric'
An integer number, as accepted by string.atol().
+
+
+
'integer'
Same as 'numeric'.
+
+
+
'real'
A real number, as accepted by string.atof(). This
+ counter accepts a 'separator' argument, which specifies
+ the character used to represent the decimal point. The
+ default 'separator' is '.'.
+
+
+
'time'
A time specification, as accepted by
+ Pmw.timestringtoseconds(). This counter accepts a
+ 'separator' argument, which specifies the character used to
+ separate the time fields. The default separator is ':'.
+ This counter also accepts a 'time24' argument. If this is
+ true, the time value is converted to a value between
+ '00:00:00' and '23:59:59'. The default is false.
+
+
+
'date'
A date specification, as accepted by
+ Pmw.datestringtojdn(). This counter accepts a 'separator'
+ argument, which specifies the character used to separate the
+ three date fields. The default is '/'. This counter also
+ accepts a 'format' argument, which is passed to
+ Pmw.datestringtojdn() to specify the desired ordering of the
+ fields. The default is 'ymd'.
+ This counter also accepts a 'yyyy' argument. If this is
+ false, the year field will be displayed as the year within the
+ century, otherwise it will be fully displayed. In both cases
+ it will be displayed with at least 2 digits, using leading
+ zeroes. The default is false.
+
+
+
If the 'counter' dictionary field is a function, then it will be
+ called whenever the counter is to be incremented or decremented.
+ The function is called with at least three arguments, the first
+ three being (text, factor, increment), where text is the
+ current contents of the entry field, factor is 1 when
+ incrementing or -1 when decrementing, and increment is the
+ value of the increment megawidget option.
+
+
The other arguments are keyword arguments made up of the fields of
+ the datatype dictionary (excluding the 'counter' field).
+
+
The counter function should return a string representing the
+ incremented or decremented value. It should raise a
+ ValueError exception if the text is invalid. In this case the
+ bell is rung and the entry text is not changed.
+
+
The default for datatype is numeric.
+
+
+
+
+
+
increment
+
+Specifies how many units should be added or subtracted when the
+ counter is incremented or decremented. If the currently displayed
+ value is not a multiple of increment, the value is changed to
+ the next multiple greater or less than the current value.
+
For the number datatypes, the value of increment is a number.
+ For the 'time' datatype, the value is in seconds. For the
+ 'date' datatype, the value is in days. The default is 1.
+
+
+
+
+
+
initwait
+
+Specifies the initial delay (in milliseconds) before a depressed
+ arrow button automatically starts to repeat counting. The default is 300.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
orient
+
+Initialisation option. Specifies whether the arrow buttons should appear to the left and
+ right of the entry field ('horizontal') or above and below
+ ('vertical'). The default is 'horizontal'.
+
+
+
+
+
padx
+
+Initialisation option. Specifies a padding distance to leave around the arrow buttons in
+ the x direction. The default is 0.
+
+
+
+
+
pady
+
+Initialisation option. Specifies a padding distance to leave around the arrow buttons in
+ the y direction. The default is 0.
+
+
+
+
+
repeatrate
+
+Specifies the delay (in milliseconds) between automatic counts
+ while an arrow button is held pressed down. The default is 50.
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
downarrow
+
+The arrow button used for decrementing the counter. Depending on
+ the value of orient, it will appear on the left or below the
+ entry field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
entryfield
+
+The entry field widget where the text is entered, displayed and
+ validated. By default, this component is a Pmw.EntryField.
+
+
+
+
+
frame
+
+If the label component has been created (that is, the labelpos
+ option is not None), the frame component is created to act as
+ the container of the entry field and arrow buttons. If there is
+ no label component, then no frame component is created and the
+ hull component acts as the container. In either case the border
+ around the container of the entry field and arrow buttons will be
+ raised (but not around the label). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
uparrow
+
+The arrow button used for incrementing the counter. Depending on
+ the value of orient, it will appear on the right or above the
+ entry field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
entry
+
+Alias for entryfield_entry.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Pmw.EntryField class
+are forwarded by this megawidget to the
+entryfield component.
+
+
+
decrement()
+Decrement the counter once, as if the down arrow had been pressed.
+
+
+
+
+
increment()
+Increment the counter once, as if the up arrow had been pressed.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A counter dialog is a dialog window which displays a counter
+ which can be used to prompt the user for a value.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the counter. The default is 20.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the counter. The default is 20.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
counter
+
+The counter for the user to enter a value. By default, this component is a Pmw.Counter.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
entry
+
+Alias for counter_entryfield_entry.
+
+
entryfield
+
+Alias for counter_entryfield.
+
+
label
+
+Alias for counter_label.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+In addition, methods from the
+Pmw.Counter class
+are forwarded by this megawidget to the
+counter component.
+
+
+
deleteentry(first, last = None)
+Delete text from the counter's entry widget. An alias for
+ component('entry').delete().
+
+
+
+
+
indexentry(index)
+An alias for component('entry').index().
+
+
+
+
+
insertentry(index, text)
+Insert text into the counter's entry widget. An alias for
+ component('entry').insert().
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the dialog to prompt for the number of times to ring the bell.
+ self.dialog = Pmw.CounterDialog(parent,
+ label_text = 'Enter the number of times to\n' + \
+ 'sound the bell (1 to 5)\n',
+ counter_labelpos = 'n',
+ entryfield_value = 2,
+ counter_datatype = 'numeric',
+ entryfield_validate =
+ {'validator' : 'numeric', 'min' : 1, 'max' : 5},
+ buttons = ('OK', 'Cancel'),
+ defaultbutton = 'OK',
+ title = 'Bell ringing',
+ command = self.execute)
+ self.dialog.withdraw()
+
+ # Create button to launch the dialog.
+ w = Tkinter.Button(parent, text = 'Show counter dialog',
+ command = self.dialog.activate)
+ w.pack(padx = 8, pady = 8)
+
+ def execute(self, result):
+ if result is None or result == 'Cancel':
+ print 'Bell ringing cancelled'
+ self.dialog.deactivate()
+ else:
+ count = self.dialog.get()
+ if not self.dialog.valid():
+ print 'Invalid entry: "' + count + '"'
+ else:
+ print 'Ringing the bell ' + count + ' times'
+ for num in range(string.atoi(count)):
+ if num != 0:
+ self.dialog.after(200)
+ self.dialog.bell()
+ self.dialog.deactivate()
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ A dialog is a toplevel window composed of a button box and a child
+ site area. The child site area can be used to specialise the
+ megawidget by creating other widgets within it. This can be done
+ by using this class directly or by deriving from it.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaToplevel.
+
+
+
interior()
+Return the child site for the dialog. This is the same as
+ component('dialogchildsite').
+
+
+
+
+
invoke(index = Pmw.DEFAULT)
+Invoke the command specified by the command option as if the
+ button specified by index had been pressed and return the
+ result. index may have any of the forms accepted by the
+ Pmw.ButtonBoxindex() method.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create two buttons to launch the dialog.
+ w = Tkinter.Button(parent, text = 'Show application modal dialog',
+ command = self.showAppModal)
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text = 'Show global modal dialog',
+ command = self.showGlobalModal)
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text = 'Show dialog with "no grab"',
+ command = self.showDialogNoGrab)
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text =
+ 'Show toplevel window which\n' +
+ 'will not get a busy cursor',
+ command = self.showExcludedWindow)
+ w.pack(padx = 8, pady = 8)
+
+ # Create the dialog.
+ self.dialog = Pmw.Dialog(parent,
+ buttons = ('OK', 'Apply', 'Cancel', 'Help'),
+ defaultbutton = 'OK',
+ title = 'My dialog',
+ command = self.execute)
+ self.dialog.withdraw()
+
+ # Add some contents to the dialog.
+ w = Tkinter.Label(self.dialog.interior(),
+ text = 'Pmw Dialog\n(put your widgets here)',
+ background = 'black',
+ foreground = 'white',
+ pady = 20)
+ w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
+
+ # Create the window excluded from showbusycursor.
+ self.excluded = Pmw.MessageDialog(parent,
+ title = 'I still work',
+ message_text =
+ 'This window will not get\n' +
+ 'a busy cursor when modal dialogs\n' +
+ 'are activated. In addition,\n' +
+ 'you can still interact with\n' +
+ 'this window when a "no grab"\n' +
+ 'modal dialog is displayed.')
+ self.excluded.withdraw()
+ Pmw.setbusycursorattributes(self.excluded.component('hull'),
+ exclude = 1)
+
+ def showAppModal(self):
+ self.dialog.activate(geometry = 'centerscreenalways')
+
+ def showGlobalModal(self):
+ self.dialog.activate(globalMode = 1)
+
+ def showDialogNoGrab(self):
+ self.dialog.activate(globalMode = 'nograb')
+
+ def showExcludedWindow(self):
+ self.excluded.show()
+
+ def execute(self, result):
+ print 'You clicked on', result
+ if result not in ('Apply', 'Help'):
+ self.dialog.deactivate(result)
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ An entry field contains an entry widget with optional validation of
+ various kinds. Built-in validation may be used, such as
+ integer, real, time or date, or an external validation
+ function may be supplied. If valid text is entered, it will be
+ displayed with the normal background. If invalid text is entered,
+ it is not displayed and the previously displayed text is restored.
+ If partially valid text is entered, it will be displayed with a
+ background color to indicate it is in error. An example of
+ partially valid real text is '-.', which may be the first two
+ charactes of the valid string '-.5'. Some validators, such as
+ date, have a relaxed interpretation of partial validity, which
+ allows the user flexibility in how they enter the text.
+
+
Validation is performed early, at each keystroke or other event
+ which modifies the text. However, if partially valid text is
+ permitted, the validity of the entered text can be checked just
+ before it is to be used, which is a form of late validation.
+
+
Minimum and maximum values may be specified. Some validators also
+ accept other specifications, such as date and time formats and
+ separators.
+
+
+
+
+
+
Validation function return values
+
+ Validation is performed by a function which takes as its first
+ argument the entered text and returns one of three standard
+ values, indicating whether the text is valid:
+
+
Pmw.OK
The text is valid.
+
+
+
Pmw.ERROR
The text is invalid and is not acceptable for
+ display. In this case the entry will be restored to its
+ previous value.
+
+
+
Pmw.PARTIAL
The text is partially valid and is acceptable
+ for display. In this case the text will be displayed
+ using the errorbackground color.
+
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
command
+
+This specifies a function to call whenever the <Return> key is
+ pressed or invoke() is called. The default is None.
+
+
+
+
+
errorbackground
+
+Specifies the background color to use when displaying invalid or
+ partially valid text. The default is 'pink'.
+
+
+
+
+
extravalidators
+
+This is a dictionary of extra validators. The keys are the names
+ of validators which may be used in a future call to the
+ validate option. Each value in the dictionary is a tuple of
+ (validate_function, stringtovalue_function).
+
The validate_function is used to implement the validation and
+ the stringtovalue_function is used to convert the entry input
+ into a value which can be compared with the minimum and maximum
+ limits. These functions are as described for the validate
+ option.
+
+
If either of these is not given as a function, it is assumed to be
+ the name of one of the other extra validators or one of the
+ standard validators. The alias search is performed when the
+ validate option is configured, not when the extravalidators
+ option is configured or when the validate function is called.
+
+
If the name of one of the extra validators is the same as one of
+ the standard validators, the extra validator takes precedence. The default is {}.
+
+
+
+
+
+
invalidcommand
+
+This is executed when invalid text is entered and the text is
+ restored to its previous value (that is, when the validate
+ function returns Pmw.ERROR). It is also called if an attempt is
+ made to set invalid text in a call to setentry(). The default
+ is self.bell.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
modifiedcommand
+
+This is called whenever the text of the entry has been changed
+ due to user action or by a call to setentry(). The default is None.
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
validate
+
+Specifies what kind of validation should be performed on the entry
+ input text.
+
The most general way to specify the validate option is as a
+ dictionary. The kind of validation is specified by the
+ 'validator' dictionary field, which may be the name of one of
+ the standard validators described below, the name of a validator
+ supplied by the extravalidators option, a function or None.
+ The default is None.
+
+
Any other dictionary fields specify other restrictions on the
+ entered values. For all validators, the following fields may be
+ specified:
+
+
'min'
Specifies the minimum acceptable value, or None if no
+ minimum checking should be performed. The default is None.
+
+
+
'max'
Specifies the maximum acceptable value, or None if no
+ maximum checking should be performed. The default is None.
+
+
+
'minstrict'
If true, then minimum checking is strictly enforced.
+ Otherwise, the entry input may be less than min, but will be
+ displayed using the errorbackground color. The default is true.
+
+
+
'maxstrict'
If true, then maximum checking is strictly enforced.
+ Otherwise, the entry input may be more than max, but will be
+ displayed using the errorbackground color. The default is true.
+
+
+
If the dictionary contains a 'stringtovalue' field, it overrides
+ the normal stringtovalue function for the validator. The
+ stringtovalue function is described below.
+
+
Other fields in the dictionary (apart from the core fields
+ mentioned above) are passed on to the validator and
+ stringtovalue functions as keyword arguments.
+
+
If validate is not a dictionary, then it is equivalent to
+ specifying it as a dictionary with a single 'validator' field.
+ For example, validate = 'real' is equivalent to /validate =
+ {'validator' : 'real'}/ and specifies real numbers without any
+ minimum or maximum limits and using '.' as the decimal point
+ character.
+
+
The standard validators accepted in the 'validator' field are:
+
+
'numeric'
An integer greater than or equal to 0. Digits
+ only. No sign.
+
+
+
'integer'
Any integer (negative, 0 or positive) as accepted
+ by string.atol().
+
+
+
'hexadecimal'
Hex number (with optional leading '0x'), as accepted
+ by string.atol(text, 16).
+
+
+
'real'
A number, with or without a decimal point and optional
+ exponent (e or E), as accepted by string.atof(). This
+ validator accepts a 'separator' argument, which specifies
+ the character used to represent the decimal point. The
+ default 'separator' is '.'.
+
+
+
'alphabetic'
Consisting of the letters 'a-z' and 'A-Z'.
+ In this case, 'min' and 'max' specify limits on the length
+ of the text.
+
+
+
'alphanumeric'
Consisting of the letters 'a-z', 'A-Z' and '0-9'.
+ In this case, 'min' and 'max' specify limits on the length
+ of the text.
+
+
+
'time'
Hours, minutes and seconds, in the format
+ 'HH:MM:SS', as accepted by Pmw.timestringtoseconds().
+ This validator accepts a 'separator' argument, which
+ specifies the character used to separate the three fields.
+ The default separator is ':'. The time may be negative.
+
+
+
'date'
Day, month and year, as accepted by
+ Pmw.datestringtojdn(). This validator accepts a
+ 'separator' argument, which specifies the character used to
+ separate the three fields. The default is ':'. This
+ validator also accepts a 'format' argument, which is passed to
+ Pmw.datestringtojdn() to specify the desired ordering of the
+ fields. The default is 'ymd'.
+
+
+
If 'validator' is a function, then it will be called whenever
+ the contents of the entry may have changed due to user action or
+ by a call to setentry(). The function is called with at least
+ one argument, the first one being the new text as modified by the
+ user or setentry(). The other arguments are keyword arguments
+ made up of the non-core fields of the validate dictionary.
+
+
The validator function should return Pmw.OK, Pmw.ERROR or
+ Pmw.PARTIAL as described above. It should not perform minimum
+ and maximum checking. This is done after the call, if it returns
+ Pmw.OK.
+
+
The 'stringtovalue' field in the dictionary may be specified as
+ the name of one of the standard validators, the name of a
+ validator supplied by the extravalidators option, a function or
+ None.
+
+
The stringtovalue function is used to convert the entry input
+ into a value which can then be compared with any minimum or
+ maximum values specified for the validator. If the 'min' or
+ 'max' fields are specified as strings, they are converted using
+ the stringtovalue function. The stringtovalue function is
+ called with the same arguments as the validator function. The
+ stringtovalue function for the standard number validators
+ convert the string to a number. Those for the standard alpha
+ validators return the length of the string. Those for the
+ standard 'time' and 'date' validators return the number of
+ seconds and the Julian Day Number, respectively. See
+ Pmw.stringtoreal(), Pmw.timestringtoseconds() and
+ Pmw.datestringtojdn().
+
+
If the validator has been specified as a function and no
+ 'stringtovalue' field is given, then it defaults to the standard
+ python len() function.
+
+
If 'validator' is None, no validation is performed. However,
+ minimum and maximum checking may be performed, according to the
+ stringtovalue function. For example, to limit the entry text to
+ a maximum of five characters:
+
+
Pmw.EntryField(validate = {'max' : 5})
+
+
The validator functions for each of the standard validators can
+ be accessed as:
Whenever the validate option is configured, the text currently
+ displayed in the entry widget is revalidated. If it is not valid,
+ the errorbackground color is set and the invalidcommand
+ function is called. However, the displayed text is not modified.
+
+
The default for validate is None.
+
+
+
+
+
+
value
+
+Initialisation option. Specifies the initial contents of the entry.
+ If this text is invalid, it will be displayed with the
+ errorbackground color and the invalidcommand function will be called.
+ If both value and entry_textvariable options are specified in
+ the constructor, value will take precedence. The default is ''.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
entry
+
+The widget where the user may enter text. Long text may be
+ scrolled horizontally by dragging with the middle mouse button. By default, this component is a Tkinter.Entry.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Entry class
+are forwarded by this megawidget to the
+entry component.
+
+
+
checkentry()
+Check the validity of the current contents of the entry widget
+ and return the result.
+ If the text is not valid, set the background to errorbackground and
+ call the invalidcommand function. If there is a variable
+ specified by the entry_textvariable option, this method should be
+ called after the set() method of the variable is called. If this
+ is not done in this case, the entry widget background will not be
+ set correctly.
+
+
+
+
+
clear()
+Remove all text from the entry widget. Equivalent to setentry('').
+
+
+
+
+
getvalue()
+Return the text displayed by the entry.
+
+
+
+
+
invoke()
+Invoke the command specified by the command option as if the
+ <Return> key had been pressed and return the result.
+
+
+
+
+
setentry(text)
+Same as setvalue() method.
+
+
+
+
+
setvalue(text)
+Set the contents of the entry widget to text and carry out
+ validation as if the text had been entered by the user. If the
+ text is invalid, the entry widget will not be changed and the
+ invalidcommand function will be called. Return the validity
+ of text.
+
+
+
+
+
valid()
+Return true if the contents of the entry widget are valid.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ This megawidget consists of an interior frame with an exterior
+ ring border and an identifying tag displayed over the top edge of
+ the ring. The programmer can create other widgets within the
+ interior frame.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
collapsedsize
+
+Initialisation option. The distance from the bottom of the tag to the bottom of the ring
+ when the groupchildsite is collapsed. The default is 6.
+
+
+
+
+
tagindent
+
+Initialisation option. The distance from the left edge of the ring to the left side of
+ the tag component. The default is 10.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
groupchildsite
+
+The frame which can contain other widgets to be grouped. By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
ring
+
+This component acts as the enclosing ring around the
+ groupchildsite. The default borderwidth is 2 and the
+ default relief is 'groove'. By default, this component is a Tkinter.Frame.
+
+
+
+
+
tag
+
+The identifying tag displayed over the top edge of the enclosing
+ ring. If the pyclass for this component is None, (ie:
+ tag_pyclass = None, then no tag component is created. By default, this component is a Tkinter.Label.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
collapse()
+Do not display the groupchildsite component.
+
+
+
+
+
expand()
+Display the groupchildsite component.
+
+
+
+
+
interior()
+Return the frame within which the programmer may create widgets.
+ This is the same as component('groupchildsite').
+
+
+
+
+
toggle()
+Display the groupchildsite component if it is currently hidden and
+ hide it if it is currently displayed.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A history text is a scrolled text widget with added functionality
+ to maintain a history of each screen and allow editing of prior
+ screens. Here, screen refers to the entire contents of the text
+ widget. This widget does not support a fine-grained history of
+ every change made to the text.
+
+
Together with a few buttons and a scrolled text to display the
+ results, a history text can be used as the query-entry part of a
+ simple interactive text-based database query system. When the
+ user enters and executes a query, the query (the entire contents
+ of the text widget) is added to the history list. The user may
+ view previous queries and either execute them again or modify them
+ and execute the new query. If a previously executed query is
+ modified, the user may undo or redo all changes made to the query
+ before the query is executed.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
borderframe
+
+Initialisation option. If true, the borderframe component will be created. The default is 0.
+
+
+
+
+
columnheader
+
+Initialisation option. If true, the columnheader component will be created. The default is 0.
+
+
+
+
+
compressany
+
+See addhistory(). The default is 1.
+
+
+
+
+
compresstail
+
+See addhistory(). The default is 1.
+
+
+
+
+
historycommand
+
+This is a callback to indicate whether the currently displayed
+ entry in the history list has a previous or next entry. The
+ callback is given two arguments, prevstate and nextstate. If
+ the currently displayed entry is first in the history list, then
+ prevstate is 'disabled', otherwise it is 'normal'. If the
+ currently displayed entry is last in the history list, then
+ nextstate is 'disabled', otherwise it is 'normal'. These
+ values can be used, for example, to modify the state of Next and
+ Previous buttons that call the next() and prev() methods. The default is None.
+
+
+
+
+
hscrollmode
+
+The horizontal scroll mode. If 'none', the horizontal scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
rowcolumnheader
+
+Initialisation option. If true, the rowcolumnheader component will be created. The default is 0.
+
+
+
+
+
rowheader
+
+Initialisation option. If true, the rowheader component will be created. The default is 0.
+
+
+
+
+
scrollmargin
+
+Initialisation option. The distance between the scrollbars and the text widget. The default is 2.
+
+
+
+
+
usehullsize
+
+Initialisation option. If true, the size of the megawidget is determined solely by the
+ width and height options of the hull component.
+
Otherwise, the size of the megawidget is determined by the width
+ and height of the text component, along with the size and/or
+ existence of the other components, such as the label, the
+ scrollbars and the scrollmargin option. All these affect the
+ overall size of the megawidget. The default is 0.
+
+
+
+
+
+
vscrollmode
+
+The vertical scroll mode. If 'none', the vertical scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
borderframe
+
+A frame widget which snuggly fits around the text widget, to give
+ the appearance of a text border. It is created with a border so
+ that the text widget, which is created without a border, looks
+ like it has a border. By default, this component is a Tkinter.Frame.
+
+
+
+
+
columnheader
+
+A text widget with a default height of 1 displayed above the main
+ text widget and which scrolls horizontally in sync with the
+ horizontal scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
horizscrollbar
+
+The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
rowcolumnheader
+
+A text widget displayed to the top left of the main text widget,
+ above the row header and to the left of the column header if they
+ exist. The widget is not scrolled automatically. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
rowheader
+
+A text widget displayed to the left of the main text widget and
+ which scrolls vertically in sync with the vertical scrolling of
+ the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
text
+
+The text widget which is scrolled by the scrollbars. If the
+ borderframe option is true, this is created with a borderwidth
+ of 0 to overcome a known problem with text widgets: if a widget
+ inside a text widget extends across one of the edges of the text
+ widget, then the widget obscures the border of the text widget.
+ Therefore, if the text widget has no border, then this overlapping
+ does not occur. By default, this component is a Tkinter.Text.
+
+
+
+
+
vertscrollbar
+
+The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.ScrolledText.
+
+
+
addhistory()
+Append the currently displayed text to the history list.
+
If compressany is true, a new entry will be added to the history
+ list only if the currently displayed entry has changed.
+
+
If compresstail is true, a new entry will be added to the
+ history list only if the currently displayed entry has changed
+ or if it is not the last entry in the history list.
+
+
+
+
+
+
gethistory()
+Return the history list. Each entry in the list is a 3-tuple.
+ The first item in a history entry is the original text as added by
+ addhistory(). The second item is the edited text (if the user
+ has modified the entry but addhistory() has not yet been called
+ on the text). The third item specifies whether the entry should
+ currently display the original or modified text.
+
+
+
+
+
next()
+Display the next screen in the history list.
+
+
+
+
+
prev()
+Display the previous screen in the history list.
+
+
+
+
+
redo()
+Reverse the effect of undo().
+
+
+
+
+
undo()
+Undo all changes made since this entry was added to the history
+ list.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack the PanedWidget to hold the query and result
+ # windows.
+ # !! panedwidget should automatically size to requested size
+ panedWidget = Pmw.PanedWidget(parent,
+ orient = 'vertical',
+ hull_height = 400,
+ hull_width = 550)
+ panedWidget.add('query', min = 0.05, size = 0.2)
+ panedWidget.add('buttons', min = 0.1, max = 0.1)
+ panedWidget.add('results', min = 0.05)
+ panedWidget.pack(fill = 'both', expand = 1)
+
+ # Create and pack the HistoryText.
+ self.historyText = Pmw.HistoryText(panedWidget.pane('query'),
+ text_wrap = 'none',
+ text_width = 60,
+ text_height = 10,
+ historycommand = self.statechange,
+ )
+ self.historyText.pack(fill = 'both', expand = 1)
+ self.historyText.component('text').focus()
+
+ buttonList = (
+ [20, None],
+ ['Clear', self.clear],
+ ['Undo', self.historyText.undo],
+ ['Redo', self.historyText.redo],
+ [20, None],
+ ['Prev', self.historyText.prev],
+ ['Next', self.historyText.next],
+ [30, None],
+ ['Execute', Pmw.busycallback(self.executeQuery)],
+ )
+ self.buttonDict = {}
+
+ buttonFrame = panedWidget.pane('buttons')
+ for text, cmd in buttonList:
+ if type(text) == type(69):
+ frame = Tkinter.Frame(buttonFrame, width = text)
+ frame.pack(side = 'left')
+ else:
+ button = Tkinter.Button(buttonFrame, text = text, command = cmd)
+ button.pack(side = 'left')
+ self.buttonDict[text] = button
+
+ for text in ('Prev', 'Next'):
+ self.buttonDict[text].configure(state = 'disabled')
+
+ self.results = Pmw.ScrolledText(panedWidget.pane('results'), text_wrap = 'none')
+ self.results.pack(fill = 'both', expand = 1)
+
+ def statechange(self, prevstate, nextstate):
+ self.buttonDict['Prev'].configure(state = prevstate)
+ self.buttonDict['Next'].configure(state = nextstate)
+
+ def clear(self):
+ self.historyText.delete('1.0', 'end')
+
+ def addnewlines(self, text):
+ if len(text) == 1:
+ text = text + '\n'
+ if text[-1] != '\n':
+ text = text + '\n'
+ if text[-2] != '\n':
+ text = text + '\n'
+ return text
+
+ def executeQuery(self):
+ sql = self.historyText.get()
+ self.results.insert('end', 'Query:\n' + self.addnewlines(sql))
+ self.results.see('end')
+ self.results.update_idletasks()
+ self.historyText.addhistory()
+ results = 'Results:\nfoo'
+ if len(results) > 0:
+ self.results.insert('end', self.addnewlines(results))
+ self.results.see('end')
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 20 May 2002
+
+ This megawidget consists of an interior frame with an associated
+ label which can be positioned on any side of the frame. The
+ programmer can create other widgets within the interior frame.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'nsew'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
labelchildsite
+
+The frame which can contain other widgets to be labelled. By default, this component is a Tkinter.Frame.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
interior()
+Return the frame within which the programmer may create widgets.
+ This is the same as component('labelchildsite').
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+
+ # Create a frame to put the LabeledWidgets into
+ frame = Tkinter.Frame(parent, background = 'grey90')
+ frame.pack(fill = 'both', expand = 1)
+
+ # Create and pack the LabeledWidgets.
+ column = 0
+ row = 0
+ for pos in ('n', 'nw', 'wn', 'w'):
+ lw = Pmw.LabeledWidget(frame,
+ labelpos = pos,
+ label_text = pos + ' label')
+ lw.component('hull').configure(relief='sunken', borderwidth=2)
+ lw.grid(column=column, row=row, padx=10, pady=10)
+ cw = Tkinter.Button(lw.interior(), text='child\nsite')
+ cw.pack(padx=10, pady=10, expand='yes', fill='both')
+
+ # Get ready for next grid position.
+ column = column + 1
+ if column == 2:
+ column = 0
+ row = row + 1
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 8 November 1998
+
+ This class is a wrapper for the Tkinter.Menu class. It should be
+ used as the main menu of toplevel windows. The class is similar
+ to Pmw.MenuBar, but should be used when native menus are required.
+ See the Tkinter.Menu documentation for full details.
+
+
This class should be created as the child of a Tkinter.Toplevel
+ and should then be specified as the menu associated with the
+ toplevel, using the toplevel's configure() method. For example:
+
# Create a Pmw.MegaToplevel.
+ megaToplevel = Pmw.MegaToplevel()
+ # Get the Tkinter.Toplevel from Pmw.MegaToplevel.
+ toplevel = megaToplevel.interior()
+ # Create the menu bar for the toplevel.
+ menuBar = Pmw.MainMenuBar(toplevel)
+ # Configure the toplevel to use the menuBar.
+ toplevel.configure(menu = menuBar)
+
+
+
There are methods to add menus, both as toplevel menus and
+ sub-menus, and for adding menu items to the menus. Each menu item
+ may have help text to be displayed by a Pmw.Balloon. Each menu and
+ cascaded menu (sub-menu) is referenced by name which is supplied
+ on creation.
+
+
This megawidget is derived from Pmw.MegaArchetype (not Pmw.MegaWidget
+ like most other megawidgets), with the hull class being
+ Tkinter.Menu.
+
+
(Note that due to bugs in Tk's menubar functionality, balloon help
+ has not been implemented and status help does not work properly.)
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
balloon
+
+Specifies a Pmw.Balloon to display the help text for menu items. If
+ None, no help is displayed. If the balloon has an associated
+ Pmw.MessageBar, the help text will also be displayed there.
+
Due to a bug in some versions of Tk (8.0 and possible others),
+ help text will not be displayed by the balloon. However, help
+ text will be displayed in the balloon's associated messagebar. The default is None.
+
+
+
+
+
+
hotkeys
+
+Initialisation option. If true, keyboard accelerators will be assigned to each menu item.
+ Keyboard accelerators can be used to access the menus without
+ using the mouse. The accelerator character is always one of the
+ alphanumeric characters in the text label of the menu item and is
+ indicated by an underline.
+
To select a menu, simultaneously press the <Alt> key and the
+ accelerator character indicated on a toplevel menu item. The
+ arrows keys can then be used to select other menus and menu items.
+ To invoke a menu item, press <Return> or press the accelerator
+ character indicated on the menu item.
+
+
Each accelerator character will be assigned automatically unless
+ traverseSpec is supplied to the addmenu(), addmenuitem() or
+ addcascademenu() methods. The automatically selected
+ accelerator character for a menu item is the first character in
+ the label text that has not already been used as an accelerator in
+ the menu containing the menu item.
+
+
If traverseSpec is given, it must be either an integer or a
+ character. If an integer, it specifies the index of the character
+ in the label text to use as the accelerator character. If a
+ character, it specifies the character to use as the accelerator
+ character. The default is 1.
+
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+The toplevel menu widget. By default, this component is a Tkinter.Menu.
+
+
+
+
+
Dynamic components
+
+ Menu components are created dynamically by the addmenu() and
+ addcascademenu() methods. By default, these are of type
+ Tkinter.Menu and are created with a component group of Menu.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaArchetype.
+In addition, methods from the
+Tkinter.Menu class
+are forwarded by this megawidget to the
+hull component.
+
+
+
+Add a cascade menu (sub-menu) to the menu parentMenuName. The
+ menuName argument must not be the same as any menu already
+ created using the addmenu() or addcascademenu() methods.
+
A menu item in the parent menu is created (with the
+ add_cascade() method of the parent menu) using all keyword
+ arguments except tearoff and name.
+
+
If the label keyword argument is not given, the label option
+ of the menu item defaults to menuName. If the underline
+ keyword argument is not given (and the hotkeys megawidget option
+ is true) the underline option is determined as described under
+ hotkeys and is used to specify the keyboard accelerator.
+
+
The statusHelp argument is used as the help string for the menu
+ item. This is displayed using the showstatus() method of the
+ balloon.
+
+
The tearoff and name keyword arguments, if present, are passed
+ to the constructor of the menu. See Tkinter.Menu for details of
+ these options. The menu is created as a component named
+ menuName.
+Add a cascade menu to the toplevel menu. The menuName argument
+ must not be the same as any menu already created using the
+ addmenu() or addcascademenu() methods.
+
A menu item in the toplevel menu is created (with the
+ add_cascade() method) using all keyword arguments except
+ tearoff and name.
+
+
If the label keyword argument is not given, the label option
+ of the menu button defaults to menuName. If the underline
+ keyword argument is not given (and the hotkeys megawidget option
+ is true) the underline option is determined as described under
+ hotkeys and is used to specify the keyboard accelerator.
+
+
The statusHelp argument is used as the help string for the menu
+ item. This is displayed using the showstatus() method of the
+ balloon. Currently balloonHelp is not used, due to a bug in Tk
+ version 8.0.
+
+
The tearoff and name keyword arguments, if present, are passed
+ to the constructor of the menu. See Tkinter.Menu for details of
+ these options. The menu is created as a component named
+ menuName.
+Add a menu item to the menu menuName. The kind of menu item is
+ given by itemType and may be one of command, separator,
+ checkbutton, radiobutton or cascade (although cascade menus
+ are better added using the addcascademenu() method). Any
+ keyword arguments present will be passed to the menu when creating
+ the menu item. See Tkinter.Menu for the valid options for each
+ item type. In addition, a keyboard accelerator may be
+ automatically given to the item, as described under hotkeys.
+
When the mouse is moved over the menu item, the helpString will
+ be displayed by the balloon's statuscommand.
+
+
+
+
+
+
deletemenu(menuName)
+Delete the menu menuName and all its items. The menu may either
+ be a toplevel menu or a cascade menu.
+
+
+
+
+
deletemenuitems(menuName, start, end = None)
+Delete menu items from the menu menuName. If end is not
+ given, the start item is deleted. Otherwise all items from
+ start to end are deleted.
+
+
+
+
+
disableall()
+Disable all toplevel menus.
+
+
+
+
+
enableall()
+Enable all toplevel menus.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create button to launch the toplevel with main menubar.
+ w = Tkinter.Button(parent, text = 'Show Pmw.MainMenuBar demo',
+ command = lambda parent=parent: MainMenuBarToplevel(parent))
+ w.pack(padx = 8, pady = 8)
+
+class MainMenuBarToplevel:
+ def __init__(self, parent):
+ # Create the toplevel to contain the main menubar.
+ megaToplevel = Pmw.MegaToplevel(parent, title = title)
+ toplevel = megaToplevel.interior()
+
+ # Create the Balloon for this toplevel.
+ self.balloon = Pmw.Balloon(toplevel)
+
+ # Create and install the MenuBar.
+ menuBar = Pmw.MainMenuBar(toplevel,
+ balloon = self.balloon)
+ toplevel.configure(menu = menuBar)
+ self.menuBar = menuBar
+
+ # Add some buttons to the MainMenuBar.
+ menuBar.addmenu('File', 'Close this window or exit')
+ menuBar.addmenuitem('File', 'command', 'Close this window',
+ command = PrintOne('Action: close'),
+ label = 'Close')
+ menuBar.addmenuitem('File', 'separator')
+ menuBar.addmenuitem('File', 'command', 'Exit the application',
+ command = PrintOne('Action: exit'),
+ label = 'Exit')
+
+ menuBar.addmenu('Edit', 'Cut, copy or paste')
+ menuBar.addmenuitem('Edit', 'command', 'Delete the current selection',
+ command = PrintOne('Action: delete'),
+ label = 'Delete')
+
+ menuBar.addmenu('Options', 'Set user preferences')
+ menuBar.addmenuitem('Options', 'command', 'Set general preferences',
+ command = PrintOne('Action: general options'),
+ label = 'General...')
+
+ # Create a checkbutton menu item.
+ self.toggleVar = Tkinter.IntVar()
+ # Initialise the checkbutton to 1:
+ self.toggleVar.set(1)
+ menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off',
+ label = 'Toggle',
+ command = self._toggleMe,
+ variable = self.toggleVar)
+ self._toggleMe()
+
+ menuBar.addcascademenu('Options', 'Size',
+ 'Set some other preferences', traverseSpec = 'z', tearoff = 1)
+ for size in ('tiny', 'small', 'average', 'big', 'huge'):
+ menuBar.addmenuitem('Size', 'command', 'Set size to ' + size,
+ command = PrintOne('Action: size ' + size),
+ label = size)
+
+ menuBar.addmenu('Help', 'User manuals', name = 'help')
+ menuBar.addmenuitem('Help', 'command', 'About this application',
+ command = PrintOne('Action: about'),
+ label = 'About...')
+
+ # Create and pack the main part of the window.
+ self.mainPart = Tkinter.Label(toplevel,
+ text = 'This is the\nmain part of\nthe window',
+ background = 'black',
+ foreground = 'white',
+ padx = 30,
+ pady = 30)
+ self.mainPart.pack(fill = 'both', expand = 1)
+
+ # Create and pack the MessageBar.
+ self.messageBar = Pmw.MessageBar(toplevel,
+ entry_width = 40,
+ entry_relief='groove',
+ labelpos = 'w',
+ label_text = 'Status:')
+ self.messageBar.pack(fill = 'x', padx = 10, pady = 10)
+ self.messageBar.message('state',
+ 'Balloon/status help not working properly - Tk menubar bug')
+
+ buttonBox = Pmw.ButtonBox(toplevel)
+ buttonBox.pack(fill = 'x')
+ buttonBox.add('Disable\nall', command = menuBar.disableall)
+ buttonBox.add('Enable\nall', command = menuBar.enableall)
+ buttonBox.add('Create\nmenu', command = self.add)
+ buttonBox.add('Delete\nmenu', command = self.delete)
+ buttonBox.add('Create\nitem', command = self.additem)
+ buttonBox.add('Delete\nitem', command = self.deleteitem)
+
+ # Configure the balloon to displays its status messages in the
+ # message bar.
+ self.balloon.configure(statuscommand = self.messageBar.helpmessage)
+
+ self.testMenuList = []
+
+ def _toggleMe(self):
+ print 'Toggle value:', self.toggleVar.get()
+
+ def add(self):
+ if len(self.testMenuList) == 0:
+ num = 0
+ else:
+ num = self.testMenuList[-1]
+ num = num + 1
+ name = 'Menu%d' % num
+ self.testMenuList.append(num)
+
+ self.menuBar.addmenu(name, 'This is ' + name)
+
+ def delete(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[0]
+ name = 'Menu%d' % num
+ del self.testMenuList[0]
+ self.menuBar.deletemenu(name)
+
+ def additem(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[-1]
+ menuName = 'Menu%d' % num
+ menu = self.menuBar.component(menuName)
+ if menu.index('end') is None:
+ label = 'item X'
+ else:
+ label = menu.entrycget('end', 'label') + 'X'
+ self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label,
+ command = PrintOne('Action: ' + menuName + ': ' + label),
+ label = label)
+
+ def deleteitem(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[-1]
+ menuName = 'Menu%d' % num
+ menu = self.menuBar.component(menuName)
+ if menu.index('end') is None:
+ self.menuBar.bell()
+ else:
+ self.menuBar.deletemenuitems(menuName, 0)
+
+class PrintOne:
+ def __init__(self, text):
+ self.text = text
+
+ def __call__(self):
+ print self.text
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 22 April 2000
+
Pmw.MegaArchetype() -
+ abstract base class for all Pmw megawidgets
+
+
+
+
+
Description
+
+ This class is the basis for all Pmw megawidgets. It provides
+ methods to manage options and component widgets.
+
+
This class is normally used as a base class for other classes. If
+ the hullClass argument is specified, such as in the Pmw.MegaWidget
+ and Pmw.MegaToplevel classes, a container widget is created to act
+ as the parent of all other component widgets. Classes derived
+ from these sub classes create other component widgets and options
+ to implement megawidgets that can be used in applications.
+
+
If no hullClass argument is given to the constructor, no
+ container widget is created and only the option configuration
+ functionality is available.
+
+
+
+
+
+
Components
+
+ A megawidget is generally made up of other widgets packed
+ within the megawidget's containing widget. These sub-widgets
+ are called the components of the megawidget and are given
+ logical names for easy reference. The component mechanism
+ allows the user of a megawidget to gain controlled access to
+ some of the internals of the megawidget, for example to call a
+ method of a component or to set a component's configuration
+ options.
+
+
Sub components: If a component is itself a megawidget containing
+ sub-components, then these sub-components can be referred to
+ using the notation component_subcomponent. For example,
+ Pmw.ComboBox has a component named entryfield which is an
+ instance of Pmw.EntryField, which itself has a Tkinter.Entry
+ component named entry. In the context of the combobox, this
+ entry widget can be referred to as entryfield_entry.
+
+
Component aliases: Because the sub-component notation may
+ make component names inconveniently long, components and
+ sub-components can be aliased to simpler names. For example,
+ the entryfield_entry sub-component of Pmw.ComboBox is aliased
+ to simply entry. If there is no conflict in component
+ names, sub-component names are usually aliased to the name of
+ the "leaf" component.
+
+
Component groups: Similar components of a megawidget can be
+ given a group name, which allows all components of a group
+ to be referenced using the one group name. For example, the
+ two arrow components of Pmw.Counter have a group name of Arrow.
+ Also, megawidgets that can create an unlimited number of
+ similar components, such as Pmw.ButtonBox, create each of these
+ components with the same group name. By convention, group
+ names begin with a capital letter.
+
+
+
+
+
+
Options
+
+ A megawidget defines options which allow the megawidget user
+ to modify the appearance and behaviour of the megawidget.
+ Using the same technique as Tkinter widgets, the values of
+ megawidget options may be set in calls to the constructor and
+ to configure() and the values may be queried by calls to
+ cget() and configure(). Like Tkinter widgets, megawidget
+ options are initialised with default values. Also, if the
+ useTkOptionDb option to Pmw.initialise() has been set,
+ then the Tk option database will be queried to get the initial
+ values. Strings found in the option database are converted
+ to python objects (integer, float, tuple, dictionary, etc)
+ using a restricted eval() call. Anything that is not accepted by
+ eval() is treated as a string.
+
+
Inherited options: As well as the options defined in a class,
+ a derived class inherits all options of its base classes. The
+ default value of an option defined by a base class may be
+ modified by the derived class.
+
+
Initialisation options: Some megawidget options can only be
+ set in the call to the constructor. These are called
+ initialisation options. Unlike normal configuration
+ options, they cannot be set by calling the configure()
+ method.
+
+
Component options: Options of the components of a megawidget
+ can be referred to using the notation component_option.
+ Like the megawidget options, component options can be used in
+ calls to the constructor and to the cget() and configure()
+ methods. For example, the state option of the Tkinter.Text
+ text component of Pmw.ScrolledText may be set by calling
+
widget.configure(text_state = 'disabled')
+
+
+
Sub-components, component aliases and component groups may
+ also be combined with options. For example, the state
+ option of the entryfield_entry component of Pmw.ComboBox
+ may be set by calling
Since it has an alias, it is more convenient to use the
+ equivalent form
+
combobox.configure(entry_state = 'normal')
+
+
+
Also, the background color of both arrows of Pmw.Counter
+ can be set using the Arrow component group.
+
counter.configure(Arrow_background = 'aliceblue')
+
+
+
+
+
+
+
The pyclass component option
+
+ The pyclass component option is a special notation that can
+ be used to specify a non-default python class for a component.
+ This can only be used when the component is being constructed.
+ For a component created during the construction of its parent
+ megawidget, this option must be given to the constructor in
+ the form component_pyclass. For example, to change the
+ python class of the text sub-component of Pmw.TextDialog
+ to a class FontText.Text
For components created after the construction of the parent
+ megawidget, the pyclass option must be passed into the
+ method which constructs the component. For example, to set
+ the python class of a button in Pmw.ButtonBox to a class
+ MyButton:
+
buttonBox.add('special', pyclass = MyButton)
+
+
+
The new python class of the component must support all methods
+ and options that are used by the megawidget when operating on
+ the component. The exact interface required for each
+ component is not documented. You will have to examine the Pmw
+ source code. However, any class derived from the default
+ class of a component can be used as the new class of the
+ component, as long as all of the original methods and options
+ are still supported. For example, any class derived from
+ Tkinter.Text can be used as the class of the text
+ sub-component of Pmw.TextDialog.
+
+
The pyclass component option should not be confused with the
+ class option that some of the Tk widgets support. The
+ class option sets the Tk option database class for the
+ widget and is used by Tk to query the database for the default
+ values of the widget's other options. The name pyclass was
+ chosen so that it did not conflict with any known Tk options.
+
+
+
+
+
+
Construction
+
+ The constructors of classes derived from this class all accept
+ the same arguments: one positional argument and any number of
+ keyword arguments. The positional argument defaults to None
+ (meaning the root window) and specifies the widget to use as
+ the parent when creating the
+ megawidget's hull component. The keyword arguments define
+ initial values for options. The format for the constructors
+ of derived classes is:
+
+
def __init__(self, parent = None, **kw):
+
+
+
+
+
+
+
Methods
+
+
addoptions(optionDefs)
+Add additional options for this megawidget. The optionDefs
+ argument is treated in the same way as for the defineoptions()
+ method.
+
This method is for use by derived classes. It is only used if a
+ megawidget should conditionally define some options, perhaps
+ depending on the value of other options. Usually, megawidgets
+ unconditionally define all their options in the call to
+ defineoptions() and do not need to use addoptions(). This
+ method must be called after the call to defineoptions() and
+ before the call to initialiseoptions().
+
+
+
+
+
+
cget(option)
+Return the current value of option (which should be in the
+ format described in the Options section). This method is also
+ available using object subscripting, for example
+ myWidget['font']. Unlike Tkinter's cget(), which always returns
+ a string, this method returns the same value and type as used when
+ the option was set (except where option is a component option
+ and the component is a Tkinter widget, in which case it returns
+ the string returned by Tcl/Tk).
+
+
+
+
+
component(name)
+Return the component widget whose name is name. This
+ allows the user of a megawidget to access and configure component
+ widgets directly.
+
+
+
+
+
componentaliases()
+Return the list of aliases for components. Each item in the list
+ is a tuple whose first item is the name of the alias and whose
+ second item is the name of the component or sub-component it
+ refers to.
+
+
+
+
+
componentgroup(name)
+Return the group of the component whose name is name or None
+ if it does not have a group.
+
+
+
+
+
components()
+Return a sorted list of names of the components of this
+ megawidget.
+
+
+
+
+
configure(option = None, **kw)
+Query or configure the megawidget options.
+
If no arguments are given, return a tuple consisting of all
+ megawidget options and values, each as a 5-element tuple
+ (name, resourceName, resourceClass, default, value).
+ This is in the same format as the value returned by the standard
+ Tkinter configure() method, except that the resource name is
+ always the same as the option name and the resource class is the
+ option name with the first letter capitalised.
+
+
If one argument is given, return the 5 element tuple for option.
+
+
Otherwise, set the configuration options specified by the keyword
+ arguments. Each key should be in the format described in the
+ Options section.
+Create a component widget by calling widgetClass with the
+ arguments given by widgetArgs and any keyword arguments. The
+ componentName argument is the name by which the component will
+ be known and must not contain the underscore, '_', character.
+ The componentGroup argument specifies the group of the
+ component. The componentAliases argument is a sequence of
+ 2-element tuples, whose first item is an alias name and whose
+ second item is the name of the component or sub-component it is to
+ refer to.
+
If this method is called during megawidget construction, any
+ component options supplied to the megawidget constructor which
+ refer to this component (by componentName or componentGroup)
+ are added to the kw dictionary before calling widgetClass. If
+ the dictionary contains a 'pyclass' key, then this item is
+ removed from the dictionary and the value is used instead of
+ widgetClass. For more details see The pyclass component option
+ section.
+
+
This method may be called by derived classes during or after
+ megawidget construction. It returns the instance of the class
+ created.
+
+
+
+
+
+
createlabel(parent, childCols = 1, childRows = 1)
+Create a Tkinter.Label component named 'label' in the parent
+ widget. This is a convenience method used by several megawidgets
+ that require an optional label. The widget must have options
+ named labelpos and labelmargin. If labelpos is None, no
+ label is created. Otherwise, a label is created and positioned
+ according to the value of labelpos and labelmargin. The label
+ is added to the parent using the grid() method, with childCols
+ and childRows indicating how many rows and columns the label
+ should span. Note that all other child widgets of the parent
+ must be added to the parent using the grid() method. The
+ createlabel() method may be called by derived classes during
+ megawidget construction.
+
+
+
+Create options for this megawidget. The optionDefs argument
+ defines the options. It is a sequence of 3-element tuples,
+ (name, default, callback), where name is the name of the
+ option, default is its default value and callback is the
+ function to call when the value of the option is set by a call to
+ configure(). The keywords argument should be the keyword
+ arguments passed in to the constructor of the megawidget. The user
+ may override the default value of an option by supplying a keyword
+ argument to the constructor.
+
If any option created by a base class is also defined by
+ optionDefs, then the derived class's default value will take
+ precedence over the base class's. If the callback field is not
+ None, then this will also override the callback set by the base
+ class.
+
+
If callback is Pmw.INITOPT, then the option is an
+ initialisation option.
+
+
The dynamicGroups argument contains a list of the groups of the
+ components created dynamically by this megawidget. If a group is
+ included in this list, then it not an error if a keyword argument
+ for the group is given to the constructor or to configure(),
+ even when no components with this group have been created.
+
+
If defineoptions() is called, it must be called once in the
+ megawidget constructor before the call to the constructor of the
+ base class and there must be a matching call to
+ initialiseoptions() at the end of the constructor.
+
+
+
+
+
+
destroy()
+Destroy the hull component widget, if it exists, including all
+ of its children.
+
+
+
+
+
destroycomponent(name)
+Remove the megawidget component called name. This method may be
+ called by derived classes to destroy a megawidget component. It
+ destroys the component widget and then removes all record of the
+ component from the megawidget.
+
+
+
+
+
hulldestroyed()
+Return true if the Tk widget corresponding to the hull component
+ has been destroyed.
+
+
+
+
+
initialiseoptions(dummy = None)
+Check keyword arguments and call option callback functions. This
+ method must be called, at the end of a megawidget constructor, if
+ and only if defineoptions() was also called in the constructor.
+ The dummy argument is not required, but is retained for
+ backwards compatibility.
+
It checks that all keyword arguments given to the constructor have
+ been used. If not, it raises an error indicating which arguments
+ were unused. A keyword is defined to be used if, during the
+ construction of a megawidget, it is defined in a call to
+ defineoptions() or addoptions() (by the megawidget or one of
+ its base classes), or it references, by name, a component of the
+ megawidget, or it references, by group, at least one component.
+ It also calls the configuration callback function for all options
+ that have a callback.
+
+
This method is only effective when called by the constructor of
+ the leaf class, that is, the class in the class hierarchy which
+ first called defineoptions(). For all other classes in the
+ class hierarchy (base classes), the method returns immediately.
+
+
+
+
+
+
interior()
+Return the widget framing the interior space in which any children
+ of this megawidget should be created. By default, this returns
+ the hull component widget, if one was created, or None
+ otherwise. A subclass should use the widget returned by
+ interior() as the parent of any components or sub-widgets it
+ creates. Megawidgets which can be further subclassed, such as
+ Pmw.Dialog, should redefine this method to return the widget in
+ which subclasses should create children. The overall containing
+ widget is always available as the hull component.
+
+
+
+
+
isinitoption(option)
+If option is an initialisation option, return true. Otherwise,
+ return false (the option is a configuration option). The option
+ argument must be an option of this megawidget, not an option of a
+ component. Otherwise an exception is raised.
+
+
+
+
+
options()
+Return a sorted list of this megawidget's options. Each item in
+ the list is a 3-element tuple, (option, default, isinit),
+ where option is the name of the option, default is its default
+ value and isinit is true if the option is an initialisation
+ option.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 22 May 1998
+
+ This class creates a megawidget contained within a toplevel
+ window. It may be used directly to create a toplevel megawidget
+ or it may be used as a base class for more specialised toplevel
+ megawidgets, such as Pmw.Dialog. It creates a Tkinter.Toplevel
+ component, named hull, to act as the container of the megawidget.
+ The window class name for the hull widget is set to the
+ most-specific class name for the megawidget. Derived classes
+ specialise this class by creating other widget components as
+ children of the hull widget.
+
+
The megawidget may be used as either a normal toplevel window or
+ as a modal dialog. Use show() and withdraw() for normal use
+ and activate() and deactivate() for modal dialog use. If the
+ window is deleted by the window manager while being shown
+ normally, the default behaviour is to destroy the window. If the
+ window is deleted by the window manager while the window is active
+ (ie: when used as a modal dialog), the window is deactivated.
+ Use the userdeletefunc() and usermodaldeletefunc() methods to
+ override these behaviours. Do not call protocol() to set the
+ WM_DELETE_WINDOW window manager protocol directly if you want to
+ use this window as a modal dialog.
+
+
The currently active windows form a stack with the most recently
+ activated window at the top of the stack. All mouse and
+ keyboard events are sent to this top window. When it
+ deactivates, the next window in the stack will start to receive
+ events.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is None.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaArchetype.
+In addition, methods from the
+Tkinter.Toplevel class
+are forwarded by this megawidget to the
+hull component.
+
+
+
+Display the window as a modal dialog. This means that all mouse
+ and keyboard events go to this window and no other windows can
+ receive any events. If you do not want to restrict mouse and
+ keyboard events to this window, use the show() method instead.
+
If the BLT extension to Tk is present, a busy cursor will be
+ displayed on other toplevel windows, using Pmw.showbusycursor().
+
+
The activate() method does not return until the deactivate()
+ method is called, when the window is withdrawn, the grab released
+ and the result returned.
+
+
If globalMode is false, the window will grab control of the
+ pointer and keyboard, preventing any events from being delivered
+ to any other toplevel windows within the application. If
+ globalMode is true, the grab will prevent events from being
+ delivered to any other toplevel windows regardless of application.
+ Global grabs should be used sparingly, if at all.
+
+
If globalMode is 'nograb', then no grab is performed. If BLT
+ is present, this will allow mouse and keyboard events to be
+ received by other windows whose exclude busycursor attribute has
+ been set to true by a call to Pmw.setbusycursorattributes().
+ Note that if 'nograb' is used and BLT is not present, then all
+ other windows will receive mouse and keyboard events. This is
+ because, in plain Tk, there is no way to specify that two windows
+ (only) receive events. If your application may be used without
+ BLT, then do not use 'nograb'.
+
+
When the window is displayed, it is positioned on the screen
+ according to geometry which may be one of:
+
+
centerscreenfirst
The window will be centered the first time it is activated.
+ On subsequent activations it will be positioned in the same
+ position as the last time it was displayed, even if it has
+ been moved by the user.
+
+
+
centerscreenalways
The window will be be centered on the screen (halfway across
+ and one third down).
+
+
+
first + spec
It is assumed that the rest of the argument (after 'first')
+ is a standard geometry specification. The window will be
+ positioned using this specification the first time it is
+ activated. On subsequent activations it will be positioned in
+ the same position as the last time it was displayed, even if
+ it has been moved by the user. For example,
+ geometry = first+100+100 will initially display the window
+ at position (100,100). Other calls to activate() will not
+ change the previous position of the window.
+
+
+
spec
This is a standard geometry specification. The window will be
+ be positioned using this specification.
+
+
+
If the BLT Tcl extension library is present, a clock cursor
+ will be displayed until the window is deactivated.
+
+
If the activatecommand option is callable, it is called just
+ before the window begins to wait for the result.
+
+
If the master option is not None, the window will become a
+ transient window of master, which should be a toplevel window.
+ If master has the special value of 'parent', the master is the
+ toplevel window of the window's parent.
+
+
+
+
+
+
active()
+Return true if the megawidget is currently active (that is,
+ activate() is currently waiting for a result to be passed to it
+ by a call to deactivate()).
+
+
+
+
+
deactivate(result = None)
+This should be called while a call to activate() is waiting. It
+ will withdraw the window, release the grab and cause the
+ activate() call to return with the value of result.
+
If the deactivatecommand option is callable, it is called just
+ before the deactivate() method returns.
+
+
+
+
+
+
destroy()
+Destroy the hull component widget, including all of its
+ children. If the megawidget is currently active, deactivate it.
+
+
+
+
+
show(master = None)
+Make the window visible. This raises or deiconifies the toplevel
+ window. If the window has previously been shown it will remain in
+ the same position. This means that calling withdraw() then
+ show() will not move the window, whereas calling withdraw()
+ then deiconify() may change the window's position. (This may
+ depend on the behaviour of the window manager.)
+
+
+
+
+
userdeletefunc(func = None)
+If func is None, return the function that will be called
+ when the window is deleted by the window manager while being
+ displayed normally. If func is not None, set this function to
+ func. By default, the function is self.destroy.
+
+
+
+
+
usermodaldeletefunc(func = None)
+If func is None, return the function that will be called
+ when the window is deleted by the window manager while it is
+ active (ie: when being used as a modal dialog). If func is not
+ None, set this function to func. By default, the function is
+ self.deactivate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 22 May 1998
+
+ This class creates a megawidget contained within a Tkinter.Frame
+ window. The class acts as the base class for megawidgets that are
+ not contained in their own toplevel window, such as Pmw.ButtonBox and
+ Pmw.ComboBox. It creates a Tkinter.Frame component, named hull,
+ to act as the container of the megawidget. The window class name
+ for the hull widget is set to the most-specific class name for
+ the megawidget. Derived classes specialise this class by
+ creating other widget components as children of the hull widget.
+
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
+
Methods
+This megawidget has no methods of its own.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaArchetype.
+In addition, methods from the
+Tkinter.Frame class
+are forwarded by this megawidget to the
+hull component.
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 22 May 1998
+
+ A menu bar is a container megawidget which manages a number of
+ menu buttons and dropdown menus. There
+ are methods to add menu buttons and menus to the menu bar and for
+ adding menu items to the menus. Menu buttons may be added to the
+ left or right of the megawidget. Each menu button and menu item may
+ have help text to be displayed by a Pmw.Balloon. Each menu
+ and cascaded menu (sub-menu) is referenced by name which is
+ supplied on creation.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
balloon
+
+Specifies a Pmw.Balloon to display the help text for menu
+ buttons and menu items. If None, no help is displayed. If the
+ balloon has an associated Pmw.MessageBar, the help text will also be
+ displayed there. The default is None.
+
+
+
+
+
hotkeys
+
+Initialisation option. If true, keyboard accelerators will be assigned to each menu
+ button and menu item. Keyboard accelerators can be used to access
+ the menus without using the mouse. The accelerator character is
+ always one of the alphanumeric characters in the text label of the
+ menu or menu item and is indicated by an underline.
+
To select a menu, simultaneously press the <Alt> key and the
+ accelerator character indicated on a menu button. The arrows keys
+ can then be used to select other menus and menu items. To invoke a
+ menu item, press <Return> or press the accelerator character
+ indicated on the menu item.
+
+
Each accelerator character will be assigned automatically unless
+ traverseSpec is supplied to the addmenu(), addmenuitem() or
+ addcascademenu() methods. The automatically selected
+ accelerator character for a menu button (or menu item) is the
+ first character in the label text that has not already been used
+ as an accelerator for a menu button (or in the menu containing the
+ menu item).
+
+
If traverseSpec is given, it must be either an integer or a
+ character. If an integer, it specifies the index of the character
+ in the label text to use as the accelerator character. If a
+ character, it specifies the character to use as the accelerator
+ character. The default is 1.
+
+
+
+
+
+
padx
+
+Initialisation option. Specifies a padding distance to leave between each menu button in
+ the x direction and also between the menu buttons and the outer
+ edge of the menu bar. The default is 0.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Dynamic components
+
+ Menu button components are created dynamically by the
+ addmenu() method. By default, these are of type
+ Tkinter.Menubutton and are created with a component group of
+ Button.
+
+
Menu components are created dynamically by the addmenu() and
+ addcascademenu() methods. By default, these are of type
+ Tkinter.Menu and are created with a component group of Menu.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
+Add a cascade menu (sub-menu) to the menu parentMenuName. The
+ menuName argument must not be the same as any menu already
+ created using the addmenu() or addcascademenu() methods.
+
A menu item in the parent menu is created (with the
+ add_cascade() method of the parent menu) using all keyword
+ arguments except tearoff.
+
+
If the label keyword argument is not given, the label option
+ of the menu item defaults to menuName. If the underline
+ keyword argument is not given (and the hotkeys megawidget option
+ is true) the underline option is determined as described under
+ hotkeys and is used to specify the keyboard accelerator.
+
+
The statusHelp argument is used as the help string for the menu
+ item. This is displayed using the showstatus() method of the
+ balloon.
+
+
The tearoff keyword argument, if present, is passed to the
+ constructor of the menu. The menu is created as a component named
+ menuName-menu.
+Add a menu button and its associated menu to the menu bar. The
+ menuName argument must not be the same as any menu already
+ created using the addmenu() or addcascademenu() methods.
+
Any keyword arguments present (except tearoff) will be passed to
+ the constructor of the menu button. If the text keyword
+ argument is not given, the text option of the menu button
+ defaults to menuName. If the underline keyword argument is
+ not given (and the hotkeys megawidget option is true) the
+ underline option is determined as described under hotkeys and
+ is used to specify the keyboard accelerator. Each menu button is
+ packed into the menu bar using the given side, which should be
+ either left or right. The menu button is created as a
+ component named menuName-button.
+
+
If the balloon option has been defined, balloonHelp and
+ statusHelp are passed to the balloon as the help strings for the
+ menu button. See the bind() method of Pmw.Balloon for how these
+ strings may be displayed.
+
+
The tearoff keyword argument, if present, is passed to the
+ constructor of the menu. The menu is created as a component named
+ menuName-menu.
+Add a menu item to the menu menuName. The kind of menu item is
+ given by itemType and may be one of command, separator,
+ checkbutton, radiobutton or cascade (although cascade menus
+ are better added using the addcascademenu() method). Any
+ keyword arguments present will be passed to the menu when creating
+ the menu item. See Tkinter.Menu for the valid options for each
+ item type. In addition, a keyboard accelerator may be
+ automatically given to the item, as described under hotkeys.
+
When the mouse is moved over the menu item, the helpString will
+ be displayed by the balloon's statuscommand.
+
+
+
+
+
+
deletemenu(menuName)
+Delete the menu menuName and all its items. The menu may either
+ be a toplevel menu (in which case the corresponding menu button is
+ also deleted) or a cascade menu.
+
+
+
+
+
deletemenuitems(menuName, start, end = None)
+Delete menu items from the menu menuName. If end is not
+ given, the start item is deleted. Otherwise all items from
+ start to end are deleted.
+
+
+
+
+
disableall()
+Disable all toplevel menus.
+
+
+
+
+
enableall()
+Enable all toplevel menus.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the Balloon.
+ self.balloon = Pmw.Balloon(parent)
+
+ # Create and pack the MenuBar.
+ menuBar = Pmw.MenuBar(parent,
+ hull_relief = 'raised',
+ hull_borderwidth = 1,
+ balloon = self.balloon)
+ menuBar.pack(fill = 'x')
+ self.menuBar = menuBar
+
+ # Add some buttons to the MenuBar.
+ menuBar.addmenu('File', 'Close this window or exit')
+ menuBar.addmenuitem('File', 'command', 'Close this window',
+ command = PrintOne('Action: close'),
+ label = 'Close')
+ menuBar.addmenuitem('File', 'separator')
+ menuBar.addmenuitem('File', 'command', 'Exit the application',
+ command = PrintOne('Action: exit'),
+ label = 'Exit')
+
+ menuBar.addmenu('Edit', 'Cut, copy or paste')
+ menuBar.addmenuitem('Edit', 'command', 'Delete the current selection',
+ command = PrintOne('Action: delete'),
+ label = 'Delete')
+
+ menuBar.addmenu('Options', 'Set user preferences')
+ menuBar.addmenuitem('Options', 'command', 'Set general preferences',
+ command = PrintOne('Action: general options'),
+ label = 'General...')
+
+ # Create a checkbutton menu item.
+ self.toggleVar = Tkinter.IntVar()
+ # Initialise the checkbutton to 1:
+ self.toggleVar.set(1)
+ menuBar.addmenuitem('Options', 'checkbutton', 'Toggle me on/off',
+ label = 'Toggle',
+ command = self._toggleMe,
+ variable = self.toggleVar)
+ self._toggleMe()
+
+ menuBar.addcascademenu('Options', 'Size',
+ 'Set some other preferences', traverseSpec = 'z', tearoff = 1)
+ for size in ('tiny', 'small', 'average', 'big', 'huge'):
+ menuBar.addmenuitem('Size', 'command', 'Set size to ' + size,
+ command = PrintOne('Action: size ' + size),
+ label = size)
+
+ menuBar.addmenu('Help', 'User manuals', side = 'right')
+ menuBar.addmenuitem('Help', 'command', 'About this application',
+ command = PrintOne('Action: about'),
+ label = 'About...')
+
+ # Create and pack the main part of the window.
+ self.mainPart = Tkinter.Label(parent,
+ text = 'This is the\nmain part of\nthe window',
+ background = 'black',
+ foreground = 'white',
+ padx = 30,
+ pady = 30)
+ self.mainPart.pack(fill = 'both', expand = 1)
+
+ # Create and pack the MessageBar.
+ self.messageBar = Pmw.MessageBar(parent,
+ entry_width = 40,
+ entry_relief='groove',
+ labelpos = 'w',
+ label_text = 'Status:')
+ self.messageBar.pack(fill = 'x', padx = 10, pady = 10)
+ self.messageBar.message('state', 'OK')
+
+ buttonBox = Pmw.ButtonBox(parent)
+ buttonBox.pack(fill = 'x')
+ buttonBox.add('Disable\nall', command = menuBar.disableall)
+ buttonBox.add('Enable\nall', command = menuBar.enableall)
+ buttonBox.add('Create\nmenu', command = self.add)
+ buttonBox.add('Delete\nmenu', command = self.delete)
+ buttonBox.add('Create\nitem', command = self.additem)
+ buttonBox.add('Delete\nitem', command = self.deleteitem)
+
+ # Configure the balloon to displays its status messages in the
+ # message bar.
+ self.balloon.configure(statuscommand = self.messageBar.helpmessage)
+
+ self.testMenuList = []
+
+ def _toggleMe(self):
+ print 'Toggle value:', self.toggleVar.get()
+
+ def add(self):
+ if len(self.testMenuList) == 0:
+ num = 0
+ else:
+ num = self.testMenuList[-1]
+ num = num + 1
+ name = 'Menu%d' % num
+ self.testMenuList.append(num)
+
+ self.menuBar.addmenu(name, 'This is ' + name)
+
+ def delete(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[0]
+ name = 'Menu%d' % num
+ del self.testMenuList[0]
+ self.menuBar.deletemenu(name)
+
+ def additem(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[-1]
+ menuName = 'Menu%d' % num
+ menu = self.menuBar.component(menuName + '-menu')
+ if menu.index('end') is None:
+ label = 'item X'
+ else:
+ label = menu.entrycget('end', 'label') + 'X'
+ self.menuBar.addmenuitem(menuName, 'command', 'Help for ' + label,
+ command = PrintOne('Action: ' + menuName + ': ' + label),
+ label = label)
+
+ def deleteitem(self):
+ if len(self.testMenuList) == 0:
+ self.menuBar.bell()
+ else:
+ num = self.testMenuList[-1]
+ menuName = 'Menu%d' % num
+ menu = self.menuBar.component(menuName + '-menu')
+ if menu.index('end') is None:
+ self.menuBar.bell()
+ else:
+ self.menuBar.deletemenuitems(menuName, 0)
+
+class PrintOne:
+ def __init__(self, text):
+ self.text = text
+
+ def __call__(self):
+ print self.text
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 22 April 2000
+
+ A message bar contains a single-line message display area. Messages
+ of several different types may displayed. Messages are cleared
+ after a period defined for each message type. Each message type
+ has a priority so that if the application attempts to display more
+ than one message at a time, the message with the highest priority
+ will be displayed. Messages may be accompanied by a number of
+ audible bells.
+
+
This megawidget can be used for both interactive help messages
+ (when the mouse enters certain widgets) and also for other general
+ messages.
+
+
To perform the help function it can cooperate with the Pmw.Balloon
+ megawidget so that the programmer (or user) can choose either
+ balloon help, message bar help, both or neither.
+
+
This megawidget supports a configurable number of message types.
+ The default types include 'state', 'help', 'usererror' and
+ 'systemerror'. The difference between these are the length of
+ time they are displayed, the number of bells that are rung and the
+ priority of the message. For example, the 'help' message type
+ is lower in priority than the 'usererror', so that error
+ messages will always be displayed in preference to help messages
+ regardless of the order the messages are created. The 'state'
+ message type is lowest in priority but has no timeout, so it
+ should contain messages describing the current state of the
+ application, such as Waiting for database connection or 'Waiting
+ for file to be unlocked'. Generally this should be set to the
+ empty string when the application is running normally. By default
+ the help messages (with message type 'help') time out after 5
+ seconds, so that if the cursor happens to be left over a widget,
+ the application state will be redisplayed after a short time.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
messagetypes
+
+Initialisation option. This defines what message types are supported by the message bar
+ and the characteristics of those message types. It is a
+ dictionary where the key is a string specifying a message type and
+ the value is a tuple of four integers, (priority, showtime,
+ bells, logmessage), where priority is the rank of the
+ message type, showtime is the number of seconds to display
+ messages of this message type, bells is the number of audible
+ bells to ring and logmessage is a boolean
+ specifying whether this message should be logged for retrieval
+ later. Messages with a higher priority are displayed in
+ preference to those with lower priority. If a high priority
+ message times out (because it has been displayed for showtime
+ seconds), then a lower priority message may be displayed. A
+ showtime of 0 means that the message will never time out and
+ is useful for displaying messages describing the current state of
+ the application as opposed to messages describing events. Logging
+ is not currently implemented. The default is
+
+If true, no audible bells will sound, regardless of the value for
+ bells defined in the messagetypes option. The default is 0.
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
entry
+
+The widget where the messages are displayed. Long messages may be
+ scrolled horizontally by dragging with the middle mouse button. By default, this component is a Tkinter.Entry.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Entry class
+are forwarded by this megawidget to the
+entry component.
+
+
+
helpmessage(text)
+A convenience method to display text in the message bar
+ according to the characteristics defined by the help message type.
+ Equivalent to message('help', text).
+
+
+
+
+
message(type, text)
+Display text in the message bar according to the characteristics
+ defined by the type message type, as discussed under
+ messagetypes.
+
+
+
+
+
resetmessages(type)
+Clear the type message and all message types with a lower
+ priority, except permanent messages, such as state. This is
+ useful to clear the busy message and any outstanding event and
+ help messages.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack the MessageBar.
+ self._messagebar = Pmw.MessageBar(parent,
+ entry_width = 40,
+ entry_relief='groove',
+ labelpos = 'w',
+ label_text = 'Status:')
+ self._messagebar.pack(side = 'bottom', fill = 'x',
+ expand = 1, padx = 10, pady = 10)
+
+ # Create and pack the ScrolledListBox to change the MessageBar.
+ self.box = Pmw.ScrolledListBox(parent,
+ listbox_selectmode='single',
+ items=('state', 'help', 'userevent', 'systemevent',
+ 'usererror', 'systemerror', 'busy',),
+ label_text='Message type',
+ labelpos='n',
+ selectioncommand=self.selectionCommand)
+ self.box.pack(fill = 'both', expand = 'yes', padx = 10, pady = 10)
+
+ self._index = 0
+ self._stateCounter = 0
+
+ def selectionCommand(self):
+ sels = self.box.getcurselection()
+ if len(sels) > 0:
+ self._index = self._index + 1
+ messagetype = sels[0]
+ if messagetype == 'state':
+ self._stateCounter = (self._stateCounter + 1) % 3
+ text = stateMessages[self._stateCounter]
+ if text != '':
+ text = text + ' (' + messagetype + ')'
+ self._messagebar.message('state', text)
+ else:
+ text = messages[messagetype]
+ text = text + ' (' + messagetype + ')'
+ self._messagebar.message(messagetype, text)
+ if messagetype == 'busy':
+ Pmw.showbusycursor()
+ self.box.after(2000)
+ Pmw.hidebusycursor()
+ self._messagebar.resetmessages('busy')
+ text = 'All files successfully removed'
+ text = text + ' (userevent)'
+ self._messagebar.message('userevent', text)
+
+
+messages = {
+ 'help': 'Save current file',
+ 'userevent': 'Saving file "foo"',
+ 'busy': 'Busy deleting all files from file system ...',
+ 'systemevent': 'File "foo" saved',
+ 'usererror': 'Invalid file name "foo/bar"',
+ 'systemerror': 'Failed to save file: file system full',
+}
+
+stateMessages = {
+ 0: '',
+ 1: 'Database is down',
+ 2: 'Waiting for reply from database',
+}
+
+
+ A message dialog is a dialog window which displays a simple
+ message to the user along with one or more buttons to press.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the text message and icon. The default is 20.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the text message and icon. The default is 20.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
iconmargin
+
+Initialisation option. The padding between the text message and icon. The default is 20.
+
+
+
+
+
iconpos
+
+Initialisation option. Specifies on which side of the text message to place the icon.
+ Must be one of 'n', 's', 'e' or 'w'. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
icon
+
+If the iconpos option is not None, this component is created
+ to contain the icon label for the dialog. To display a bitmap as
+ an icon, set the icon_bitmap component option to any of the
+ forms acceptable to Tk, such as 'warning' or 'error'. By default, this component is a Tkinter.Label.
+
+
+
+
+
message
+
+The label to contain the text message for the dialog. To set
+ the text, use the message_text component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
+
Methods
+This megawidget has no methods of its own.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ self.parent = parent
+
+ # Create dialog 1.
+ self.dialog1 = Pmw.MessageDialog(parent,
+ title = 'Simple message dialog',
+ defaultbutton = 0,
+ message_text = 'A simple message dialog\nwith no callback.')
+ self.dialog1.iconname('Simple message dialog')
+ self.dialog1.withdraw()
+
+ # Create dialog 2.
+ self.dialog2 = Pmw.MessageDialog(parent,
+ title = 'Bell ringing dialog',
+ message_text = 'This message dialog\nwill ring the bell ' +
+ 'when\nyou click on the buttons.',
+ iconpos = 'w',
+ icon_bitmap = 'error',
+ command = self.execute2,
+ buttons = ('One', 'Two', 'Three', 'Close'))
+ self.dialog2.iconname('Bell ringing dialog')
+ self.dialog2.withdraw()
+
+ # Create dialog 3.
+ self.dialog3 = Pmw.MessageDialog(parent,
+ title = 'Vertical button dialog',
+ message_text = 'This message dialog\nhas the buttons on the\n' +
+ 'right hand side.',
+ buttonboxpos = 'e',
+ iconpos = 'n',
+ icon_bitmap = 'warning',
+ buttons = ('Goodbye', 'Au revoir', 'Sayonara', 'Close'),
+ defaultbutton = 'Close')
+ self.dialog3.iconname('Vertical button dialog')
+ self.dialog3.withdraw()
+
+ # Create some buttons to launch the dialogs.
+ w = Tkinter.Button(parent, text = 'Simple dialog',
+ command = lambda self = self:
+ self.dialog1.activate(geometry = 'first+100+100'))
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text = 'Bell ringing dialog',
+ command = self.dialog2.activate)
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text = 'Vertical buttons',
+ command = self.dialog3.activate)
+ w.pack(padx = 8, pady = 8)
+
+ w = Tkinter.Button(parent, text = 'On the fly dialog',
+ command = self._createOnTheFly)
+ w.pack(padx = 8, pady = 8)
+
+ def execute2(self, result):
+ print 'You clicked on', result
+ if result is None:
+ self.dialog2.deactivate(result)
+ elif result == 'Close':
+ self.dialog2.deactivate(result)
+ else:
+ for count in range({'One': 1, 'Two': 2, 'Three': 3}[result]):
+ if count != 0:
+ self.dialog2.after(200)
+ self.dialog2.bell()
+
+ def _createOnTheFly(self):
+ dialog = Pmw.MessageDialog(self.parent,
+ title = 'On the fly dialog',
+ defaultbutton = 0,
+ buttons = ('OK', 'Apply', 'Cancel', 'Help'),
+ message_text = 'This dialog was created when you clicked ' +
+ 'on the button.')
+ dialog.iconname('Simple message dialog')
+ result = dialog.activate()
+
+ print 'You selected', result
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ A notebook contains a set of tabbed pages. At any one time only
+ one of these pages (the selected page) is visible, with the
+ other pages being hidden "beneath" it. Another page in the
+ notebook may be displayed by clicking on the tab attached to the
+ page. The tabs are displayed along the top edge.
+
+
Optionally, the notebook may be displayed without tabs. In this
+ case, another selection widget, such as Pmw.OptionMenu, may be used
+ to select the pages.
+
+
This megawidget is derived from Pmw.MegaArchetype (not Pmw.MegaWidget
+ like most other megawidgets), with the hull class being
+ Tkinter.Canvas.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
arrownavigation
+
+Initialisation option. If true and a tab button has the keyboard focus, then the Left and
+ Right arrow keys can be used to select the page before or after
+ the tab button with the focus. The default is 1.
+
+
+
+
+
borderwidth
+
+Initialisation option. The width of the border drawn around each tab and around the
+ selected page. The default is 2.
+
+
+
+
+
createcommand
+
+Specifies a function to call when a page is selected for the first
+ time. The function is called with a single argument, which is the
+ name of the selected page, and is called before the raisecommand
+ function. This allows the creation of the page contents to be
+ deferred until the page is first displayed. The default is None.
+
+
+
+
+
lowercommand
+
+Specifies a function to call when the selected page is replaced
+ with a new selected page. The function is called with a single
+ argument, which is the name of the previously selected page, and
+ is called before the createcommand or raisecommand functions. The default is None.
+
+
+
+
+
pagemargin
+
+Initialisation option. The margin (in pixels) around the selected page inside the
+ notebook's page border. The default is 4.
+
+
+
+
+
raisecommand
+
+Specifies a function to call when a new page is selected. The
+ function is called with a single argument, which is the name of
+ the selected page. The default is None.
+
+
+
+
+
tabpos
+
+Initialisation option. Specifies the location of the tabs. If 'n', tabs are created
+ for each page and positioned at the top of the notebook. If
+ None, no tabs are created, in which case another selection
+ widget can be used to select pages by calling the selectpage()
+ method. The default is 'n'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the megawidget. The contents of the
+ megawidget are created as canvas items and positioned in the
+ hull using the canvas coordinate system. By default, this component is a Tkinter.Canvas.
+
+
+
+
+
Dynamic components
+
+ Page and tab components are created dynamically by the add()
+ and insert() methods. By default, the pages are of type
+ Tkinter.Frame and are created with a component group of Page
+ and the tabs are of type Tkinter.Button and are created with a
+ component group of Tab.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaArchetype.
+In addition, methods from the
+Tkinter.Canvas class
+are forwarded by this megawidget to the
+hull component.
+
+
+
add(pageName, **kw)
+Add a page at the end of the notebook. See the insert() method
+ for full details.
+
+
+
+
+
delete(*pageNames)
+Delete the pages given by pageNames from the notebook. Each of
+ the pageNames may have any of the forms accepted by the
+ index() method.
+
If the currently selected page is deleted, then the next page, in
+ index order, is selected. If the end page is deleted, then the
+ previous page is selected.
+
+
+
+
+
+
getcurselection()
+Return the name of the currently selected page.
+
+
+
+
+
index(index, forInsert = 0)
+Return the numerical index of the page corresponding to index.
+ This may be specified in any of the following forms:
+
name
Specifies the page labelled name.
+
+
+
number
Specifies the page numerically, where 0 corresponds to
+ the first page.
+
+
+
Pmw.END
Specifies the last page.
+
+
+
Pmw.SELECT
Specifies the currently selected page.
+
+
+
If forInsert is true, Pmw.END returns the number of pages
+ rather than the index of the last page.
+
+
+
+
+
+
insert(pageName, before = 0, **kw)
+Add a page to the notebook as a component named pageName. The
+ page is added just before the page specified by before, which
+ may have any of the forms accepted by the index() method. If
+ tabpos is not None, also create a tab as a component named
+ pageName-tab. Keyword arguments prefixed with page_ or
+ tab_ are passed to the respective constructors when creating the
+ page or tab. If the tab_text keyword argument is not given, the
+ text option of the tab defaults to pageName. If a page is
+ inserted into an empty notebook, the page is selected. To add a
+ page to the end of the notebook, use add(). The method returns
+ the pageName component widget.
+
+
+
+
+
nextpage(pageIndex = None)
+If pageIndex is None, then select the page after the
+ currently selected page. Otherwise select the page after
+ pageIndex, which may have any of the forms accepted by the
+ index() method.
+
+
+
+
+
page(pageIndex)
+Return the frame component widget of the page pageIndex, where
+ pageIndex may have any of the forms accepted by the index()
+ method.
+
+
+
+
+
pagenames()
+Return a list of the names of the pages, in display order.
+
+
+
+
+
previouspage(pageIndex = None)
+If pageIndex is None, then select the page before the
+ currently selected page. Otherwise select the page before
+ pageIndex, which may have any of the forms accepted by the
+ index() method.
+
+
+
+
+
recolorborders()
+Change the color of the page and tab borders. This method is
+ required because the borders are created as canvas polygons and
+ hence do not respond to normal color changing techniques, such as
+ Pmw.Color.changecolor().
+
+
+
+
+
selectpage(page)
+Select page to be the currently selected page. The page will be
+ raised and the previous selected page will be lowered.
+
+
+
+
+
setnaturalsize(pageNames = None)
+Set the width and height of the notebook to be the maximum
+ requested width and height of the pages specified by pageNames.
+ If pageNames is None, the size of all pages are used to
+ determine the size of the notebook. Otherwise, pageNames must
+ be a list of page names whose sizes are to be used to determine
+ the size of the notebook. This method should be called after all
+ pages and their contents have been created. It calls
+ update_idletasks() so that the width and height of the pages can
+ be determined. This may cause the notebook to flash onto the
+ screen at the default size before resizing to the natural size.
+
+
+
+
+
tab(pageIndex)
+Return the tab component widget of the page pageIndex, where
+ pageIndex may have any of the forms accepted by the index()
+ method. If tabpos is None, return None.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack the NoteBook.
+ notebook = Pmw.NoteBook(parent)
+ notebook.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
+
+ # Add the "Appearance" page to the notebook.
+ page = notebook.add('Appearance')
+ notebook.tab('Appearance').focus_set()
+
+ # Create the "Toolbar" contents of the page.
+ group = Pmw.Group(page, tag_text = 'Toolbar')
+ group.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
+ b1 = Tkinter.Checkbutton(group.interior(), text = 'Show toolbar')
+ b1.grid(row = 0, column = 0)
+ b2 = Tkinter.Checkbutton(group.interior(), text = 'Toolbar tips')
+ b2.grid(row = 0, column = 1)
+
+ # Create the "Startup" contents of the page.
+ group = Pmw.Group(page, tag_text = 'Startup')
+ group.pack(fill = 'both', expand = 1, padx = 10, pady = 10)
+ home = Pmw.EntryField(group.interior(), labelpos = 'w',
+ label_text = 'Home page location:')
+ home.pack(fill = 'x', padx = 20, pady = 10)
+
+ # Add two more empty pages.
+ page = notebook.add('Helpers')
+ page = notebook.add('Images')
+
+ notebook.setnaturalsize()
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 30 October 1999
+
+ An option menu consists of a menu button
+ and an associated menu which pops up when the button is pressed.
+ The text displayed in the menu button is updated whenever an item
+ is selected in the menu. The currently selected value can be
+ retrieved from the megawidget.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
command
+
+Specifies a function to call whenever a menu item is selected or
+ the invoke() method is called. The function is called with the
+ currently selected value as its single argument. The default is None.
+
+
+
+
+
initialitem
+
+Initialisation option. Specifies the initial selected value. This option is treated in
+ the same way as the index argument of the setitems() method. The default is None.
+
+
+
+
+
items
+
+Initialisation option. A sequence of strings containing the initial items to be displayed
+ in the menu component. The default is ().
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
menu
+
+The popup menu displayed when the menubutton is pressed. By default, this component is a Tkinter.Menu.
+
+
+
+
+
menubutton
+
+The menu button displaying the currently selected value. By default, this component is a Tkinter.Menubutton.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
getcurselection()
+Same as getvalue() method.
+
+
+
+
+
getvalue()
+Return the currently selected value.
+
+
+
+
+
index(index)
+Return the numerical index of the menu item corresponding to
+ index. This may be specified in any of the following forms:
+
name
Specifies the menu item labelled name.
+
+
+
number
Specifies the menu item numerically, where 0 corresponds to
+ the first menu item.
+
+
+
Pmw.END
Specifies the last menu item.
+
+
+
Pmw.SELECT
Specifies the currently selected menu item.
+
+
+
+
+
+
+
invoke(index = Pmw.SELECT)
+Calling this method is the same as selecting the menu item
+ specified by index: the text displayed by the
+ menubutton component is updated and the function specified by
+ the command option is called. index may have any of the
+ forms accepted by the index() method. The value returned by
+ command is returned.
+
+
+
+
+
setitems(items, index = None)
+Replace all the items in the menu component with those specified
+ by items, which must be a sequence of strings.
+
If index is not None, set the selected value to index, which
+ may have any of the forms accepted by the index() method.
+
+
If index is None and the textvariable option of the
+ menubutton component is the empty string, then if
+ the previous selected value is one of the items, then do not
+ change the selection. If the previous selected value is no longer
+ in items, then set the selected value to the first value in
+ items. If items is empty, set the selected value to the empty
+ string.
+
+
If index is None and the textvariable option of the
+ menubutton component is not the empty string, then do not set
+ the selected value. This assumes that the variable is already (or
+ will be) set to the desired value.
+
+
+
+
+
+
setvalue(text)
+Set the text displayed by the menubutton component to text.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A paned widget is a container megawidget which manages a number of
+ resizable frames, known as panes. Each pane may act as the container for
+ other widgets. The user may interactively resize the panes by
+ dragging a small rectangle (the handle) or the line between the
+ panes (the separator). The panes may be arranged horizontally or
+ vertically. Each pane may have maximum and minimum limits of its
+ size.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
command
+
+Specifies a function to be called whenever the size of any of the
+ panes changes. The function is called with a single argument,
+ being a list of the sizes of the panes, in order. For vertical
+ orientation, the size is the height of the panes. For
+ horizontal orientation, the size is the width of the panes. The default is None.
+
+
+
+
+
handlesize
+
+Initialisation option. Specifies the size in pixels of the square handle which appears on
+ the lines separating the panes. The default is 8.
+
+
+
+
+
orient
+
+Initialisation option. Specifies the orientation of the paned widget. This may be
+ 'horizontal' or 'vertical'. If 'vertical', the panes are
+ stacked above and below each other, otherwise the panes are laid
+ out side by side. The default is 'vertical'.
+
+
+
+
+
separatorrelief
+
+Initialisation option. Specifies the relief of the lines separating the panes. The default is 'sunken'.
+
+
+
+
+
separatorthickness
+
+Initialisation option. Specifies the thickness of the lines separating the panes. The default is 2.
+
+
+
+
+
Pane options
+
+ Each pane has the following options. These may be set when
+ creating or configuring a pane. The value of each option may
+ be an integer, which specifies a pane size in pixels, or a
+ real number between 0.0 and 1.0, which specifies a pane size
+ proportional to the size of the entire paned widget.
+
+
size
Specifies the initial size of the pane. The default is 0.
+
+
+
min
Specifies the minimum size of the pane. The default is 0.
+
+
+
max
Specifies the maximum size of the pane. The default is a
+ very large number.
+
+
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Dynamic components
+
+ Frame, separator and handle components are created dynamically
+ by the add() and insert() methods. The components are of type
+ Tkinter.Frame and are created with component groups of
+ Frame, Separator and Handle respectively.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
add(name, **kw)
+Add a pane to the end of the paned widget as a component named
+ name. This is equivalent to calling insert() with before
+ set to the current number of panes. The method returns the name
+ component widget.
+
+
+
+
+
configurepane(name, **kw)
+Configure the pane specified by name, where name is either an
+ integer, specifying the index of the pane, or a string, specifying
+ the name of the pane. The keyword arguments specify the new
+ values for the options for the pane. These options are described
+ in the Pane options section.
+
+
+
+
+
delete(name)
+Delete the pane specified by name, where name is either an
+ integer, specifying the index of the pane, or a string, specifying
+ the name of the pane.
+
If the pane deleted was not the only pane in the paned widget,
+ also delete the separator and handle components named
+ separator-n and handle-n, where n is the number of
+ panes remaining.
+
+
+
+
+
+
insert(name, before = 0, **kw)
+Add a pane to the paned widget as a component named name. The
+ pane is added just before the pane specified by before, where
+ before may be either an integer, specifying the index of the
+ pane, or a string, specifying the name of the pane. The keyword
+ arguments specify the initial values for the options for the new
+ pane. These options are described in the Pane options section.
+ To add a pane to the end of the paned widget, use add().
+
The new pane is created as a Tkinter.Frame component named name.
+ If this is not the only pane, a separator and handle are also
+ created as components named separator-n and handle-n,
+ where n is one less than the number of panes. The method
+ returns the name component widget.
+
+
+
+
+
+
move(name, newPos, newPosOffset = 0)
+Move the pane specified by name to the new position specified by
+ newPos. The first two arguments may be either an integer,
+ specifying the index of the pane, or a string, specifying the name
+ of the pane. If newPosOffset is specified, it is added to the
+ newPos index. For example, to move a horizontal pane one pane
+ to the left, specify the name or index of the pane for both name
+ and newPos and specify -1 for newPosOffset.
+
+
+
+
+
pane(name)
+Return the Tkinter.Frame pane widget for the pane specified by
+ name, where name is either an integer, specifying the index of
+ the pane, or a string, specifying the name of the pane.
+
+
+
+
+
panes()
+Return a list of the names of the panes, in display order.
+
+
+
+
+
setnaturalsize()
+If oriented horizontally, set the width of the paned widget to the
+ sum of the requested widths of all panes and set the height to the
+ maximum requested height of all panes.
+
If oriented vertically, set the height of the paned widget to the
+ sum of the requested heights of all panes and set the width to the
+ maximum requested width of all panes.
+
+
+
+
+
+
updatelayout()
+Recalculate size and position of panes. This method must be
+ called after adding or deleting one or more panes. However it
+ does not need to be called when panes are first added to a newly
+ created paned widget, before it has been displayed.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ The value passed to this function is used to construct the text
+ displayed by Pmw.AboutDialog megawidgets created subsequently.
+
+
+
+
+
+
Pmw.aboutcopyright(value)
+
+ The value passed to this function is used to construct the text
+ displayed by Pmw.AboutDialog megawidgets created subsequently.
+
+
+
+
+
+
Pmw.aboutversion(value)
+
+ The value passed to this function is used to construct the text
+ displayed by Pmw.AboutDialog megawidgets created subsequently.
+
+
+
+
+
+
Pmw.aligngrouptags(groups)
+
+ This function takes a sequence of Pmw.Groups and adjusts the
+ vertical position of the tags in each group so that they all have
+ the height of the tallest tag. This can be used when groups are
+ positioned side-by-side but the natural height of the tags are
+ different because, for example, different fonts with different
+ sizes are used.
+
+
+
+
+
+
Pmw.alignlabels(widgets, sticky = None)
+
+ Adjust the size of the labels of all the widgets to be equal, so
+ that the body of each widget lines up vertically. This assumes
+ that each widget is a megawidget with a label component in
+ column 0 (ie, the labelpos option was set to 'w', 'wn' or
+ 'ws'). If sticky is set to a combination of 'n', 's',
+ 'e' and 'w', the label will be positioned within its cell
+ accordingly. For example to make labels right justified, set
+ sticky to 'e', 'ne' or 'se'.
+
+
+
+
+
+
Pmw.alphabeticvalidator(text)
+
+ Validator function for Pmw.EntryFieldalphabetic standard validator.
+
+
+
+
+
+
Pmw.alphanumericvalidator(text)
+
+ Validator function for Pmw.EntryFieldalphanumeric standard validator.
+
+
+
+
+
+
Pmw.busycallback(command, updateFunction = None)
+
+ Create a wrapper function which displays a busy cursor while
+ executing command and return the wrapper. When the wrapper
+ function is called, it first calls Pmw.showbusycursor(), then
+ the command (passing any arguments to it), then Pmw.hidebusycursor().
+ The return value of command is returned from the wrapper.
+
+
If updateFunction is specified, it is called just before the
+ call to Pmw.hidebusycursor(). This is intended to be the
+ Tkinter update() method, in which case it will clear any events
+ that may have occurred while command was executing. An example
+ of this usage is in the ShowBusy demonstration: run the
+ demonstration, click on the entry widget then click on the button
+ and type some characters while the busy cursor is displayed. No
+ characters should appear in the entry widget.
+
+
Note that the Tkinter update() method should only be called when
+ it is known that it can be safely called. One case where a
+ problem has been found is when a filehandler has been created (on
+ a non-blocking Oracle database connection), but the filehandler
+ does not read from the connection. The connection is read (by a
+ call to the Oracle fetch function ofen) in a loop which also
+ contains a call to _tkinter.dooneevent(). If update() is
+ called from dooneevent() and there is data to be read on the
+ connection, then the filehandler will be called continuously, thus
+ hanging the application.
+
+
+
+
+
+
Pmw.clearbusycursor()
+
+ Unconditionally remove the event block and busy cursor from all
+ windows. This undoes all outstanding calls to
+ Pmw.showbusycursor().
+
+
+
+
+
+
Pmw.datestringtojdn(text, format = 'ymd', separator = '/')
+
+ Return the Julian Day Number corresponding to the date in text.
+ A Julian Day Number is defined as the number of days since 1 Jan 4713
+ BC. The date must be specified as three integers separated by the
+ separator character. The integers must be in the order specified by
+ format, which must be a combination of 'd', 'm' and 'y' in
+ any order. These give the order of the day, month and year
+ fields. Examples of valid input are:
If the application's
+ pivot year (default 50) is not None and the year specified
+ in text has only one or two digits, then the year is
+ converted to a four digit year. If it is less than or equal to
+ the pivot year, then it is incremented by the application's
+ century value (default 2000). If it is more than the pivot year
+ then it is incremented by the century value less 100.
+
+
The function Pmw.setyearpivot() can be used to change the
+ default values for the application's
+ pivot and century.
+
+
+
+
+
+
Pmw.datevalidator(text, format = 'ymd', separator = '/')
+
+ Validator function for Pmw.EntryFielddate standard validator.
+
+
+
+
+
+
Pmw.displayerror(text)
+
+ This is a general purpose method for displaying background errors
+ to the user. The errors would normally be programming errors and
+ may be caused by errors in Tk callbacks or functions called by other
+ asynchronous events.
+
+
If the global error report file (set by calling
+ Pmw.reporterrorstofile()) is None, the error message `text` is
+ written to standard error and also shown in a text window. If
+ displayerror is called while previous error messages are being
+ displayed, the window is raised and the new error is queued. The
+ queued errors may be viewed by the user or ignored by dismissing
+ the window.
+
+
If the global error report file is not None, `text` is written
+ to the file. file may be any object with a write() method,
+ such as sys.stderr.
+ Draw a triangle in the Tkinter.Canvas canvas in the given
+ color. The value of direction may be 'up', 'down',
+ 'left' or 'right' and specifies which direction the arrow
+ should point. The values of baseOffset and edgeOffset specify
+ how far from the edges of the canvas the points of the triangles
+ are as a fraction of the size of the canvas.
This function adds methods to the class fromClass. The names of
+ the methods added are the names of the methods of the class
+ toClass (and its base classes) except those which are already
+ defined by fromClass or are found in the exclude list.
+ Special methods with one or more leading or trailing underscores
+ are also excluded.
+
+
When one of the added methods is called, the method of the same
+ name is called on an instance defined by toPart and the return
+ value passed back. If toPart is a string, then it specifies the
+ name of an attribute (not a component) of the fromClass
+ object. The class of this attribute should be toClass. If
+ toPart is not a string, it must be a function taking a
+ fromClass object and returning a toClass object.
+
+
This function must be called outside of and after the definition
+ of fromClass.
In both cases, all TargetClass methods will be forwarded from
+ MyClass except for dangerous1, dangerous2, special methods like
+ __str__, and pre-existing methods like foo.
+
+
+
+
+
+
Pmw.grabstacktopwindow()
+
+ Return the window at the top of the grab stack (the window
+ currently with the grab) or None if the grab stack is empty (no
+ window has the grab). See also pushgrab().
+
+
+
+
+
+
Pmw.hexadecimalvalidator(text)
+
+ Validator function for Pmw.EntryFieldhexadecimal standard validator.
+
+
+
+
+
+
Pmw.hidebusycursor(forceFocusRestore = 0)
+
+ Undo one call to Pmw.showbusycursor(). If there are no
+ outstanding calls to Pmw.showbusycursor(), remove the event
+ block and busy cursor.
+
+
If the focus window has not been changed since the corresponding
+ call to Pmw.showbusycursor(), or if forceFocusRestore is true,
+ then the focus is restored to that saved by Pmw.showbusycursor().
+ Initialise Pmw. This performs several functions:
+
Set up a trap in the Tkinter Toplevel constructor so that a
+ list of Toplevels can be maintained. A list of all Toplevel
+ windows needs to be kept so that Pmw.showbusycursor() can
+ create busy cursors for them.
+
+
+
Set up a trap in the Tkinter Toplevel and Frame destructors
+ so that Pmw is notified when these widgets are destroyed.
+ This allows Pmw to destroy megawidgets when their hull
+ widget is destroyed and to prune the list of Toplevels.
+
+
+
Modify Tkinter's CallWrapper class to improve the display of
+ errors which occur in callbacks. If an error occurs, the
+ new CallWrapper class calls Pmw.clearbusycursor() to
+ remove any outstanding busy cursors and calls
+ Pmw.displayerror() to display the error.
+
+
+
Using the window given by root, set the WM_DELETE_WINDOW
+ root window protocol to destroy the root window. This means
+ that the root window is destroyed if the window manager
+ deletes it. This is only done if the protocol has not been
+ set before the call to Pmw.initialise(). This protocol is
+ required if there is a modal dialog displayed and the window
+ manager deletes the root window. Otherwise the application
+ will not exit, even though there are no windows.
+
+
+
Set the base font size for the application to size. This
+ is used by Pmw.logicalfont() as the default point size for
+ fonts. If this is not given, the default is 14, except
+ under NT where it is 16. These are reasonable default
+ sizes for most screens, but for unusually high or low screen
+ resolutions, an appropriate size should be supplied. Note
+ that Tk's definition of point size, is somewhat
+ idiosyncratic.
+
+
+
Set the Tk option database for root according to
+ fontScheme. This changes the default fonts set by Tk.
+ fontScheme may be one of
+
None
Do not change the Tk defaults.
+
+
+
'pmw1'
If running under posix (Unix), set the default font to
+ be Helvetica with bold italic menus, italic scales and
+ a special balloon font 6 points smaller than the base
+ font size and with the 'pixel' field set to '12'.
+ For other operating systems (such as NT or Macintosh),
+ simply set the default font to be Helvetica. All
+ fonts are as returned by calls to Pmw.logicalfont().
+
+
+
'pmw2'
This is the same as 'pmw1' except that under posix
+ the balloon font is 2 points smaller than the base
+ font size and the 'pixel' field is not set.
+
+
+
'default'
This sets the default fonts using the Tk font naming
+ convention, rather than that returned by
+ Pmw.logicalfont(). The default font is bold
+ Helvetica. The font for entry widgets is Helvetica.
+ The font for text widgets is Courier The size of all
+ fonts is the application base font size as described
+ above.
+
+
+
+
+
If root is None, use the Tkinter default root window as the
+ root, if it has been created, or create a new Tk root window.
+ The initialise() method returns this root.
+
+
+
If useTkOptionDb is true, then, when a megawidget is
+ created, the Tk option database will be queried to get the
+ initial values of the options which have not been set in
+ the call to the constructor. The resource name used in the
+ query is the same as the option name and the resource class
+ is the option name with the first letter capitalised. If
+ useTkOptionDb is false, then options for newly created
+ megawidgets will be initialised to default values.
+
+
+
If noBltBusy is true, then Pmw.showbusycursor() will not
+ display a busy cursor, even if the BLT busy command is
+ present.
+
+
+
If disableKeyboardWhileBusy is false, then do not disable
+ keyboard input while displaying the busy cursor. Normally,
+ Pmw ignores keyboard input while displaying the busy cursor
+ by setting the focus for each toplevel window to the Blt
+ busy window. However, under NT, this may cause the toplevel
+ windows to be raised. If this is not acceptable, programs
+ running on NT can request show/hidebusycursor to not ignore
+ keyboard input by setting disableKeyboardWhileBusy to true
+ in Pmw.initialise().
+
+
+
+
It is not absolutely necessary to call this function to be able to use
+ Pmw. However, some functionality will be lost. Most importantly,
+ Pmw megawidgets will not be notified when their hull widget is
+ destroyed. This may prevent the megawidget from cleaning up
+ timers which will try to access the widget, hence causing a
+ background error to occur.
+
+
+
+
+
+
Pmw.installedversions(alpha = 0)
+
+ If alpha is false, return the list of base versions of Pmw
+ that are currently installed and available for use. If alpha is
+ true, return the list of alpha versions.
+
+
+
+
+
+
Pmw.integervalidator(text)
+
+ Validator function for Pmw.EntryFieldinteger standard validator.
+
+
+
+
+
+
Pmw.jdntoymd(jdn, julian = -1, papal = 1)
+
+ Return the year, month and day of the Julian Day Number jdn. If
+ julian is 1, then the date returned will be in the Julian
+ calendar. If julian is 0, then the date returned will be in
+ the modern calendar. If julian is -1, then which calendar to
+ use will be automatically determined by the value of jdn and
+ papal. If papal is true, then the date set by Pope Gregory
+ XIII's decree (4 October 1582) will be used as the last day to use
+ the Julian calendar. If papal is false, then the last day to
+ use the Julian calendar will be according to British-American
+ usage (2 September 1752).
+ Return the full name of a Tk font, being a hyphen-separated list
+ of font properties. The logical name of the font is given by
+ name and may be one of 'Helvetica', 'Times', 'Fixed',
+ 'Courier' or 'Typewriter'. Pmw uses this name to define the
+ default values of many of the font properties. The size of the
+ font is the base font size for the application specified in the
+ call to Pmw.initialise() increased or decreased by the value of
+ sizeIncr. The other properties of the font may be specified by
+ other named arguments. These may be 'registry', 'foundry',
+ 'family', 'weight', 'slant', 'width', 'style',
+ 'pixel', 'size', 'xres', 'yres', 'spacing',
+ 'avgwidth', 'charset' and 'encoding'.
+
+
+
+
+
+
Pmw.logicalfontnames()
+
+ Return the list of known logical font names that can be given
+ to Pmw.logicalfont().
+
+
+
+
+
+
Pmw.numericvalidator(text)
+
+ Validator function for Pmw.EntryFieldnumeric standard validator.
+
+
+
+
+
+
Pmw.popgrab(window)
+
+ Remove window from the grab stack. If there are not more
+ windows in the grab stack, release the grab. Otherwise set the
+ grab and the focus to the next window in the grab stack. See also
+ pushgrab().
+ The grab functions (pushgrab(), popgrab(), releasegrabs()
+ and grabstacktopwindow()) are an interface to the Tk grab
+ command which implements simple pointer and keyboard grabs. When
+ a grab is set for a particular window, Tk restricts all pointer
+ events to the grab window and its descendants in Tk's window
+ hierarchy. The functions are used by the activate() and
+ deactivate() methods to implement modal dialogs.
+
+
Pmw maintains a stack of grabbed windows, where the window on the
+ top of the stack is the window currently with the grab. The grab
+ stack allows nested modal dialogs, where one modal dialog can be
+ activated while another modal dialog is activated. When the
+ second dialog is deactivated, the first dialog becomes active
+ again.
+
+
Use pushgrab() to add grabWindow to the grab stack. This
+ releases the grab by the window currently on top of the stack (if
+ there is one) and gives the grab and focus to the grabWindow.
+ If globalMode is true, perform a global grab, otherwise perform
+ a local grab. The value of deactivateFunction specifies a
+ function to call (usually grabWindow.deactivate) if popgrab() is
+ called (usually from a deactivate() method) on a window which is
+ not at the top of the stack (that is, does not have the grab or
+ focus). For example, if a modal dialog is deleted by the window
+ manager or deactivated by a timer. In this case, all dialogs
+ above and including this one are deactivated, starting at the top
+ of the stack.
+
+
For more information, see the Tk grab manual page.
+
+
+
+
+
+
Pmw.realvalidator(text, separator = '.')
+
+ Validator function for Pmw.EntryFieldreal standard validator.
+
+
+
+
+
+
Pmw.releasegrabs()
+
+ Release grab and clear the grab stack. This should normally not
+ be used, use popgrab() instead. See also pushgrab().
+
+
+
+
+
+
Pmw.reporterrorstofile(file = None)
+
+ Sets the global error report file, which is initially None. See
+ Pmw.displayerror()
+
+
+
+
+
+
Pmw.setalphaversions(*alpha_versions)
+
+ Set the list of alpha versions of Pmw to use for this session to
+ the arguments. When searching for Pmw classes and functions,
+ these alpha versions will be searched, in the order given, before
+ the base version. This must be called before any other Pmw class
+ or function, except functions setting or querying versions.
+
+
+
+
+
+
Pmw.setbusycursorattributes(window, **kw)
+
+ Use the keyword arguments to set attributes controlling the effect
+ on window (which must be a Tkinter.Toplevel) of future calls
+ to Pmw.showbusycursor(). The attributes are:
+
+
exclude
a boolean value which specifies whether the window
+ will be affected by calls to Pmw.showbusycursor(). If a window
+ is excluded, then the cursor will not be changed to a busy cursor
+ and events will still be delivered to the window. By default,
+ windows are affected by calls to Pmw.showbusycursor().
+
+
+
cursorName
the name of the cursor to use when displaying the
+ busy cursor. If None, then the default cursor is used.
+
+
+
+
+
+
+
Pmw.setgeometryanddeiconify(window, geom)
+
+ Deiconify and raise the toplevel window and set its position and
+ size according to geom. This overcomes some problems with the
+ window flashing under X and correctly positions the window under
+ NT (caused by Tk bugs).
+
+
+
+
+
+
Pmw.setversion(version)
+
+ Set the version of Pmw to use for this session to version. If
+ Pmw.setversion() is not called, the latest installed version of
+ Pmw will be used. This must be called before any other Pmw class
+ or function, except functions setting or querying versions.
+
+
+
+
+
+
Pmw.setyearpivot(pivot, century = None)
+
+ Set the pivot year and century for the application's date
+ processing. These values are used in the datestringtojdn()
+ method, which is used by Pmw.Counter and Pmw.EntryField
+ and derived classes. The initial values of pivot and century
+ are 50 and 2000 repectively. Return a tuple containing the
+ old values of pivot and century.
+
+
+
+
+
+
Pmw.showbusycursor()
+
+ Block events to and display a busy cursor over all windows in this
+ application that are in the state 'normal' or 'iconic', except
+ those windows whose exclude busycursor attribute has been set to
+ true by a call to Pmw.setbusycursorattributes().
+
+
If a window and its contents have just been created,
+ update_idletasks() may have to be called before
+ Pmw.showbusycursor() so that the window is mapped to the screen.
+ Windows created or deiconified after calling
+ Pmw.showbusycursor() will not be blocked.
+
+
To unblock events and remove the busy cursor, use
+ Pmw.hidebusycursor(). Nested calls to Pmw.showbusycursor()
+ may be made. In this case, a matching number of calls to
+ Pmw.hidebusycursor() must be made before the event block and
+ busy cursor are removed.
+
+
If the BLT extension to Tk is not present, this function has no
+ effect other than to save the value of the current focus window,
+ to be later restored by Pmw.hidebusycursor().
+
+
+
+
+
+
Pmw.stringtoreal(text, separator = '.')
+
+ Return the real number represented by text. This is similar to
+ string.atof() except that the character representing the decimal
+ point in text is given by separator.
+
+
+
+
+
+
Pmw.timestringtoseconds(text, separator = ':')
+
+ Return the number of seconds corresponding to the time in text.
+ The time must be specified as three integers separated by the
+ separator character and must be in the order hours, minutes and
+ seconds. The first number may be negative, indicating a negative
+ time.
+
+
+
+
+
+
Pmw.timevalidator(text, separator = ':')
+
+ Validator function for Pmw.EntryFieldtime standard validator.
+ Print debugging trace of calls to, and callbacks from, the Tk
+ interpreter associated with the root window . If root is
+ None, use the Tkinter default root. If on is true, start
+ tracing, otherwise stop tracing. If withStackTrace is true,
+ print a python function call stacktrace after the trace for each
+ call to Tk. If file is None, print to standard error,
+ otherwise print to the file given by file.
+
+
For each call to Tk, the Tk command and its options are printed as
+ a python tuple, followed by the return value of the command (if
+ not the empty string). For example:
Some calls from python to Tk (such as update, tkwait,
+ invoke, etc) result in the execution of callbacks from Tk to
+ python. These python callbacks can then recursively call into Tk.
+ When displayed by tracetk(), these recursive calls are indented
+ proportionally to the depth of recursion. The depth is also
+ printed as a leading number. The return value of a call to Tk
+ which generated recursive calls is printed on a separate line at
+ the end of the recursion. For example:
Pmw.initialise() must be called before tracetk() so that hooks
+ are put into the Tkinter CallWrapper class to trace callbacks from
+ Tk to python and also to handle recursive calls correctly.
+
+
+
+
+
+
Pmw.version(alpha = 0)
+
+ If alpha is false, return the base version of Pmw being used
+ for this session. If Pmw.setversion() has not been called, this
+ will be the latest installed version of Pmw. If alpha is true,
+ return the list of alpha versions of Pmw being used for this
+ session, in search order. If Pmw.setalphaversions() has not
+ been called, this will be the empty list.
+ The prompt dialog is a dialog window which displays an entry field
+ which can be used to prompt the user for a value.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the entry field. The default is 20.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the entry field. The default is 20.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
entryfield
+
+The entry field for the user to enter a value. By default, this component is a Pmw.EntryField.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
entry
+
+Alias for entryfield_entry.
+
+
label
+
+Alias for entryfield_label.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+In addition, methods from the
+Pmw.EntryField class
+are forwarded by this megawidget to the
+entryfield component.
+
+
+
deleteentry(first, last = None)
+Delete text from the entry field's entry widget. An alias for
+ component('entry').delete().
+
+
+
+
+
indexentry(index)
+An alias for component('entry').index().
+
+
+
+
+
insertentry(index, text)
+Insert text into the entry field's entry widget. An alias for
+ component('entry').insert().
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the dialog to prompt for the password.
+ self.dialog = Pmw.PromptDialog(parent,
+ title = 'Password',
+ label_text = 'Password:',
+ entryfield_labelpos = 'n',
+ entry_show = '*',
+ defaultbutton = 0,
+ buttons = ('OK', 'Cancel'),
+ command = self.execute)
+ self.dialog.withdraw()
+
+ # Create the confirmation dialog.
+ self.confirm = Pmw.MessageDialog(
+ title = 'Are you sure?',
+ message_text = 'Are you really sure?',
+ defaultbutton = 0,
+ buttons = ('OK', 'Cancel'))
+ self.confirm.withdraw()
+
+ # Create button to launch the dialog.
+ w = Tkinter.Button(parent, text = 'Show prompt dialog',
+ command = self.dialog.activate)
+ w.pack(padx = 8, pady = 8)
+
+ def execute(self, result):
+ if result is None or result == 'Cancel':
+ print 'Password prompt cancelled'
+ self.dialog.deactivate(result)
+ else:
+ result = self.confirm.activate()
+ if result == 'OK':
+ print 'Password entered ' + self.dialog.get()
+ self.dialog.deactivate()
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ A radio select is a container megawidget which manages a number of
+ buttons. The buttons may be laid out either horizontally or
+ vertically. In single selection mode, only one button may be
+ selected at any one time. In multiple selection mode, several
+ buttons may be selected at the same time and clicking on a
+ selected button will deselect it.
+
+
The buttons displayed can be either standard buttons, radio
+ buttons or check buttons. When selected, standard buttons are
+ displayed sunken and radio and check buttons are displayed with
+ the appropriate indicator color and relief.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
buttontype
+
+Initialisation option. Specifies the default type of buttons created by the add()
+ method. If 'button', the default type is Tkinter.Button. If
+ 'radiobutton', the default type is Tkinter.Radiobutton. If
+ 'checkbutton', the default type is Tkinter.Checkbutton.
+
If 'radiobutton', single selection mode is automatically set.
+ If 'checkbutton', multiple selection mode is automatically set. The default is 'button'.
+
+
+
+
+
+
command
+
+Specifies a function to call when one of the buttons is clicked on
+ or when invoke() is called.
+
In single selection mode, the function is called with a single
+ argument, which is the name of the selected button.
+
+
In multiple selection mode, the function is called with the first
+ argument being the name of the button and the second argument
+ being true if the button is now selected or false if it is now
+ deselected. The default is None.
+
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
orient
+
+Initialisation option. Specifies the direction in which the buttons are laid out. This
+ may be 'horizontal' or 'vertical'. The default is 'horizontal'.
+
+
+
+
+
padx
+
+Initialisation option. Specifies a padding distance to leave between each button in the x
+ direction and also between the buttons and the outer edge of the
+ radio select. The default is 5.
+
+
+
+
+
pady
+
+Initialisation option. Specifies a padding distance to leave between each button in the y
+ direction and also between the buttons and the outer edge of the
+ radio select. The default is 5.
+
+
+
+
+
selectmode
+
+Initialisation option. Specifies the selection mode: whether a single button or multiple
+ buttons can be selected at one time. If 'single', clicking on
+ an unselected button selects it and deselects all other buttons.
+ If 'multiple', clicking on an unselected button selects it and
+ clicking on a selected button deselects it. This option is
+ ignored if buttontype is 'radiobutton' or 'checkbutton'. The default is 'single'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
frame
+
+If the label component has been created (that is, the labelpos
+ option is not None), the frame component is created to act as
+ the container of the buttons created by the add() method. If
+ there is no label component, then no frame component is
+ created and the hull component acts as the container. By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
Dynamic components
+
+ Button components are created dynamically by the add()
+ method. The default type of the buttons depends on the value
+ of the buttontype option.
+
+
Button components are created with a component group of Button.
+
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
add(componentName, **kw)
+Add a button to the end of the radio select as a component
+ named componentName. with a default type as specified by
+ buttontype. Any keyword arguments present (except command)
+ will be passed to the constructor when creating the button. If
+ the text keyword argument is not given, the text option of the
+ button defaults to componentName. The method returns the
+ component widget.
+
+
+
+
+
button(buttonIndex)
+Return the button specified by buttonIndex, which may have any
+ of the forms accepted by the index() method.
+
+
+
+
+
deleteall()
+Delete all buttons and clear the current selection.
+
+
+
+
+
getcurselection()
+Same as getvalue() method.
+
+
+
+
+
getvalue()
+In single selection mode, return the name of the currently
+ selected button, or None if no buttons have been selected yet.
+
In multiple selection mode, return a list of the names of the
+ currently selected buttons.
+
+
+
+
+
+
index(index)
+Return the numerical index of the button corresponding to index.
+ This may be specified in any of the following forms:
+
name
Specifies the button named name.
+
+
+
number
Specifies the button numerically, where 0 corresponds to
+ the left (or top) button.
+
+
+
Pmw.END
Specifies the right (or bottom) button.
+
+
+
+
+
+
+
invoke(index)
+Calling this method is the same as clicking on the button
+ specified by index: the buttons are displayed selected or
+ deselected according to the selection mode and command is
+ called. index may have any of the forms accepted by the
+ index() method. The value returned by command is returned.
+
+
+
+
+
numbuttons()
+Return the number of buttons in the radio select.
+
+
+
+
+
setvalue(textOrList)
+Set the current selection for the radio select to textOrList,
+ but do not invoke command.
+
In single selection mode, select only the button specified by the
+ string textOrList.
+
+
In multiple selection mode, select only the buttons specified by
+ the list textOrList.
+
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack a horizontal RadioSelect widget.
+ horiz = Pmw.RadioSelect(parent,
+ labelpos = 'w',
+ command = self.callback,
+ label_text = 'Horizontal',
+ frame_borderwidth = 2,
+ frame_relief = 'ridge'
+ )
+ horiz.pack(fill = 'x', padx = 10, pady = 10)
+
+ # Add some buttons to the horizontal RadioSelect.
+ for text in ('Fruit', 'Vegetables', 'Cereals', 'Legumes'):
+ horiz.add(text)
+ horiz.invoke('Cereals')
+
+ # Create and pack a multiple selection RadioSelect widget.
+ self.multiple = Pmw.RadioSelect(parent,
+ labelpos = 'w',
+ command = self.multcallback,
+ label_text = 'Multiple\nselection',
+ frame_borderwidth = 2,
+ frame_relief = 'ridge',
+ selectmode = 'multiple',
+ )
+ self.multiple.pack(fill = 'x', padx = 10)
+
+ # Add some buttons to the multiple selection RadioSelect.
+ for text in ('Apricots', 'Eggplant', 'Rice', 'Lentils'):
+ self.multiple.add(text)
+ self.multiple.invoke('Rice')
+
+ # Create and pack a vertical RadioSelect widget, with checkbuttons.
+ self.checkbuttons = Pmw.RadioSelect(parent,
+ buttontype = 'checkbutton',
+ orient = 'vertical',
+ labelpos = 'w',
+ command = self.checkbuttoncallback,
+ label_text = 'Vertical,\nusing\ncheckbuttons',
+ hull_borderwidth = 2,
+ hull_relief = 'ridge',
+ )
+ self.checkbuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10)
+
+ # Add some buttons to the checkbutton RadioSelect.
+ for text in ('Male', 'Female'):
+ self.checkbuttons.add(text)
+ self.checkbuttons.invoke('Male')
+ self.checkbuttons.invoke('Female')
+
+ # Create and pack a RadioSelect widget, with radiobuttons.
+ radiobuttons = Pmw.RadioSelect(parent,
+ buttontype = 'radiobutton',
+ orient = 'vertical',
+ labelpos = 'w',
+ command = self.callback,
+ label_text = 'Vertical,\nusing\nradiobuttons',
+ hull_borderwidth = 2,
+ hull_relief = 'ridge',
+ )
+ radiobuttons.pack(side = 'left', expand = 1, padx = 10, pady = 10)
+
+ # Add some buttons to the radiobutton RadioSelect.
+ for text in ('Male', 'Female', 'Both', 'Neither'):
+ radiobuttons.add(text)
+ radiobuttons.invoke('Both')
+
+ def callback(self, tag):
+ # This is called whenever the user clicks on a button
+ # in a single select RadioSelect widget.
+ print 'Button', tag, 'was pressed.'
+
+ def multcallback(self, tag, state):
+ # This is called whenever the user clicks on a button
+ # in the multiple select RadioSelect widget.
+ if state:
+ action = 'pressed.'
+ else:
+ action = 'released.'
+
+ print 'Button', tag, 'was', action, \
+ 'Selection:', self.multiple.getcurselection()
+
+ def checkbuttoncallback(self, tag, state):
+ # This is called whenever the user clicks on a button
+ # in the checkbutton RadioSelect widget.
+ if state:
+ action = 'pressed.'
+ else:
+ action = 'released.'
+
+ print 'Button', tag, 'was', action, \
+ 'Selection:', self.checkbuttons.getcurselection()
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 6 June 2002
+
+ A scrolled canvas consists of a standard canvas widget with optional
+ scrollbars which can be used to scroll the canvas. The scrollbars
+ can be dynamic, which means that a scrollbar will only be
+ displayed if it is necessary, that is, if the scrollregion of the
+ canvas is larger than the canvas.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
borderframe
+
+Initialisation option. If true, the borderframe component will be created. The default is 0.
+
+
+
+
+
canvasmargin
+
+Initialisation option. The margin around the items in the canvas. Used by the
+ resizescrollregion() method. The default is 0.
+
+
+
+
+
hscrollmode
+
+The horizontal scroll mode. If 'none', the horizontal scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
scrollmargin
+
+Initialisation option. The distance between the scrollbars and the enclosing canvas
+ widget. The default is 2.
+
+
+
+
+
usehullsize
+
+Initialisation option. If true, the size of the megawidget is determined solely by the
+ width and height options of the hull component.
+
Otherwise, the size of the megawidget is determined by the width
+ and height of the canvas component, along with the size and/or
+ existence of the other components, such as the label, the
+ scrollbars and the scrollmargin option. All these affect the
+ overall size of the megawidget. The default is 0.
+
+
+
+
+
+
vscrollmode
+
+The vertical scroll mode. If 'none', the vertical scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
borderframe
+
+A frame widget which snuggly fits around the canvas, to give the
+ appearance of a canvas border. It is created with a border so
+ that the canvas, which is created without a border, looks like it
+ has a border. By default, this component is a Tkinter.Frame.
+
+
+
+
+
canvas
+
+The canvas widget which is scrolled by the scrollbars. If the
+ borderframe option is true, this is created with a borderwidth
+ of 0 to overcome a known problem with canvas widgets: if a
+ widget inside a canvas extends across one of the edges of the
+ canvas, then the widget obscures the border of the canvas.
+ Therefore, if the canvas has no border, then this overlapping does
+ not occur. By default, this component is a Tkinter.Canvas.
+
+
+
+
+
horizscrollbar
+
+The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
vertscrollbar
+
+The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Canvas class
+are forwarded by this megawidget to the
+canvas component.
+
+
+
bbox(*args)
+This method is explicitly forwarded to the canvas component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
interior()
+Return the canvas widget within which the programmer should create
+ graphical items and child widgets. This is the same as
+ component('canvas').
+
+
+
+
+
resizescrollregion()
+Resize the scrollregion of the canvas component to be the
+ bounding box covering all the items in the canvas plus a margin on
+ all sides, as specified by the canvasmargin option.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the ScrolledCanvas.
+ self.sc = Pmw.ScrolledCanvas(parent,
+ borderframe = 1,
+ labelpos = 'n',
+ label_text = 'ScrolledCanvas',
+ usehullsize = 1,
+ hull_width = 400,
+ hull_height = 300,
+ )
+
+ # Create a group widget to contain the scrollmode options.
+ w = Pmw.Group(parent, tag_text='Scroll mode')
+ w.pack(side = 'bottom', padx = 5, pady = 5)
+
+ hmode = Pmw.OptionMenu(w.interior(),
+ labelpos = 'w',
+ label_text = 'Horizontal:',
+ items = ['none', 'static', 'dynamic'],
+ command = self.sethscrollmode,
+ menubutton_width = 8,
+ )
+ hmode.pack(side = 'left', padx = 5, pady = 5)
+ hmode.invoke('dynamic')
+
+ vmode = Pmw.OptionMenu(w.interior(),
+ labelpos = 'w',
+ label_text = 'Vertical:',
+ items = ['none', 'static', 'dynamic'],
+ command = self.setvscrollmode,
+ menubutton_width = 8,
+ )
+ vmode.pack(side = 'left', padx = 5, pady = 5)
+ vmode.invoke('dynamic')
+
+ buttonBox = Pmw.ButtonBox(parent)
+ buttonBox.pack(side = 'bottom')
+ buttonBox.add('yview', text = 'Show\nyview', command = self.showYView)
+ buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown)
+ buttonBox.add('center', text = 'Center', command = self.centerPage)
+
+ # Pack this last so that the buttons do not get shrunk when
+ # the window is resized.
+ self.sc.pack(padx = 5, pady = 5, fill = 'both', expand = 1)
+
+ self.sc.component('canvas').bind('<1>', self.addcircle)
+
+ testEntry = Tkinter.Entry(parent)
+ self.sc.create_line(20, 20, 100, 100)
+ self.sc.create_oval(100, 100, 200, 200, fill = 'green')
+ self.sc.create_text(100, 20, anchor = 'nw',
+ text = 'Click in the canvas\nto draw ovals',
+ font = testEntry.cget('font'))
+ button = Tkinter.Button(self.sc.interior(),
+ text = 'Hello,\nWorld!\nThis\nis\na\nbutton.')
+ self.sc.create_window(200, 200,
+ anchor='nw',
+ window = button)
+
+ # Set the scroll region of the canvas to include all the items
+ # just created.
+ self.sc.resizescrollregion()
+
+ self.colours = ('red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
+ 'black', 'white')
+ self.oval_count = 0
+ self.rand = 12345
+
+ def sethscrollmode(self, tag):
+ self.sc.configure(hscrollmode = tag)
+
+ def setvscrollmode(self, tag):
+ self.sc.configure(vscrollmode = tag)
+
+ def addcircle(self, event):
+ x = self.sc.canvasx(event.x)
+ y = self.sc.canvasy(event.y)
+ width = 10 + self.random() % 100
+ height = 10 + self.random() % 100
+ self.sc.create_oval(
+ x - width, y - height, x + width, y + height,
+ fill = self.colours[self.oval_count])
+ self.oval_count = (self.oval_count + 1) % len(self.colours)
+ self.sc.resizescrollregion()
+
+ # Simple random number generator.
+ def random(self):
+ self.rand = (self.rand * 125) % 2796203
+ return self.rand
+
+ def showYView(self):
+ print self.sc.yview()
+
+ def pageDown(self):
+ self.sc.yview('scroll', 1, 'page')
+
+ def centerPage(self):
+ top, bottom = self.sc.yview()
+ size = bottom - top
+ middle = 0.5 - size / 2
+ self.sc.yview('moveto', middle)
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 20 September 1998
+
+ A scrolled field displays a single line of text. If the text is
+ too wide to display in the megawidget it can be scrolled to the
+ left and right by the user by dragging with the middle mouse
+ button. The text is also selectable by clicking or dragging with
+ the left mouse button.
+
+
It can be used instead of a Tkinter.Label widget when displaying
+ text of unknown width such as application status messages.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
sticky
+
+Initialisation option. The default is 'ew'.
+
+
+
+
+
text
+
+Specifies the text to display in the scrolled field. The default is ''.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
entry
+
+This is used to display the text and allows the user to scroll and
+ select the text. The state of this component is set to
+ 'readonly' (or 'disabled' in earlier versions of Tcl/Tk which do
+ not support 'readonly'), so that the user is unable to modify the text. By default, this component is a Tkinter.Entry.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
+
Methods
+This megawidget has no methods of its own.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Entry class
+are forwarded by this megawidget to the
+entry component.
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create and pack the ScrolledField.
+ self._field = Pmw.ScrolledField(parent, entry_width = 30,
+ entry_relief='groove', labelpos = 'n',
+ label_text = 'Scroll the field using the\nmiddle mouse button')
+ self._field.pack(fill = 'x', expand = 1, padx = 10, pady = 10)
+
+ # Create and pack a button to change the ScrolledField.
+ self._button = Tkinter.Button(parent, text = 'Change field',
+ command = self.execute)
+ self._button.pack(padx = 10, pady = 10)
+
+ self._index = 0
+ self.execute()
+
+ def execute(self):
+ self._field.configure(text = lines[self._index % len(lines)])
+ self._index = self._index + 1
+
+lines = (
+ 'Alice was beginning to get very tired of sitting by her sister',
+ 'on the bank, and of having nothing to do: once or twice she had',
+ 'peeped into the book her sister was reading, but it had no',
+ 'pictures or conversations in it, "and what is the use of a book,"',
+ 'thought Alice "without pictures or conversation?"',
+ 'Alice\'s Adventures in Wonderland',
+ 'Lewis Carroll',
+)
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 23 August 1998
+
+ A scrolled frame consists of a scrollable interior frame within a
+ clipping frame. The programmer can create other widgets within
+ the interior frame. If the frame becomes larger than the
+ surrounding clipping frame, the user can position the frame using
+ the horizontal and vertical scrollbars.
+
+
The scrollbars can be dynamic, which means that a scrollbar will
+ only be displayed if it is necessary. That is, if the frame is
+ smaller than the surrounding clipping frame, the scrollbar will be
+ hidden.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
borderframe
+
+Initialisation option. If true, the borderframe component will be created. The default is 1.
+
+
+
+
+
horizflex
+
+Specifies how the width of the scrollable interior frame should be
+ resized relative to the clipping frame.
+
If 'fixed', the interior frame is set to the natural width, as
+ requested by the child widgets of the frame. If 'expand' and
+ the requested width of the interior frame is less than the width
+ of the clipping frame, the interior frame expands to fill the
+ clipping frame. If 'shrink' and the requested width of the
+ interior frame is more than the width of the clipping frame, the
+ interior frame shrinks to the width of the clipping frame. If
+ 'elastic', the width of the interior frame is always set to the
+ width of the clipping frame. The default is 'fixed'.
+
+
+
+
+
+
horizfraction
+
+Initialisation option. The fraction of the width of the clipper frame to scroll the
+ interior frame when the user clicks on the horizontal scrollbar
+ arrows. The default is 0.05.
+
+
+
+
+
hscrollmode
+
+The horizontal scroll mode. If 'none', the horizontal scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
scrollmargin
+
+Initialisation option. The distance between the scrollbars and the clipping frame. The default is 2.
+
+
+
+
+
usehullsize
+
+Initialisation option. If true, the size of the megawidget is determined solely by the
+ width and height options of the hull component.
+
Otherwise, the size of the megawidget is determined by the width
+ and height of the clipper component, along with the size and/or
+ existence of the other components, such as the label, the
+ scrollbars and the scrollmargin option. All these affect the
+ overall size of the megawidget. The default is 0.
+
+
+
+
+
+
vertflex
+
+Specifies how the height of the scrollable interior frame should
+ be resized relative to the clipping frame.
+
If 'fixed', the interior frame is set to the natural height,
+ as requested by the child widgets of the frame. If 'expand' and
+ the requested height of the interior frame is less than the height
+ of the clipping frame, the interior frame expands to fill the
+ clipping frame. If 'shrink' and the requested height of the
+ interior frame is more than the height of the clipping frame, the
+ interior frame shrinks to the height of the clipping frame. If
+ 'elastic', the height of the interior frame is always set to the
+ height of the clipping frame. The default is 'fixed'.
+
+
+
+
+
+
vertfraction
+
+Initialisation option. The fraction of the height of the clipper frame to scroll the
+ interior frame when the user clicks on the vertical scrollbar
+ arrows. The default is 0.05.
+
+
+
+
+
vscrollmode
+
+The vertical scroll mode. If 'none', the vertical scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
borderframe
+
+A frame widget which snuggly fits around the clipper, to give the
+ appearance of a border. It is created with a border so that the
+ clipper, which is created without a border, looks like it has a
+ border. By default, this component is a Tkinter.Frame.
+
+
+
+
+
clipper
+
+The frame which is used to provide a clipped view of the frame
+ component. If the borderframe option is true, this is created
+ with a borderwidth of 0 to overcome a known problem with using
+ place to position widgets: if a widget (in this case the
+ frame component) is placed inside a frame (in this case the
+ clipper component) and it extends across one of the edges of the
+ frame, then the widget obscures the border of the frame.
+ Therefore, if the clipper has no border, then this overlapping
+ does not occur. By default, this component is a Tkinter.Frame.
+
+
+
+
+
frame
+
+The frame within the clipper to contain the widgets to be scrolled. By default, this component is a Tkinter.Frame.
+
+
+
+
+
horizscrollbar
+
+The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
vertscrollbar
+
+The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
interior()
+Return the frame within which the programmer may create widgets to
+ be scrolled. This is the same as component('frame').
+
+
+
+
+
reposition()
+Update the position of the frame component in the clipper and
+ update the scrollbars.
+
Usually, this method does not need to be called explicitly, since
+ the position of the frame component and the scrollbars are
+ automatically updated whenever the size of the frame or
+ clipper components change or the user clicks in the scrollbars.
+ However, if horizflex or vertflex is 'expand', the
+ megawidget cannot detect when the requested size of the frame
+ increases to greater than the size of the clipper. Therefore,
+ this method should be called when a new widget is added to the
+ frame (or a widget is increased in size) after the initial
+ megawidget construction.
+
+
+
+
+
+
xview(mode = None, value = None, units = None)
+Query or change the horizontal position of the scrollable interior
+ frame. If mode is None, return a tuple of two numbers, each
+ between 0.0 and 1.0. The first is the position of the left edge
+ of the visible region of the contents of the scrolled frame,
+ expressed as a fraction of the total width of the contents. The
+ second is the position of the right edge of the visible region.
+
If mode == 'moveto', adjust the view of the interior so that
+ the fraction value of the total width of the contents is
+ off-screen to the left. The value must be between 0.0 and
+ 1.0.
+
+
If mode == 'scroll', adjust the view of the interior left or
+ right by a fixed amount. If what is 'units', move the view in
+ units of horizfraction. If what is pages, move the view in
+ units of the width of the scrolled frame. If value is positive,
+ move to the right, otherwise move to the left.
+
+
+
+
+
+
yview(mode = None, value = None, units = None)
+Query or change the vertical position of the scrollable interior
+ frame. If mode is None, return a tuple of two numbers, each
+ between 0.0 and 1.0. The first is the position of the top edge
+ of the visible region of the contents of the scrolled frame,
+ expressed as a fraction of the total height of the contents. The
+ second is the position of the bottom edge of the visible region.
+
If mode == 'moveto', adjust the view of the interior so that
+ the fraction value of the total height of the contents is
+ off-screen to the top. The value must be between 0.0 and
+ 1.0.
+
+
If mode == 'scroll', adjust the view of the interior up or
+ down by a fixed amount. If what is 'units', move the view in
+ units of vertfraction. If what is pages, move the view in
+ units of the height of the scrolled frame. If value is
+ positive, move to down, otherwise move up.
+
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A scrolled listbox consists of a standard listbox widget with optional
+ scrollbars which can be used to scroll the listbox. The
+ scrollbars can be dynamic, which means that a scrollbar will
+ only be displayed if it is necessary. That is, if the listbox
+ does not contain enough entries, the vertical scrollbar will be
+ automatically hidden and if the entries are not wide enough, the
+ horizontal scrollbar will be automatically hidden.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
dblclickcommand
+
+This specifies a function to call when mouse button 1 is double
+ clicked over an entry in the listbox component. The default is None.
+
+
+
+
+
hscrollmode
+
+The horizontal scroll mode. If 'none', the horizontal scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
items
+
+Initialisation option. A tuple containing the initial items to be displayed by the
+ listbox component. The default is ().
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
scrollmargin
+
+Initialisation option. The distance between the scrollbars and the listbox widget. The default is 2.
+
+
+
+
+
selectioncommand
+
+This specifies a function to call when mouse button 1 is single
+ clicked over an entry in the listbox component or if the <Space>
+ or <Return> key is hit while the listbox has focus. The default is None.
+
+
+
+
+
usehullsize
+
+Initialisation option. If true, the size of the megawidget is determined solely by the
+ width and height options of the hull component.
+
Otherwise, the size of the megawidget is determined by the width
+ and height of the listbox component, along with the size and/or
+ existence of the other components, such as the label, the
+ scrollbars and the scrollmargin option. All these affect the
+ overall size of the megawidget. The default is 0.
+
+
+
+
+
+
vscrollmode
+
+The vertical scroll mode. If 'none', the vertical scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
horizscrollbar
+
+The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
listbox
+
+The listbox widget which is scrolled by the scrollbars. By default, this component is a Tkinter.Listbox.
+
+
+
+
+
vertscrollbar
+
+The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Listbox class
+are forwarded by this megawidget to the
+listbox component.
+
+
+
bbox(index)
+This method is explicitly forwarded to the listbox component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
clear()
+Delete all items from the scrolled listbox. Equivalent to
+ setlist(()).
+
+
+
+
+
get(first = None, last = None)
+This is the same as the get() method of the listbox component,
+ except that if first is None all list
+ elements are returned.
+
+
+
+
+
getcurselection()
+Same as getvalue() method.
+
+
+
+
+
getvalue()
+Return a list of the currently selected items of the listbox.
+
+
+
+
+
setlist(items)
+Replace all the items of the listbox component with those
+ specified by the items sequence.
+
+
+
+
+
setvalue(textOrList)
+Set the current selection for the scrolled list to textOrList.
+
If textOrList is a string, select only the list item specified.
+
+
Otherwise, select only the list items specified by textOrList,
+ which must be a sequence of strings.
+
+
+
+
+
+
size()
+This method is explicitly forwarded to the listbox component's
+ size() method. Without this explicit forwarding, the size()
+ method (aliased to grid_size()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the ScrolledListBox.
+ self.box = Pmw.ScrolledListBox(parent,
+ items=('Sydney', 'Melbourne', 'Brisbane'),
+ labelpos='nw',
+ label_text='Cities',
+ listbox_height = 6,
+ selectioncommand=self.selectionCommand,
+ dblclickcommand=self.defCmd,
+ usehullsize = 1,
+ hull_width = 200,
+ hull_height = 200,
+ )
+
+ # Create a group widget to contain the scrollmode options.
+ w = Pmw.Group(parent, tag_text='Scroll mode')
+ w.pack(side = 'bottom', padx = 5, pady = 5)
+
+ hmode = Pmw.OptionMenu(w.interior(),
+ labelpos = 'w',
+ label_text = 'Horizontal:',
+ items = ['none', 'static', 'dynamic'],
+ command = self.sethscrollmode,
+ menubutton_width = 8,
+ )
+ hmode.pack(side = 'top', padx = 5, pady = 5)
+ hmode.invoke('dynamic')
+
+ vmode = Pmw.OptionMenu(w.interior(),
+ labelpos = 'w',
+ label_text = 'Vertical:',
+ items = ['none', 'static', 'dynamic'],
+ command = self.setvscrollmode,
+ menubutton_width = 8,
+ )
+ vmode.pack(side = 'top', padx = 5, pady = 5)
+ vmode.invoke('dynamic')
+
+ buttonBox = Pmw.ButtonBox(parent)
+ buttonBox.pack(side = 'bottom')
+ buttonBox.add('yview', text = 'Show\nyview', command = self.showYView)
+ buttonBox.add('scroll', text = 'Page\ndown', command = self.pageDown)
+ buttonBox.add('center', text = 'Center', command = self.centerPage)
+
+ # Pack this last so that the buttons do not get shrunk when
+ # the window is resized.
+ self.box.pack(fill = 'both', expand = 1, padx = 5, pady = 5)
+
+ # Do this after packing the scrolled list box, so that the
+ # window does not resize as soon as it appears (because
+ # alignlabels has to do an update_idletasks).
+ Pmw.alignlabels((hmode, vmode))
+
+ # Add some more entries to the listbox.
+ items = ('Andamooka', 'Coober Pedy', 'Innamincka', 'Oodnadatta')
+ self.box.setlist(items)
+ self.box.insert(2, 'Wagga Wagga', 'Perth', 'London')
+ self.box.insert('end', 'Darwin', 'Auckland', 'New York')
+ index = list(self.box.get(0, 'end')).index('London')
+ self.box.delete(index)
+ self.box.delete(7, 8)
+ self.box.insert('end', 'Bulli', 'Alice Springs', 'Woy Woy')
+ self.box.insert('end', 'Wallumburrawang', 'Willandra Billabong')
+
+ def sethscrollmode(self, tag):
+ self.box.configure(hscrollmode = tag)
+
+ def setvscrollmode(self, tag):
+ self.box.configure(vscrollmode = tag)
+
+ def selectionCommand(self):
+ sels = self.box.getcurselection()
+ if len(sels) == 0:
+ print 'No selection'
+ else:
+ print 'Selection:', sels[0]
+
+ def defCmd(self):
+ sels = self.box.getcurselection()
+ if len(sels) == 0:
+ print 'No selection for double click'
+ else:
+ print 'Double click:', sels[0]
+
+ def showYView(self):
+ print self.box.yview()
+
+ def pageDown(self):
+ self.box.yview('scroll', 1, 'page')
+
+ def centerPage(self):
+ top, bottom = self.box.yview()
+ size = bottom - top
+ middle = 0.5 - size / 2
+ self.box.yview('moveto', middle)
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 30 August 1998
+
+ A scrolled text consists of a standard text widget with optional
+ scrollbars which can be used to scroll the text. The
+ scrollbars can be dynamic, which means that a scrollbar will
+ only be displayed if it is necessary. That is, if the text widget
+ does not contain enough text (either horizontally or vertically),
+ the scrollbar will be automatically hidden. If it is displayed,
+ the horizontal scrollbar is under the text widget. Similarly, if
+ it is displayed, the vertical scrollbar is to the right of the
+ text widget.
+
+
Row and column headers may also be displayed, which scroll in sync
+ with the text widget and may be useful when displaying tabular
+ data. To assist in ensuring that columns line up when using a
+ column header, a fixed width font should be used.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
borderframe
+
+Initialisation option. If true, the borderframe component will be created. The default is 0.
+
+
+
+
+
columnheader
+
+Initialisation option. If true, the columnheader component will be created. The default is 0.
+
+
+
+
+
hscrollmode
+
+The horizontal scroll mode. If 'none', the horizontal scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
rowcolumnheader
+
+Initialisation option. If true, the rowcolumnheader component will be created. The default is 0.
+
+
+
+
+
rowheader
+
+Initialisation option. If true, the rowheader component will be created. The default is 0.
+
+
+
+
+
scrollmargin
+
+Initialisation option. The distance between the scrollbars and the text widget. The default is 2.
+
+
+
+
+
usehullsize
+
+Initialisation option. If true, the size of the megawidget is determined solely by the
+ width and height options of the hull component.
+
Otherwise, the size of the megawidget is determined by the width
+ and height of the text component, along with the size and/or
+ existence of the other components, such as the label, the
+ scrollbars and the scrollmargin option. All these affect the
+ overall size of the megawidget. The default is 0.
+
+
+
+
+
+
vscrollmode
+
+The vertical scroll mode. If 'none', the vertical scrollbar
+ will never be displayed. If 'static', the scrollbar will always
+ be displayed. If 'dynamic', the scrollbar will be displayed
+ only if necessary. The default is 'dynamic'.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
borderframe
+
+A frame widget which snuggly fits around the text widget, to give
+ the appearance of a text border. It is created with a border so
+ that the text widget, which is created without a border, looks
+ like it has a border. By default, this component is a Tkinter.Frame.
+
+
+
+
+
columnheader
+
+A text widget with a default height of 1 displayed above the main
+ text widget and which scrolls horizontally in sync with the
+ horizontal scrolling of the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
horizscrollbar
+
+The horizontal scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
rowcolumnheader
+
+A text widget displayed to the top left of the main text widget,
+ above the row header and to the left of the column header if they
+ exist. The widget is not scrolled automatically. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
rowheader
+
+A text widget displayed to the left of the main text widget and
+ which scrolls vertically in sync with the vertical scrolling of
+ the main text widget. By default, this component is a Tkinter.Text. Its component group is Header.
+
+
+
+
+
text
+
+The text widget which is scrolled by the scrollbars. If the
+ borderframe option is true, this is created with a borderwidth
+ of 0 to overcome a known problem with text widgets: if a widget
+ inside a text widget extends across one of the edges of the text
+ widget, then the widget obscures the border of the text widget.
+ Therefore, if the text widget has no border, then this overlapping
+ does not occur. By default, this component is a Tkinter.Text.
+
+
+
+
+
vertscrollbar
+
+The vertical scrollbar. By default, this component is a Tkinter.Scrollbar. Its component group is Scrollbar.
+
+
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+In addition, methods from the
+Tkinter.Text class
+are forwarded by this megawidget to the
+text component.
+
+
+
appendtext(text)
+Add text to the end of the text component. Scroll to the
+ bottom of the text, but only if it was already visible before the
+ new text was added.
+
+
+
+
+
bbox(index)
+This method is explicitly forwarded to the text component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
clear()
+Delete all text from the text component.
+
+
+
+
+
exportfile(fileName)
+Write the contents of the text component to the file fileName.
+
+
+
+
+
get(first = None, last = None)
+This is the same as the get() method of the text component,
+ except that if first is None the entire
+ contents of the text widget are returned.
+
+
+
+
+
getvalue()
+Return the entire contents of the text widget.
+
+
+
+
+
importfile(fileName, where = 'end')
+Read the contents of the file fileName and insert into the
+ text component at the position given by where.
+
+
+
+
+
settext(text)
+Same as setvalue() method.
+
+
+
+
+
setvalue(text)
+Replace the entire contents of the text component with text.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ The selection dialog is a dialog window which displays a scrolled
+ list which can be used to prompt the user for a value.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the scrolled list. The default is 10.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the scrolled list. The default is 10.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
scrolledlist
+
+The scrolled list for the user to enter a value. By default, this component is a Pmw.ScrolledListBox.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
label
+
+Alias for scrolledlist_label.
+
+
listbox
+
+Alias for scrolledlist_listbox.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+In addition, methods from the
+Pmw.ScrolledListBox class
+are forwarded by this megawidget to the
+scrolledlist component.
+
+
+
bbox(index)
+This method is explicitly forwarded to the listbox component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
size()
+This method is explicitly forwarded to the listbox component's
+ size() method. Without this explicit forwarding, the size()
+ method (aliased to grid_size()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ A text dialog is a dialog window which displays a text message to
+ the user along with one or more buttons to press.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
activatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ activated by a call to activate(). The default is None.
+
+
+
+
+
borderx
+
+Initialisation option. The padding to the left and right of the scrolled text. The default is 10.
+
+
+
+
+
bordery
+
+Initialisation option. The padding above and below the scrolled text. The default is 10.
+
+
+
+
+
buttonboxpos
+
+Initialisation option. Specifies on which side of the dialog window to place the button
+ box. Must be one of 'n', 's', 'e' or 'w'. The default is 's'.
+
+
+
+
+
buttons
+
+This must be a tuple or a list and specifies the names on the
+ buttons in the button box. The default is ('OK',).
+
+
+
+
+
command
+
+Specifies a function to call whenever a button in the button box
+ is invoked or the window is deleted by the window manager. The
+ function is called with a single argument, which is the name of
+ the button which was invoked, or None if the window was deleted
+ by the window manager.
+
If the value of command is not callable, the default behaviour
+ is to deactivate the window if it is active, or withdraw the
+ window if it is not active. If it is deactivated, deactivate()
+ is called with the button name or None as described above. The default is None.
+
+
+
+
+
+
deactivatecommand
+
+If this is callable, it will be called whenever the megawidget is
+ deactivated by a call to deactivate(). The default is None.
+
+
+
+
+
defaultbutton
+
+Specifies the default button in the button box. If the <Return>
+ key is hit when the dialog has focus, the default button will be
+ invoked. If defaultbutton is None, there will be no default
+ button and hitting the <Return> key will have no effect. The default is None.
+
+
+
+
+
master
+
+This is used by the activate() method to control whether the
+ window is made transient during modal dialogs. See the
+ activate() method. The default is 'parent'.
+
+
+
+
+
separatorwidth
+
+Initialisation option. If this is greater than 0, a separator line with the specified
+ width will be created between the button box and the child site,
+ as a component named separator. Since the default border of the
+ button box and child site is raised, this option does not
+ usually need to be set for there to be a visual separation between
+ the button box and child site. The default is 0.
+
+
+
+
+
title
+
+This is the title that the window manager displays in the title
+ bar of the window. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
buttonbox
+
+This is the button box containing the buttons for the dialog. By
+ default it is created with the options
+ (hull_borderwidth = 1, hull_relief = 'raised'). By default, this component is a Pmw.ButtonBox.
+
+
+
+
+
dialogchildsite
+
+This is the child site for the dialog, which may be used to
+ specialise the megawidget by creating other widgets within it. By
+ default it is created with the options
+ (borderwidth = 1, relief = 'raised'). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Toplevel.
+
+
+
+
+
scrolledtext
+
+The scrolled text to contain the text for the dialog. By default, this component is a Pmw.ScrolledText.
+
+
+
+
+
separator
+
+If the separatorwidth initialisation option is non-zero, the
+ separator component is the line dividing the area between the
+ button box and the child site. By default, this component is a Tkinter.Frame.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
label
+
+Alias for scrolledtext_label.
+
+
text
+
+Alias for scrolledtext_text.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.Dialog.
+In addition, methods from the
+Pmw.ScrolledText class
+are forwarded by this megawidget to the
+scrolledtext component.
+
+
+
bbox(index)
+This method is explicitly forwarded to the text component's
+ bbox() method. Without this explicit forwarding, the bbox()
+ method (aliased to grid_bbox()) of the hull would be invoked,
+ which is probably not what the programmer intended.
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+class Demo:
+ def __init__(self, parent):
+ # Create the dialog.
+ dialog = Pmw.TextDialog(parent, scrolledtext_labelpos = 'n',
+ title = 'My TextDialog',
+ defaultbutton = 0,
+ label_text = 'Lawyer jokes')
+ dialog.withdraw()
+ dialog.insert('end', jokes)
+ dialog.configure(text_state = 'disabled')
+
+ # Create button to launch the dialog.
+ w = Tkinter.Button(parent, text = 'Show text dialog',
+ command = dialog.activate)
+ w.pack(padx = 8, pady = 8)
+
+jokes = """
+Q: What do you call 5000 dead lawyers at the bottom of the ocean?
+A: A good start!
+
+Q: How can you tell when a lawyer is lying?
+A: His lips are moving.
+
+Q: Why won't sharks attack lawyers?
+A: Professional courtesy.
+
+Q: What do have when a lawyer is buried up to his neck in sand?
+A: Not enough sand.
+
+Q: How do you get a lawyer out of a tree?
+A: Cut the rope.
+
+Q: What is the definition of a shame (as in "that's a shame")?
+A: When a bus load of lawyers goes off a cliff.
+
+Q: What is the definition of a "crying shame"?
+A: There was an empty seat.
+
+Q: What do you get when you cross the Godfather with a lawyer?
+A: An offer you can't understand.
+
+Q. What do lawyers use as contraceptives?
+A. Their personalities.
+
+Q. What's brown and black and looks good on a lawyer?
+A. A doberman.
+
+Q. Why are lawyers buried 12 feet underground?
+A. Deep down their good.
+
+Q. What's the difference between a catfish and a lawyer?
+A. One's a slimy scum-sucking scavenger, the other is just a fish.
+
+"""
+
+
+
+
+
+
+
+
+
+
+
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 18 May 2002
+
+ A time counter is similar to a regular Pmw.Counter except that the
+ user may increment and decrement the hours, minutes and seconds
+ individually.
+
+
+
+
+
+
Options
+Options for this megawidget and its base
+classes are described below.
+
+
autorepeat
+
+If true, the counter will continue to count up or down while an
+ arrow button is held pressed down. The default is 1.
+
+
+
+
+
buttonaspect
+
+Initialisation option. Specifies the width of the arrow buttons as a proportion of their
+ height. Values less than 1.0 will produce thin arrow buttons.
+ Values greater than 1.0 will produce fat arrow buttons. The default is 1.0.
+
+
+
+
+
command
+
+This specifies a function to call whenever the <Return> key is
+ pressed in one of the entry fields or invoke() is called. The default is None.
+
+
+
+
+
initwait
+
+Specifies the initial delay (in milliseconds) before a depressed
+ arrow button automatically starts to repeat counting. The default is 300.
+
+
+
+
+
labelmargin
+
+Initialisation option. If the labelpos option is not None, this specifies the
+ distance between the label component and the rest of the
+ megawidget. The default is 0.
+
+
+
+
+
labelpos
+
+Initialisation option. Specifies where to place the label component. If not
+ None, it should be a concatenation of one or two of the
+ letters 'n', 's', 'e' and 'w'. The first letter
+ specifies on which side of the megawidget to place the label.
+ If a second letter is specified, it indicates where on that
+ side to place the label. For example, if labelpos is 'w',
+ the label is placed in the center of the left hand side; if
+ it is 'wn', the label is placed at the top of the left
+ hand side; if it is 'ws', the label is placed at the
+ bottom of the left hand side.
+
If None, a label component is not created. The default is None.
+
+
+
+
+
+
max
+
+Specifies the maximum acceptable time in the form "HH:MM:SS", or
+ None if no maximum checking should be performed. The default is None.
+
+
+
+
+
min
+
+Specifies the minimum acceptable time in the form "HH:MM:SS", or
+ None if no minimum checking should be performed. The default is None.
+
+
+
+
+
padx
+
+Initialisation option. Specifies how much wider to make each column than the default
+ width (where a column consists of two arrows and an entry field).
+ The entry fields expand to fill the extra space, but the arrow
+ buttons are centered in the available space. The default is 0.
+
+
+
+
+
pady
+
+Initialisation option. Specifies how much higher to make each row of arrow buttons than
+ the default hight. The arrow buttons are centered in the
+ available space. The default is 0.
+
+
+
+
+
repeatrate
+
+Specifies the delay (in milliseconds) between automatic counts
+ while an arrow button is held pressed down. The default is 50.
+
+
+
+
+
value
+
+Initialisation option. Specifies the initial contents of the time counter, in the form
+ "HH:MM:SS". If this is None, the current time is used as the
+ initial contents. The default is None.
+
+
+
+
+
Components
+Components created by this megawidget and its base
+classes are described below.
+
+
downhourarrow
+
+The arrow button used for decrementing the hour field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
downminutearrow
+
+The arrow button used for decrementing the minute field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
downsecondarrow
+
+The arrow button used for decrementing the second field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
frame
+
+If the label component has been created (that is, the labelpos
+ option is not None), the frame component is created to act as
+ the container of the entry fields and arrow buttons. If there is
+ no label component, then no frame component is created and the
+ hull component acts as the container. In either case the border
+ around the container of the entry fields and arrow buttons will be
+ raised (but not around the label). By default, this component is a Tkinter.Frame.
+
+
+
+
+
hourentryfield
+
+The entry field where the hours are entered and displayed. By default, this component is a Pmw.EntryField.
+
+
+
+
+
hull
+
+This acts as the body for the entire megawidget. Other components
+ are created as children of the hull to further specialise this
+ class. By default, this component is a Tkinter.Frame.
+
+
+
+
+
label
+
+If the labelpos option is not None, this component is
+ created as a text label for the megawidget. See the
+ labelpos option for details. Note that to set, for example,
+ the text option of the label, you need to use the label_text
+ component option. By default, this component is a Tkinter.Label.
+
+
+
+
+
minuteentryfield
+
+The entry field where the minutes are entered and displayed. By default, this component is a Pmw.EntryField.
+
+
+
+
+
secondentryfield
+
+The entry field where the seconds are entered and displayed. By default, this component is a Pmw.EntryField.
+
+
+
+
+
uphourarrow
+
+The arrow button used for incrementing the hour field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
upminutearrow
+
+The arrow button used for incrementing the minute field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
upsecondarrow
+
+The arrow button used for incrementing the second field. By default, this component is a Tkinter.Canvas. Its component group is Arrow.
+
+
+
+
+
Component aliases
+Sub-components of components of this megawidget
+may be accessed via the following aliases.
+
hourentry
+
+Alias for hourentryfield_entry.
+
+
minuteentry
+
+Alias for minuteentryfield_entry.
+
+
secondentry
+
+Alias for secondentryfield_entry.
+
+
+
+
Methods
+Only methods specific to this megawidget are described below.
+For a description of its inherited methods, see the
+manual for its base class
+Pmw.MegaWidget.
+
+
+
decrement(seconds = 1)
+Decrement the time by seconds seconds.
+
+
+
+
+
getint()
+Return the currently displayed time as a number of seconds.
+
+
+
+
+
getstring()
+Same as getvalue() method.
+
+
+
+
+
getvalue()
+Return the currently displayed time as a string in the form
+ "HH:MM:SS".
+
+
+
+
+
increment(seconds = 1)
+Increment the time by seconds seconds.
+
+
+
+
+
invoke()
+Invoke the command specified by the command option as if the
+ <Return> key had been pressed.
+
+
+
+
+
setvalue(text)
+Set the contents of the time counter, where text must be in the
+ form "HH:MM:SS".
+
+
+
+
+
Example
+The image at the top of this manual is a snapshot
+of the window (or part of the window) produced
+by the following code.
+
+ Pmw 1.2 -
+ 5 Aug 2003
+ - Home
+ Manual page last reviewed: 25 May 2002
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/blue_line.gif b/Pmw/Pmw_1_2/doc/blue_line.gif
new file mode 100644
index 00000000..2063df02
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/blue_line.gif differ
diff --git a/Pmw/Pmw_1_2/doc/blueball.gif b/Pmw/Pmw_1_2/doc/blueball.gif
new file mode 100644
index 00000000..013183af
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/blueball.gif differ
diff --git a/Pmw/Pmw_1_2/doc/bugs.html b/Pmw/Pmw_1_2/doc/bugs.html
new file mode 100644
index 00000000..f46e8e9e
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/bugs.html
@@ -0,0 +1,378 @@
+
+
+
+
+
+ List of known bugs
+
+
+
+
+
List of known bugs
+
+
+This is a list of some of the known bugs in Pmw. If you fix any of
+these, please let the maintainer (gregm@iname.com) know.
+
Under the Enlightenment window manager, if show() is called when
+ a window is already displayed (and is not obscured by other
+ windows), then the application will hang for two seconds. This
+ is either a bug in Tcl/Tk or in Enlightenment. See the comment
+ in the Tk function WaitForConfigureNotify() in the Tk source
+ file tk8.3.2/unix/tkUnixWm.c:
+
/*
+ * One more tricky detail about this procedure. In some cases the
+ * window manager will decide to ignore a configure request (e.g.
+ * because it thinks the window is already in the right place).
+ * To avoid hanging in this situation, only wait for a few seconds,
+ * then give up.
+ */
+
+
+
+
On NT, Pmw.MenuBar does not display message bar help for menu
+ items. It seems that Tk menu widgets do not support <Motion>
+ events on MS. This probably is an issue that should be taken up
+ with the Tcl/Tk people. (Reported by Stefan Schone. Pmw.0.7)
+
+
+
Run the CounterDialog.py demo, select the show dialog button and
+ press ok. Now exit the dialog (either with the exit button or
+ the close box). The following error appears:
+
Menu ID 256 is already in use!Fatal Python Error: Tcl/Tk panic
+
+
This may be a problem with Mac version of Tk. (Reported by
+ Anthony Wilson.)
+
+
+
+
Pmw.Balloons bind to widgets and canvas items. This means that
+ bindings made by other users are deleted when the balloon makes
+ its bindings. (For example, the "Delete" canvas item in the
+ Balloon demo overrides that <ButtonPress> binding and so that
+ balloon is not withdrawn when the mouse button is pressed over
+ the item.)
+
The obvious solution is for Pmw.Balloon to add its bindings with
+ a +. But this would make the unbind and tagunbind methods
+ inconsistent - they would remove all bindings, not just the ones
+ added by the balloon. A better way would be for the balloon to
+ add a bindtag to each widget`s bindtag list - then it would not
+ upset any other bindings and it could be deleted cleanly.
+ (Reported by Joe Saltiel)
+
+
+
+
+
import Tkinter
+ import Pmw
+
+ def foo(event):
+ print '<Enter> event on text'
+
+ root = Pmw.initialise()
+ balloon = Pmw.Balloon()
+
+ canvas = Tkinter.Canvas()
+ canvas.pack()
+
+ text1 = canvas.create_text(50, 50, text = 'hello
+there')
+
+ # As is, the balloon does not appear over the text, but foo
+ # is called. Swap the following two lines and the balloon
+ # appears but foo will not be called.
+ canvas.tag_bind(text1, "<Enter>", foo)
+ balloon.tagbind(canvas, text1, 'text 1 help')
+
+ root.mainloop()
+
In Pmw.Balloon, the balloon should not be withdrawn when the
+ pointer leaves a widget or item and it immediatly enters another
+ widget or item with balloon help. Instead, the balloon should
+ be moved and its contents changed immediately.
+
+
+
When a Pmw.Balloon is bound to a canvas item, moving the item
+ becomes very slow. (Reported by Joe Saltiel)
+
> Second, after I fixed my ordering problem I noticed, there
+ > is a pretty big delay in updating widgets that have balloon
+ > messages bound to them. (For example dragging a box across
+ > a screen, the box has a delayed reaction.) I believe this is
+ > due to some of the timing functions used in PmwBalloon, I am
+ > not sure if there is a way around it. I set all timers to
+ > zero, and still had the problem.
+
+
+
+
When running Pmw demos under ptui the busy cursor does not
+ appear.
+
+
+
If a combobox has a horizontal scrollbar and it displays its
+ listbox above the entry, then it is misplaced.
+
+
+
Bug in Pmw.PanedWidget: repeat by creating new panes in Demo -
+ existing panes jump to the right 1 or 2 pixels.
+
+
+
Bug in Pmw.PanedWidget: repeat by setting hull_borderwidth to
+ 20 in demo - initial drag jumps to right by about 20 pixels.
+ Also right hand side border is missing. (Fix may be similar to
+ method used in Pmw.ScrolledFrame to give canvas border.)
+
+
+
Fix ButtonRelease events so they do not trigger without a
+ corresponding ButtonPress event.
+
From Joe Saltiel: I was playing around with a scrolledlistbox
+ and tkFileDialog. When I have the dialog open above the list
+ box and I doubleclick on it, I invoke the selectioncmd of the
+ listbox as well as the tkFileDialog box, should this be
+ happening?
+
+
Attached is small sample program you can try. To get the bug to
+ show you must do two things. First, when you open the file
+ dialog box, make sure the item you are going to select if
+ over(above) the scrolledlistbox. Second, you have to double
+ click on that item. If you single click and hit "Open" you do
+ not get the bug. Nor do you get it unless the file you click on
+ is directly over the clickable region of the scrolledlist box.
Response: I have found where the problem is but I am not sure
+ how to fix it. It appears that the tkFileDialog box closes on a
+ ButtonPress event. The corresponding ButtonRelease event is
+ then sent to whichever widget is under the cursor at the time of
+ the Release. I have reproduced the problem with a Tcl-only
+ script:
If you do a quick Press-Release-Press over the file dialog, it
+ is withdrawn. If you then keep the mouse button down and move
+ the mouse around, you will see that the button and the listbox
+ still respond to it. If you do the final button Release over
+ the listbox, its <ButtonRelease-1> binding is invoked.
+
+
I think the correct solution is to modify Pmw to be very careful
+ when to accept ButtonRelease events. It will need to also bind
+ to ButtonPress events and make sure that it gets a Press before
+ it accepts the Release. I'll try to do the change as soon as
+ possible, but the code involved is fairly complex so I it may
+ take a little time.
+
+
+
+
Investigate bug in Tk8.0: When a dialog pops up over the
+ pointer then the keyboard focus is not set and so <Return> does
+ not invoke default button.
+
+
+
Under both X and NT, the arrows in the timecounter, counter and
+ combobox do not match the scrollbar arrows.
+
+
+
Pmw.Group does not work correctly when the tag is a compound
+ widget. The tag is placed such that the top of the tag is cut
+ off. (Reported by Peter Stoehr.)
Also, Pmw.Group does not resize correctly if the simple widget
+ changes size. For example:
+
grp3.configure(tag_font = ('Helveltica', '-160'))
+
+
+
+
+
Bug(s) in PmwScrolledCanvas. There is a bug in 0.8.1
+ PmwScrolledCanvas._setRegion. If there are no objects in the
+ canvas, then error occurs on len(region) because region is None.
+ Below is an attempt to fix it. Click on Show, then on Delete.
+ The window then continuously resizes. If the ScrolledCanvas is
+ created with canvasmargin = 0, the problem goes away. (Reported
+ by Anders Henja.)
Bug in Pmw.Dialog: if defaultbutton is configured before
+ buttons during self.initialiseoptions() (that is if
+ self._constructorKeywords.keys() returns a different order),
+ then setdefault() fails.
+
+
+
Bugs in Tk which affect Pmw.MainMenuBar:
+
Extra bindings assigned to a Tkinter.Menu widget using
+ bindtags have no effect. Hence the method used in
+ Pmw.MenuBar for status help (bind_class followed by
+ bindtags) does not work and therefore binding to the menu
+ widget is used instead.
+
+
+
The 'active' tag for the index() method of Tkinter.Menu
+ always returns None. Hence, in the menu widget motion
+ binding, event.y and the '@' format is used instead, for
+ all menus except the toplevel main menu.
+
+
+
For the toplevel main menu, event.x must be used for the
+ index() method, but it returns the wrong index. It
+ appears that the Tk widget is assuming vertical layout
+ to calculate distances, rather than horizontal.
+
+
+
For toplevel main menus, several Tk commands, such as
+ winfo_height(), do not work. This prevents the use of
+ balloon help for Pmw.MainMenuBar.
+
+
+
+
+
Bug in Pmw.ComboBox: Tab to combobox arrow, use up/down arrow
+ keys to change selection, hit return, nothing happens, <Shift
+ Tab> to entry window, hit return, combobox changes
+
actually, it would be better if you could not tab to
+ the arrow, only the entry field, like the Pmw.Counter.
+
+
+
the problem is if the entry field is not editable, what to
+ do then?
+
+
+
+
+
Bug in TimeCounter: Arrow keys don't work when focus is on entry.
+
+
+
Bug in Pmw.NoteBook: The size of the tab does not change when
+ the text value changes
+
+
+
Bug in Pmw.NoteBook: The name of the tab components has a "-" sign
+ in it, which means that component options can not be used in the
+ configure command. Eg:
+
n = Pmw.NoteBook()
+ p = n.add('page1')
+ n.configure(page1_background = 'red') # works
+ n.configure(page1-tab_background = 'red') # fail, must do this:
+ n.component('page1-tab').configure(background = 'red') # works
Fixed bug in Counter demo for the Macintosh - the maximum size of an
+ integer is smaller than the value returned by time.time().
+
+
+
Fixed bug in Grid demo for Tk 4.2 - grid_bbox returns garbage if it is
+ called without update_idletasks. Also, grid_bbox can only have two
+ arguments in Tk 4.1.
+
+
+
Modified ScrolledText demo so that the text widget contains enough text
+ to require a vertical scrollbar.
+
+
+
Changes to PmwBase:
+
Prefixed the name of several private variables with a double underscore.
+
+
+
Added symbolic constants for the indexes into an optionInfo list.
+
+
+
Changed names of several methods and variables to be more descriptive.
+
+
+
Removed options() method.
+
+
+
Simplified configuration option data structures. Modified option
+ handling code so that default options are set correctly. If an
+ option is created before initialise() is called then initialise()
+ checks if the option is set by the keyword arguments to
+ initialise(). If not, then it is given the value found in the
+ Tk option database, if a value exists, or the default value. If an
+ option is created after initialise() is called, then it is given the
+ value found in the Tk option database, if a value exists, or the
+ default value.
+
+
+
+
+
Replaced usage of self._hull in megawidgets by interior() method.
+
+
+
Added autoclear option to ComboBox.
+
+
+
Fixed bug in ComboBox - fast clicking on the arrow button could result
+ in an attempt to grab a window that was not yet visible.
+
+
+
Added "sys.exc_traceback = None" to the except clauses of all try
+ statements so that references to objects in the stack trace would not
+ be left.
+
+
+
Added takefocus option to PushButton.
+
+
+
Modified the getcurselection() method of ScrolledListBox so that it
+ returns a string if the selection mode is 'single' or 'browse', rather
+ than a tuple with one element. This also affects methods forwarded and
+ derived from ScrolledListBox.
+
+
+
Modified ScrolledListBox so that it avoids unnecessary updates by
+ using idle timer.
+
+
+
Modified ScrolledText to use grid instead of pack.
+
+
+
Added shutdown() function to Tk module to clean up all references to
+ the Tcl interpreter and then delete it.
+
+
+
Fixed bug in Tk module for the Macintosh - update() was being called in
+ initialise() before the Tcl interpreter was created.
+
+
+
14 February 1997
+
+
Version 0.1.1 completed and released internally.
+
+
+
6 March 1997
+
+
Pmw now uses the standard Tkinter module. The Tk module has been
+ dropped. This means that the Tk module functions such as after,
+ bell, bind, update, etc, are no longer available and the equivalent
+ Tkinter methods should be used.
+
+
+
To restore some of the features of the Tk module, Pmw.initialise()
+ now adds run-time hooks into Tkinter to get notification of when Tk
+ widgets are created and destroyed. It also modifies the CallWrapper
+ class so that errors during callbacks and bindings can be displayed
+ in a window. If Pmw.initialise() is not called, Tkinter is not
+ modified and these features are not available.
+
+
+
If a Tk widget which is acting as the hull of a megawidget is
+ destroyed, then the megawidget is destroyed as well. This can
+ only happen if Pmw.initialise() is called.
+
+
+
Pmw.initialise() now takes the Tkinter root as its argument.
+
+
+
The parent of megawidgets now defaults to the Tk root. Previously,
+ the parent of non-toplevel megawidgets had to be given.
+
+
+
Added PmwBase.tracetk() function to get trace of calls to the Tcl
+ interpreter for debugging.
+
+
+
Added functions to PmwBase to display a busy cursor over the
+ application such as when a modal dialog is displayed or it is
+ blocked doing a long calculation. Uses busy command of the blt
+ extension, if present.
+
+
+
Created a nifty new demo which demonstrates most of the megawidgets
+ in a convenient way.
+
+
+
Added a TextDialog.
+
+
+
Added functionality to handle the grabbing of nested modal dialogs
+ correctly.
+
+
+
Added an activatecommand option to Dialog which allows, for example,
+ the PromptDialog widget to set the keyboard focus when it is
+ activated.
+
+
+
Added tests for Counter and logicalfont.
+
+
+
The ScrolledListBox selectioncommand is no longer given the widget
+ as its first argument.
+
+
+
Several method, function and component names were changed, to be
+ consistent with the coding conventions.
+
+
+
Some of the effects of moving from the Tk module to Tkinter are:
+
The Tk module used to exit if there were no non-root toplevel
+ windows shown. This is no longer the case and so the application
+ must handle this explicitly, particularly if the root window is
+ withdrawn and the last non-root toplevel is deleted by the window
+ manager.
+
+
+
The Tk module bind functions and methods used to take a noEvent
+ argument to indicate that the Tk event should not be passed to the
+ callback. Tkinter does not support this.
+
+
+
The Tk module initialise() function should be replaced by
+ "root = Tkinter.Tk()" and root should be used instead of "Tk.Root()"
+
+
+
The Tk module quit() function should be replace by "root.destroy()".
+
+
+
Toplevels are not hidden when created. To be consistent,
+ MegaToplevels are not hidden either.
+
+
+
The hide and show methods are not available for Tkinter Toplevels,
+ only MegaToplevels
+
+
+
There is no grid_configure method.
+
+
+
Tkinter.Canvas.coords() returns a python list, not a tuple.
+
+
+
The Tkinter cget and configure widget methods always return
+ strings for the option values. The Tk module used to convert the
+ string to the appropriate python type (such as string, integer,
+ float, Variable, Image, callback function).
+
+
+
Tkinter Menu and Toplevel classes incorrectly have a pack method.
+
+
+
Menu class has no geometry method.
+
+
+
Canvas focus returns '' rather than None.
+
+
+
Text mark_gravity returns '' rather than None.
+
+
+
+
+
13 March 1997
+
+
Release of version 0.2
+
+
+
17 March 1997
+
+
Set default WM_DELETE_WINDOW protocol of Tkinter.Toplevel to
+ destroy() and removed duplicated protocol request from all demos.
+
+
+
Modified text of ShowBusy demo to indicate that busy cursor will
+ only be seen if the BLT extension is present.
+
+
+
Replaced call to update() in PmwLabeledWidget.py with update_idletasks().
+
+
+
Changed name of PromptDialog component from 'entry' to 'entryfield'.
+
+
+
28 April 1997
+
+
Version 0.3 released internally
+
+
+
19 August 1997
+
+
Many changes made (see the version 0.4 porting guide for
+ more details).
+
+
+
The option propagation mechanism that iwidgets uses is too
+ cumbersome, too hard to understand and, in python, too slow.
+ Developed a new mechanism which is more explicit in naming
+ options. This resulted in most options which were simply
+ propagated to components being removed. Removed keep(), rename()
+ and ignore() methods and "usual" options.
+
+
+
For speed, Pmw no longer queries the Tk option database for
+ default values for megawidget options. Hence, resource names and
+ classes do not need to be supplied when creating options and
+ None is returned for the resource name and class when using
+ configure() to query the options. Option "types" no longer
+ used.
+
+
+
Changed method and component names to be more consistent.
+
+
+
Replaced most uses of pack() with grid().
+
+
+
Megawidgets no longer inherit from LabeledWidget. Instead they
+ call createlabel() to optionally create the label component.
+
+
+
Removed child site from EntryField and rewrote ComboBox
+ accordingly.
+
+
+
Wrote lots more documentation, including automatically generated
+ reference manuals.
+
+
+
Removed PushButton and rewrote ButtonBox to directly create
+ Tkinter.Buttons rather than PushButtons.
+
+
+
Added initialisation options - options which can be set at
+ creation time but not later using configure().
+
+
+
Added aliases for components.
+
+
+
Modified the base classes so that during option configuration,
+ components are configured before configuration called functions
+ are called.
+
+
+
Added several more megawidgets.
+
+
+
Added interface to BLT graph and vector commands.
+
+
+
Created PmwLazy module for lazy importing of Pmw - avoids loading
+ megawidgets which are not used.
+
+
+
Added several more functions for handling color and fonts.
+
+
+
Replaced Counter and EntryField time with timeN and time24
+
+
+
Pmw.initialise() will now create Tkinter.Tk if not given root.
+
+
+
1 September 1997
+
+
Release of version 0.4
+
+
+
5 September 1997
+
+
Modified the base classes so that the Tk option database resource
+ class of megawidgets can be overridden in the call to the
+ constructor using the hull_class option.
+
+
+
The separators in Pmw.PanedWidget are now active - they can be
+ grabbed, like the handles, and moved around. The cursor now
+ changes to the correct left/right or up/down cursor when over a
+ separator or handle. (Clemens Hintze)
+
+
+
Fixed bug in MessageInfo demo Dismiss button. If it is invoked,
+ an error occurs saying "not enough arguments". (Mark Colclough)
+
+
+
9 September 1997
+
+
Added the useTkOptionDb argument to Pmw.initialise which
+ specifies that the initial values of megawidget options are to be
+ set by querying the Tk option database.
+
+
+
When used to query options, the configure() method now returns the
+ resource class and name of the options.
+
+
+
19 September 1997
+
+
Changed functions datestringtoint() and timestringtoint() to
+ datestringtojdn() and timestringtoseconds(). Changed return value
+ of datestringtojdn() to be Julian Day Numbers rather than seconds
+ since the epoch.
+
+
+
Fixed a bug in the date Counter due to use of time.timezone, by
+ replacing, when calculating date increments, calls to the time
+ module with calls to datestringtojdn().
+
+
+
Added century pivot year (setyearpivot function) to Counter date
+ datatypes to handle two-digit years.
+
+
+
Added date_dmy4, date_mdy4 and date_y4md datatypes to Counter.
+
+
+
Modified demos All.py and ScrolledText.py so that demos can be called
+ from directories other than the demos directory. (Case Roole and
+ Guido van Rossum)
+
+
+
Changed the default for the Pmw.Balloon label_justify option to
+ left to improve appearance of multi-line balloons. Pmw.Balloon
+ now replaces newlines with spaces in the statusHelp string so that
+ the strings look better when displayed in a Pmw.MessageBar.
+ (Andreas Kostyrka)
+
+
+
Pmw.Blt now calls package require BLT when checking for the
+ existence of Blt, so that it can be loaded if it is not statically
+ linked. (Clemens Hintze, Matthias Klose)
+
+
+
Copied earthris.gif and flagup.bmp files from Tcl distribution to
+ test directory, just in case they have not been installed.
+ (Jonathan Kelly)
+
+
+
Lots of improvements to the documentation and documenting recent
+ changes.
+
+
+
16 October 1997
+
+
Modified Pmw.Balloon and Pmw.ComboBox to work around a bug in the
+ Windows95 version of Tk which caused the popup windows to appear
+ in the wrong place. (Fredrik Lundh and Jerome Gay)
+
+
+
Added Pmw.maxfontwidth() function. (Rob Pearson)
+
+
+
24 October 1997
+
+
Changed PmwBase._reporterror to handle the class exceptions of
+ python 1.5. (Case Roole)
+
+
+
29 October 1997
+
+
Fixed a bug in forwardmethods() function which occurred if the
+ toClass class had a method called type.
+
+
+
7 November 1997
+
+
Changed tests/Test._getErrorValue to handle the class exceptions of
+ python 1.5. (Michael McLay)
+
+
+
Changed bug fix in forwardmethods() function to use the
+ exec execString in d construct. (Guido van Rossum)
+
+
+
Can now use Pmw.MegaArchetype as a base class just to get option
+ handling; it will not create the hull component unless requested.
+ Moved __str__() and interior() methods from Pmw.MegaToplevel and
+ Pmw.MegaWidget to Pmw.MegaArchetype class.
+
+
+
10 November 1997
+
+
Added textclass option to Pmw.ScrolledText and listboxclass
+ option for Pmw.ScrolledListBox to allow embedding of custom
+ widgets.
+
+
+
Added Mitch Chapman's FontText module to the demos directory
+ and used it to display the demo source code in color.
+
+
+
Added two notebook megawwidgets, Pmw.NoteBookR and Pmw.NoteBookS.
+ (Case Roole and Joe Saltiel)
Added Pmw.Group megawidget and modified to use grid() instead
+ of pack(). (Case Roole)
+
+
+
Release of version 0.5
+
+
+
12 November 1997
+
+
Added pyclass option to components and removed textclass
+ option from Pmw.ScrolledText and listboxclass option from
+ Pmw.ScrolledListBox. (Suggested by Shen Wang)
+
+
+
Added label component to Pmw.ButtonBox megawidget.
+
+
+
Fixed mis-spelling of PmwTreeBrowse in Pmw.py.
+
+
+
Release of version 0.5.1
+
+
+
5 December 1997
+
+
The pyclass option can now be None. If so, createcomponent
+ returns None.
+
+
+
Removed tagtype option from Pmw.Group. Can now use the more
+ general tag_pyclass instead.
+
+
+
Added tcl call to load {} Blt when testing for presence of Blt.
+
+
+
Added julian and papal options to Pmw.ymdtojulian and
+ Pmw.juliantoymd functions and made sure divisions give the same
+ result as C even when operands are negative.
+
+
+
Exported ymdtojulian and juliantoymd functions.
+
+
+
Fixed bug in activate method. Did not prepend TclError with Tkinter.
+
+
+
When the Blt busy hold command is called from showbusycursor, the
+ bindtags on the busy window are set so that no events cause
+ callbacks to occur for the toplevel or all bindings. Also, while
+ a busy window is up, the focus is changed to the busy window so
+ that no keyboard events are accepted. This fixes a bug where the
+ Tkinter._nametowidget function could crash with a KeyError: _Busy
+ if there was a binding on a toplevel window and the mouse
+ was pressed while the busy cursor was up.
+
+
+
9 December 1997
+
+
Fixed bug in Pmw.datestringtojdn() when dealing with century year,
+ such as 2000.
+
+
+
10 December 1997
+
+
Added where option to Pmw.ScrolledText.importfile(). (Graham
+ Matthews)
+
+
+
16 December 1997
+
+
Modified Pmw.RadioSelect and Pmw.ButtonBox so that you can no
+ longer index their buttons using regular expressions. This
+ feature seemed to have little use and caused problems with buttons
+ labeled for example a* and b*. (Problem reported by Rob
+ Hooft)
+
+
+
Added updateFunction option to Pmw.busycallback(). If set, the
+ function will be called just after the command given to
+ Pmw.busycallback(). If the function is set the Tkinter update()
+ method, then this will clear any events that may have occurred
+ while the command was executing.
+
+
+
30 December 1997
+
+
Changed ymdtojulian and juliantoymd functions to jdntoymd and
+ ymdtojdn, because the meaning of "julian" is ambiguous, whereas
+ the meaning of "Julian Day Number" is not (maybe).
+
+
+
Converted Pmw to use python 1.5 package mechanism. (Michael McLay
+ and Case Roole)
+
+
+
Removed Pmw.py and PmwLazy files. Added __init__.py, PmwLoader.py
+ and Pmw.def files. (Case Roole)
+
+
+
Applications can now specify at runtime which version of Pmw to
+ use and also which alpha versions, if any. (Case Roole)
+
+
+
Modified Pmw code for the version of Tkinter released with python
+ 1.5.
+
+
+
Release of version 0.6
+
+
+
5 January 1998
+
+
Fixed alpha version handling so that alpha versions do not have to
+ supply PmwBase.py and PmwUtils.py. (Case Roole)
+
+
+
Added example alpha directory and documentation. (Case Roole)
+
+
+
7 January 1998
+
+
Added selectmode option to Pmw.RadioSelect megawidget. (Roman
+ Sulzhyk)
+
+
+
Added some changes to Pmw.ScrolledCanvas to get around some bugs.
+ (Joe Saltiel)
+
+
+
Release of version 0.6.1
+
+
+
8 January 1998
+
+
Added some more changes to Pmw.ScrolledCanvas. (from Joe Saltiel)
+
+
+
12 January 1998
+
+
Added Pmw.OptionMenu megawidget. (Roman Sulzhyk)
+
+
+
20 February 1998
+
+
Added new Pmw.MenuBar features to delete menus and menuitems,
+ enable and disable menu bar and to add cascade menus. (Rob Pearson)
+
+
+
Added extra arguments to Pmw.Color.spectrum for more control over
+ color choice.
+
+
+
23 February 1998
+
+
Added canvasbind() method to Pmw.Balloon.
+
+
+
Fixed demos/All.py so that it will correctly determine which Pmw
+ version to use even if it is in a directory symlinked to the demos
+ directory.
+
+
+
Removed "import DemoVersion" from all demos, except All.py, so
+ that they will work unchanged when copied outside of the Pmw
+ distribution.
+
+
+
Release of version 0.6.2
+
+
+
26 February 1998
+
+
Fixed PmwLoader so that it works on Macintoshes. (Jack Jansen)
+
+
+
2 March 1998
+
+
Fixed PmwBase and PmwBlt so that an attempt is made to dynamically
+ load Blt before it is used. Previously only attempted to load Blt
+ when calling showbusycursor.
+
+
+
16 March 1998
+
+
Added hulldestroyed() method.
+
+
+
Modified displayerror() function to use value given to
+ reporterrorstofile() if it is set.
+
+
+
Fixed bug in Pmw.EntryField which occurred when the command
+ option destroyed the megawidget.
+
+
+
Pmw.EntryField invoke method now passes on the value returned by
+ the command function.
+
+
+
3 April 1998
+
+
Added Pmw.ScrolledFrame megawidget. (Joe Saltiel)
+
+
+
Color.rgb2hsi() now uses the built-in min() and max() functions.
+
+
+
20 April 1998
+
+
Moved time and date functions from PmwCounter.py to new file,
+ PmwTimeFuncs.py.
+
+
+
Added optional separator argument to timestringtoseconds and
+ datestringtojdn functions. These functions are now stricter
+ when checking if a string is a valid date or time. For example,
+ it now checks for correct day in month, month in year, etc. These
+ changes also affect the Pmw.Counter date and time validators.
+
+
+
The datestringtojdn function now accepts all combinations of
+ 'd', 'm', 'y' as format string.
+
+
+
Moved functions to bottom of file and class to top of file in
+ PmwEntryField.py and PmwCounter.py.
+
+
+
The validation for Pmw.EntryField integer, hexadecimal and
+ real types now use string.atol or string.atof rather than
+ regular expressions.
+
+
+
The validation for the Pmw.EntryField real type accepts a
+ separator argument, for those who prefer a comma instead of a
+ full stop/period/point as the decimal dividing symbol.
+
+
+
The Pmw.EntryField time* and date_* validators have been
+ removed. The functionality can be replaced by using the new
+ time and date validators with min and max fields.
+
+
+
The Pmw.EntryField maxwidth option has been removed. The
+ functionality can be replaced by using the max field of the
+ validator.
+
+
+
Added an extravalidators option to Pmw.EntryField. This allows
+ new types of validation to be added, particularly in classes
+ derived from Pmw.EntryField. It also allows the use of different
+ names for the same validation, by using aliases. Added
+ SpecialEntry demo to show extravalidators option, based on work
+ by Joachim Schmitz.
+
+
+
Fixed a bug in Pmw.EntryField when combining use of value and
+ entry_textvariable options.
+
+
+
The Pmw.EntryField validate option now also accepts a dictionary
+ to handle minimum and maximum validation and to allow the passing
+ of other arguments to the validating functions, such as date, time
+ and number formats and separators.
+
+
+
Fixed bug in Pmw.EntryField where the entry would scroll to the
+ start of the text if an invalid character was typed.
+
+
+
Added checkentry() method to Pmw.EntryField, so that it can be
+ updated if the entry widget is tied to a textvariable.
+
+
+
10 May 1998
+
+
The activate() method now takes a geometry option to allow more
+ flexible positioning of the modal dialog.
+
+
+
Fixed rarely occurring bug in deactivate() method if it is called
+ (perhaps from a timer) during the call to wait_visibility() in the
+ activate() method. This bug used to generate an error and the
+ application would not exit properly.
+
+
+
Fixed another rarely occurring bug in deactivate() method if it is
+ called while another application has the grab.
+
+
+
Removed "sys.exc_traceback = None" for except clauses which used
+ to be required by python 1.4 so that references to objects in the
+ stack trace would not be left.
+
+
+
Now uses sys.exc_info() function when displaying exception
+ traceback.
+
+
+
The state option of Pmw.Balloon and the orient option of
+ several others now generate an exception if they have a bad value.
+
+
+
Added a deactivatecommand option to Pmw.MegaToplevel which can be
+ used, for example, to cancel timers.
+
+
+
Made changes to Pmw.Counter so that the entry display continuously
+ changes when arrow key presses are repeated quickly.
+
+
+
Made changes to Pmw.Counter so that the insertion cursor is maintained
+ while counting and the entry scrolls to the end if the value is long.
+
+
+
Pmw.Counter now behaves correctly when counting past the maximum
+ and minimum values of the EntryField.
+
+
+
28 May 1998
+
+
Made all Pmw.EntryField standard validators publicly available
+ as Pmw.numericvalidator, etc.
+
+
+
Now uses faster string.replace() instead of regsub.gsub() when
+ applicable.
+
+
+
If the balloonHelp argument of the Pmw.Balloon bind methods is
+ None, no balloon is displayed.
+
+
+
Merged the code from the PmwUtils module (forwardmethods()) into
+ PmwBase, since it was always used, was used nowhere else, and made
+ freezing a little more complicated.
+
+
+
Added a short delay between calling Tkinter bell() method (sounds nicer).
+
+
+
The functions datestringtojdn() and timestringtoseconds() now
+ return ValueError on invalid input.
+
+
+
Created bundlepmw.py, to help when freezing in Pmw. Placed in bin
+ directory.
+
+
+
29 May 1998
+
+
Fixed rare bug in Pmw.Counter which occured if the counter was
+ unmapped while the mouse button was held down over an arrow button.
+
+
+
Created contrib directory and placed PmwVerticalGuage.py in it.
+ (Chris Wright)
+
+
+
Patched PmwNoteBookR.py. (Siggy Brentrup)
+
+
+
Added addoptions() method to Pmw.MegaArchetype class. (Dieter Maurer)
+
+
+
By default, MenuBar creates hotkeys for menus and menu items for
+ keyboard traversal. Added traversSpec argument to MenuBar add
+ methods. (Michael McLay)
+
+
+
31 May 1998
+
+
Cleaned up bbox() methods in Pmw.ScrolledCanvas and
+ Pmw.ScrolledListBox.
+
+
+
The createcomponent() method now disallows the creation of
+ component names containing an underscore, since the query
+ functions would not be able to find them.
+
+
+
2 June 1998
+
+
Release of version 0.7
+
+
+
3 June 1998
+
+
Moved Pmw.TreeBrowse megawidget to contrib directory.
+
+
+
17 June 1998
+
+
Added PmwFullTimeCounter.py to contrib directory (Daniel Michelson)
+
+
+
1 July 1998
+
+
Changed mispelt file PmwVerticalGuage.py to PmwVerticalGauge.py
+ in contrib directory.
+
+
+
7 July 1998
+
+
Fixed bug in Pmw.Counter real datatype. Sometimes incorrectly
+ counted negative decimal fractions. (Reported by David Ascher)
+
+
+
12 July 1998
+
+
The format argument of Pmw.datestringtojdn() now defaults to
+ 'ymd'.
+
+
+
Removed Tkinter_test.py from tests since it does not test any Pmw
+ functionality (only Tkinter) and it fails under MS-Windows 95.
+
+
+
23 August 1998
+
+
Changed several exception types to be more consistent.
+
+
+
Made the interface to Pmw.Blt.Vector more like the builtin python
+ list type.
+
+
+
It is no longer an error to call Pmw.setversion() or
+ Pmw.setalphaversions() after initialisation, as long as the
+ requested version matches the actual version.
+
+
+
Fixed Pmw.NoteBookR so that it behaves better when the
+ highlightthickness is changed.
+
+
+
The setyearpivot() function now returns a tuple containing the old
+ values of pivot and century.
+
+
+
Added PmwFileDialog.py to contrib directory (Rob Hooft)
+
+
+
Modified demos so that full tracebacks are displayed if an error
+ occurs when importing a module.
+
+
+
Removed justify() method from Pmw.ScrolledListBox, since it is
+ just a wrapper around the xview and yview methods of the listbox.
+ Also, it was not a permanent justification, as the name implied.
+
+
+
20 September 1998
+
+
Changed implementation of Pmw.ScrolledCanvas.
+
+
+
Added borderframe option to Pmw.ScrolledText and Pmw.ScrolledCanvas.
+
+
+
18 October 1998
+
+
Major overhaul of all scrolled widgets. Modified all to use
+ similar structure, given the peculiarities of each. Fixed several
+ subtle bugs.
+
+
+
Pmw.ScrolledFrame: now uses a frame positioned within a clipping
+ frame using the place geometry manager. Added borderframe,
+ horizflex, horizfraction, usehullsize, vertflex, vertfraction
+ options. Added reposition() method. Removed getFrame() method;
+ use interior() method instead.
+
+
+
Pmw.ScrolledListBox: added usehullsize option.
+
+
+
Pmw.ScrolledText: added borderframe and usehullsize options.
Modified Pmw.OptionMenu to use standard widgets rather than call
+ tcl procedure. Added initialitem option. Now handles
+ menubutton_textvariable component option correctly.
+
+
+
1 November 1998
+
+
Documented more Pmw functions and Pmw.ComboBox.
+
+
+
15 November 1998
+
+
Fixed some bugs, cleaned up code and wrote documentation for
+ Pmw.Group. Removed ringpadx and ringpady options, since this
+ functionality is more generally available by padding the
+ megawidget itself and by padding the children of the megawidget.
+ Modified Pmw.aligngrouptags so that it takes into account the
+ borderwidth and highlightthickness of the ring and so that it
+ works when there is no tag widget. Added tagindent option.
+
+
+
18 November 1998
+
+
Renamed canvasbind() and canvasunbind() methods of Pmw.Balloon to
+ tagbind() and tagunbind() and modified so that they work with both
+ Tkinter.Canvas items and Tkinter.Text tagged items.
+
+
+
19 November 1998
+
+
Added havebltbusy() method to Pmw.Blt. (Robin Becker)
+
+
+
21 November 1998
+
+
Modified contrib/PmwFileDialog.py so that when a file is selected
+ with the mouse, the highlight (in the file list) persists and the
+ file list does not scroll to the top. (Rob Hooft)
+
+
+
Modified Pmw.Balloon so that it can be bound to a tag associated
+ with several Canvas or Text items. (Magnus Kessler)
+
+
+
21 November 1998
+
+
Cleaned up appearance and colors of Pmw.NoteBookR tabs. (Georg
+ Mischler)
+
+
+
Added buttontype option to Pmw.RadioSelect to support
+ radiobuttons and checkbuttons. (Georg Mischler)
+
+
+
23 November 1998
+
+
Updated usage of bind_class(tag) due to change in return value
+ in Tkinter module in python 1.5.2. (Magnus Kessler, Fredrik Lundh)
+
+
+
The default time displayed in Pmw.TimeCounter is now the current
+ local time, not GMT as before.
+
+
+
The times displayed in the Counter demonstration are now the
+ current local time, not GMT as before.
+
+
+
7 December 1998
+
+
Modified Pmw.ComboBox to take advantage of the fix to the Tkinter
+ bind() method callback handling of Event.widget in python
+ 1.5.2. It works even if the selectioncommand destroys the
+ combobox. For simple comboboxes, the invoke() method now returns
+ the return value of the selectioncommand.
+
+
+
Modified Pmw.EntryField to take advantage of the fix to the
+ Tkinter bind() method callback handling of Event.widget in
+ python 1.5.2. It works even if a user-supplied callback
+ (command, invalidcommand, validator or stringtovalue)
+ destroys the entryfield. Cleans up correctly when destroyed. The
+ invoke() method now returns the return value of the command.
+
+
+
The invoke() method of Pmw.TimeCounter now returns the return
+ value of the command.
+
+
+
Modified Pmw.ButtonBox to use the new (in Tk8.0) default option
+ of the Tkinter Button widget instead of a separate frame.
+ Changed default padding to be more compact. Removed "ring" frame
+ component and "ringborderwidth", "ringpadx" and "ringpady"
+ options. (Georg Mischler)
+
+
+
Changed 'pmw1' fontScheme to set default fonts only when running
+ under posix, since the default fonts on other systems look better.
+
+
+
10 December 1998
+
+
Release of version 0.8
+
+
+
20 January 1999
+
+
Added master option to Pmw.MegaToplevel and removed master
+ argument from the activate method.
+
+
+
Replaced rand module in demos with a simple random number
+ generator (since rand is not built-in on all versions of python).
+
+
+
22 February 1999
+
+
Modified __init__.py so that it only accepts directories whose
+ names begin with Pmw_M_N and which have a /lib/PmwLoader.py/
+ file.
+
+
+
13 May 1999
+
+
Changed Pmw.ScrolledCanvas, Pmw.ScrolledText and Pmw.ScrolledListBox
+ to speed up scrolling if the scrollmodes are not both dynamic.
+
+
+
Changed busy cursor and activate/deactivate code so that it works
+ correctly under fast mouse clicking or fast keyboarding (using
+ accelerators). Also fixed so that grab is correctly restored
+ after a Pmw.ComboBox popup list is unmapped inside a modal dialog.
+ (Clemens Hintze)
+
+
+
Several dialogs now give focus to one of their components (listbox
+ or entry widget) when activated. (Clemens Hintze)
+
+
+
Fixed Pmw.ComboBox so that it unposts popup if the combobox is
+ unmapped and returns grab and focus correctly if destroyed.
+
+
+
Improved tracetk() output to be more readable. Also displays
+ nested calls to the Tk mainloop better and shows callbacks from
+ tcl to python.
+
+
+
Upgraded Blt support to blt2.4i. Graph widget is not backwards
+ compatible with blt2.1.
+
+
+
19 May 1999
+
+
Fixed bug in Pmw.Balloon in placement of balloons over canvas
+ items when the canvas was scrolled. (Tessa Lau)
+
+
+
20 May 1999
+
+
Added new Tk event types (new in Tk 8.0 and 8.0.5) to PmwBase
+ error display method. Also added check for unknown event types to
+ safeguard against future changes. (Magnus Kessler)
+
+
+
Added exclude argument to showbusycursor(). (Rob Hooft)
+
+
+
1 June 1999
+
+
Added wrappers for Blt Stripchart and Tabset widgets. (Nick Belshaw)
+
+
+
Changed createcomponent() so that arguments to the constructor of
+ the component can now be specified as either multiple trailing
+ arguments to createcomponent() or as a single tuple argument.
+
+
+
7 June 1999
+
+
Added call to update_idletasks() in Pmw.ScrolledCanvas,
+ Pmw.ScrolledFrame, Pmw.ScrolledText and Pmw.ScrolledListBox to
+ avoid endless mapping/unmapping of two dynamic scrollbars when the
+ window is first mapped and only one scrollbar is needed.
+ (Reported by Mark C Favas, solution suggested by Dieter Maurer.)
+
+
+
10 June 1999
+
+
Fixed bug in bundlepmw.py when called with -noblt option.
+ (Reported by Kevin O'Connor)
+
+
+
Pmw.ComboBox now unposts the dropdown listbox before the selection
+ callback is invoked, to avoid problems when the callback takes a
+ long time to run. (Reported by Randall Hopper)
+
+
+
11 June 1999
+
+
Release of version 0.8.1
+
+
+
29 June 1999
+
+
PmwMessageBar.message() now replaces newlines with spaces before
+ displaying message. Also applies to helpmessage().
+
+
+
2 July 1999
+
+
Improved toplevel window positioning under NT, and stopped most of
+ the ugly flashing.
+
+
+
5 July 1999
+
+
The pmw1 fontScheme is now supported under NT, as is the size
+ option to Pmw.initialise().
+
+
+
6 July 1999
+
+
Changed the names of positional arguments in the following
+ methods, so that they have less chance of conflicting with keyword
+ arguments: MegaArchetype.createcomponent(), ButtonBox.insert(),
+ ButtonBox.add(), MenuBar.addcascademenu(), MenuBar.addmenuitem()
+ and RadioSelect.add().
+
+
+
9 July 1999
+
+
Added images and example code to the megawidget reference manuals.
+ (Suggested by Joerg Henrichs)
+
+
+
Fixed showbusycursor() under NT. It now calls update() instead of
+ update_idletasks() to force display of cursor. (Solution
+ suggested by George Howlett)
+
+
+
Improved display of arrows in ComboBox, Counter and TimeCounter.
+
+
+
16 July 1999
+
+
Removed Pmw.maxfontwidth() function, since better functionality is
+ now supplied by the Tk "font measure" command.
+
+
+
Removed Pmw.fontexists() function, since in Tk8.0 all fonts exist.
+
+
+
28 July 1999
+
+
Fixed bug in date counter with separator other than '/' and time
+ counter with separator other than ':'. (David M. Cooke, Alan
+ Robinson)
+
+
+
Under NT, the font named 'fixed' is not fixed width, so added
+ alias from 'Fixed' to 'Courier'.
+
+
+
Changed the bind() and tagbind() methods of Pmw.Balloon to
+ remove a potential memory leak. The methods now store the
+ funcids of the callback functions, so that if the same widget or
+ tag is bound twice, the balloon can remove the old bindings.
+ (Peter Stoehr)
+
+
+
Changed NoteBookR so that lowercmd, creatcmd and raisecmd are
+ called in that order when a page is selected. Also fixed bug
+ which always raised page 0 when notebook is resized. (Scott
+ Evans, Charles Choi)
+
+
+
1 August 1999
+
+
Added dynamicGroups argument to defineoptions() method and
+ modified ButtonBox, MenuBar, PanedWidget, RadioSelect to register
+ their dynamic groups.
+
+
+
Pmw.initialise() can now be called multiple times, with
+ different root arguments, but only sequentially. Pmw does not
+ (yet) support multiple simultaneous interpreters. Modified
+ Pmw.EntryField so that it recreates class bindings when
+ Tkinter.root changes.
+
+
+
4 August 1999
+
+
Added relmouse option to Pmw.Balloon. Fixed Pmw.Balloon so that
+ the balloon is not displayed off-screen. (Tessa Lau)
+
+
+
16 August 1999
+
+
Added disableKeyboardWhileBusy option to initialise(). To ignore
+ keyboard input while displaying the busy cursor, Pmw sets the
+ focus for each toplevel window to the Blt busy window. However,
+ under NT, this causes each window to be raised. If this is not
+ acceptable, programs running on NT can request show/hidebusycursor
+ not to ignore keyboard input.
+
+
+
25 August 1999
+
+
Added Pmw.Blt.busy_forget() and used it in Pmw.hidebusycursor()
+ when running under NT. There is a bug in the Blt busy release
+ command under NT where it sometimes fails to display the busy
+ cursor. Using busy forget avoids the problem.
+
+
+
27 September 1999
+
+
Added busyCursorName option to Pmw.initialise() and added cursor
+ argument to Pmw.Blt.busy_hold(). (Mark Favas)
+
+
+
20 October 1999
+
+
Replaced Pmw.NoteBookR and Pmw.NoteBookS with completely rewritten
+ Pmw.NoteBook.
+
+
+
Renamed Pmw.OptionMenu.get() to Pmw.OptionMenu.getcurselection()
+ and Pmw.PanedWidget.remove() to Pmw.PanedWidget.delete(), to be
+ more consistent with other megawidgets.
+
+
+
The index() method of several megawidgets now use Pmw.END,
+ Pmw.SELECT and Pmw.DEFAULT instead of strings, since these may
+ conflict with component names.
+
+
+
Pmw.OptionMenu.index() now uses Pmw.SELECT to return
+ index of the currently selected menu item, rather than None.
+
+
+
Added destroy() method to Pmw.MegaArchetype to handle cleaning up
+ of _hullToMegaWidget mapping.
+
+
+
Removed exclude argument from Pmw.showbusycursor() and added
+ Pmw.excludefrombusycursor() function instead. (Rob Hooft)
+
+
+
Fixed several bugs for Windows NT.
+
+
+
Added Pmw.ButtonBox.button() and Pmw.RadioSelect.button().
+
+
+
Added Pmw.Color.bordercolors().
+
+
+
21 October 1999
+
+
Release of version 0.8.3. (Version 0.8.2 was not released.)
+
+
+
30 October 1999
+
+
Added arrownavigation option and previouspage() and nextpage()
+ methods to Pmw.NoteBook. (Peter Funk)
+
+
+
Renamed the setnaturalpagesize() method of Pmw.NoteBook to
+ setnaturalsize() to be consistent with Pmw.PanedWidget.
+
+
+
Changed Pmw.excludefrombusycursor() to Pmw.setbusycursorattributes().
+ Removed busyCursorName option from Pmw.initialise() and added
+ cursorName attribute to Pmw.setbusycursorattributes().
+
+
+
Added documentation source and build scripts to ftp site.
+
+
+
6 November 1999
+
+
Fixed memory leaks when destroying megawidgets. Added automatic
+ check for memory leak to test script used by all tests.
+ Pmw.initialise() now uses a hook into Tkinter.Widget.destroy
+ rather than Tkinter.Frame.destroy to handle the case of
+ Pmw.NoteBook being destroyed (since the notebook hull is a canvas
+ and not a frame). Window manager delete protocol callbacks are
+ now cleaned up. Pmw.ScrolledListBox event bindings now do not
+ leak. (Reported by Jeff Weeks)
+
+
+
Removed key bindings for Pmw.ScrolledListBox except space and return keys.
+
+
+
20 November 1999
+
+
Fixed bug in Pmw.Balloon when the canvas or text item that
+ triggered the balloon is deleted before the balloon is displayed
+ by the initwait timer. (Magnus Kessler)
+
+
+
Added 'nograb' to globalMode option of activate() method. (Rob Hooft)
+
+
+
Added __setitem__ method to Pmw.MegaArchetype, so that megawidget
+ options can be now set using megawidget['option'] = value style.
+ (Oliver Gathmann)
+
+
+
27 December 1999
+
+
Converted from regex module to re module, since regex is not
+ implemented for Jpython. (Finn Bock)
+
+
+
30 December 1999
+
+
Added clear() method to Pmw.ScrolledListBox (suggested by Carson
+ Fenimore).
+
+
+
15 March 2000
+
+
Fixed problem in PmwBase when deleting windows that were created
+ before Pmw was initialised (such as splash windows displayed while
+ the application is coming up). (Mark Favas)
+
+
+
Added splash window to Pmw demo. (Mark Favas)
+
+
+
30 April 2000
+
+
Added Pmw.MainMenuBar megawidget, which uses the menubar feature
+ of Tk to provide platform specific menu bars.
+
+
+
Fixed Pmw.Counter and several other megawidgets so that certain
+ hull constructor keywords, such as hull_relief and
+ hull_borderwidth, are not overriden in the constructor.
+
+
+
Thanks to Peter Cashin for his help on how to unpack gzipped tar
+ files on Microsoft Windows operating systems.
+
+
+
Added Pmw.HistoryText megawidget. This can be used as the basis
+ of an interactive text-based database query gui. It maintains a
+ history of each query and allows editing of prior queries.
+
+
+
Added references to the Pmw.Blt.Graph documentation by Bjørn Ove
+ Thue and Hans Petter Langtangen.
+
+
+
Searched for and fixed memory leaks. There are no more known memory leaks.
+
For commands created by bind: these are cleaned up by Tkinter
+ when the widget is destroyed. Pmw.Balloon, which repeatedly
+ binds to the same widget (or item, using tag_bind), has been
+ fixed by passing the old command into the call to unbind or
+ tag_unbind which is cleaned up by Tkinter.
+
+
+
For commands created by class_bind: most class bindings are
+ only created once (per Tk interpreter) and so do not need to be
+ cleaned up. The exception is adding and deleting menus in
+ Pmw.MenuBar. This has now been fixed to clean up class_bind
+ commands when deleting menus.
+
+
+
Callbacks given to command, xscrollcommand, yscrollcommand, etc
+ options are cleaned up by Tkinter when the widget is destroyed.
+ Cases where Pmw repeatedly sets such options have now been fixed
+ to clean up the old command before configuring the new one.
+ These are in setitems in Pmw.OptionMenu and when modifying the
+ scrollcommand options in several of the scrolled widgets.
+
+
+
Pmw now cleans up calbacks it registers with the
+ WM_DELETE_WINDOW protocol for toplevel windows.
+
+
+
+
+
Added ManualTests.py to tests directory for tests which need to be
+ run by hand.
+
+
+
12 May 2000
+
+
Release of version 0.8.4.
+
+
+
17 May 2000
+
+
Modified Pmw.Counter to deal with the presence (python up to
+ 1.5.2) or absence (python 1.6 and after) of an L at the end of
+ the ascii representation of a long. (Mark Favas)
+
+
+
Fixed bug in Pmw.ScrolledFrame when given invalid flex options.
+ (Stephen D Evans)
+
+
+
23 January 2001
+
+
Moved Pmw home from www.dscpl.com.au to pmw.sourceforge.net.
+
+
+
Added pmw2 font scheme, since the font used for balloon text with
+ pmw1 is too small on Linux.
+
+
+
Removed syntax coloring from code window in demos. It did not
+ look good and the pattern matching was not always correct.
+
+
+
Changed font size used for demos to 12 for Unix, since 14 looked
+ too big under Linux.
+
+
+
Minor fixes to tests for Tk 8.3.
+
+
+
8 February 2001
+
+
Release of version 0.8.5
+
+
+
18 February 2001
+
+
Added xview() and yview() methods to Pmw.ScrolledFrame (suggested
+ by Christer Fernstrom).
+
+
+
Made tktrace output more readable.
+
+
+
Added noBltBusy option to Pmw.initialise.
+
+
+
Fixed bug where combobox dropdown list could stay mapped after
+ entryfield was unmapped.
+
+
+
Improved scrolling in scrolled frame.
+
+
+
21 February 2001
+
+
Fixed tests for recent version of Blt graph (reported by
+ Venkatesh Prasad Ranganath).
+
+
+
Fixed problem in Pmw.ScrolledFrame in python 1.5 - string.atof
+ does not accept a number as argument, but it does in python 2.0.
+
+
+
24 February 2001
+
+
Modified Pmw.OptionMenu documentation to specify that list
+ elements must be strings (problem reported by Guy Middleton).
+
+
+
Fixed bug in Pmw.OptionMenu where the wrong item was displayed
+ when an integer item in the menu was selected with the mouse (even
+ though items should be strings).
+
+
+
Added work around to Pmw.ScrolledFrame for bug in Tk when
+ retrieving value from scrollbars soon after creation.
+
+
+
27 February 2001
+
+
Added HistoryText and MainMenuBar to bin/bundlepmw.py - accidently
+ left out.
+
+
+
13 April 2001
+
+
Changed default foreground (text) of Pmw.Balloown to black. (Eric
+ Pettersen)
+
+
+
Added default fontScheme to Pmw.initialise().
+
+
+
Added -fontscheme and -fontsize options to demo.
+
+
+
Added updatelayout() to Pmw.PanedWidget for use when dynamically
+ adding and deleting panes. (G Cash)
+
+
+
Added move() to Pmw.PanedWidget to move panes. (G Cash)
+
+
+
20 April 2001
+
+
Fixed bug in Pmw.Balloon where the balloon would reappear if the
+ mouse button was pressed down inside a widget and then, while the
+ mouse button was being held down, the mouse was moved outside of
+ the widget and then moved back over the widget.
+
+
+
Fixed bug in Pmw.Balloon when destroying widgets while the balloon
+ was up. In this case, the balloon remained displayed even though
+ the widget had been destroyed. (Reported by Stefan Schone.)
+
+
+
Fixed bug in Pmw.Balloon when destroying widgets during the
+ initwait period. In this case, an error occurred when the
+ initwait timer went off when it tried to access the destroyed
+ widget. (Reported by Stefan Schone.)
+
+
+
Fixed Pmw.Balloon so that unbinding withdraws the balloon if
+ the widget being unbound is the widget which triggered the balloon.
+
+
+
Modified Pmw.Balloon so that when deleting a canvas or text item,
+ tagunbind() can be called which will withdraw the balloon if it
+ was triggered by the item. Unfortunately this can not be
+ automated as for widgets since Tk does not support <Destroy>
+ bindings on canvas or text items, so there is no way that
+ Pmw.Balloon can be notified of the deletion of an item.
+
+
+
Updated tests for python 2.1.
+
+
+
21 May 2001
+
+
Pmw.OptionMenu now defaults to taking focus (on <Tab> key).
+
+
+
15 May 2002
+
+
Fixed bug in Pmw.Graph.element_closest() where element names
+ should follow option arguments. (Val Shkolnikov)
+
+
+
5 June 2002
+
+
Added command option to Pmw.TimeCounter.
+
+
+
Finished all documentation.
+
+
+
Fixed bug in documentation creation script which, since python
+ 2.0, printed default values of real options (such as the
+ horizfraction option of Pmw.ScrolledFrame) with too many digits
+ (such as 0.050000000000000003).
+
+
+
Fixed bug in setgeometryanddeiconify for cygwin python (John
+ Williams).
+
+
+
4 July 2002
+
+
Added master option to MegaToplevel.show()
+
+
+
Improved MegaToplevel.show() so that tkraise is not called
+ unecessarily, thus avoiding 2 second delay under certain window
+ managers (such as sawfish) in most circumstances. There are still
+ problems with the Enlightenment window manager.
+
+
+
18 August 2002
+
+
Added columnheader, rowheader and rowcolumnheader components to
+ Pmw.ScrolledText. (Rob Pearson)
+
+
+
Added getvalue() and setvalue() methods to several megawidgets
+ as a consistent way to set and get the user-modifiable state.
+ (Cimarron Taylor)
+
+
+
Made sub-classing simpler when no new options or components are
+ being created. A sub-class of a Pmw megawidget does not need to
+ have an __init__() method. If it does, it does not need to call
+ defineoptions(). Also, initialiseoptions() no longer requires an
+ argument (for backwards compatibility it may take an argument, but
+ it is ignored).
+
+
+
24 August 2002
+
+
Release of version 1.0
+
+
+
26 August 2002
+
+
Minor fixes.
+
+
+
Release of version 1.1
+
+
+
4 September 2002
+
+
Added collapse, expand and toggle methods and collapsedsize option
+ to Pmw.Group. (Rob Pearson)
+
+
+
5 September 2002
+
+
Added sticky option to several megawidgets.
+
+
+
18 September 2002
+
+
Added appendtext method to Pmw.ScrolledText. (Graham Dumpleton)
+
+
+
26 September 2002
+
+
Modified Pmw.ScrolledListBox to call dblclickcommand on
+ <Double-ButtonRelease-1> rather than <Double-ButtonPress-1> which
+ caused problems if the double button press unmapped the
+ ScrolledListBox. In this case, the second button release of the
+ double click is given to another widget. (Eric Pettersen)
+
+
+
14 June 2003
+
+
Changes for python 2.3 and Tcl/Tk 8.4.2:
+
Wrapped calls to cget() for Tkinter widgets in a call to
+ str(). Before python 2.3 cget() always returned a string.
+ Under python 2.3, Tkinter sometimes returns non-string values
+ (such as int, or Tcl_Obj). Made similar change when using
+ configure() to retrieve values. Fixed tests to handle integer
+ and Tcl_Obj return value from cget(). (Charles Doutriaux)
+
+
+
Fixed uses of col field of grid command. Must use full
+ column under Tcl/Tk 8.4.2.
+
+
+
Fixed PmwEntryField.py, PmwMessageBar.py, PmwScrolledField.py
+ so that the text is not greyed out under Tcl/Tk 8.4.2. This
+ was caused by a change in behaviour of the 'disabled' state
+ and the Tk entry widget. Now use new 'readonly' state for
+ Tcl/Tk 8.4.2.
+
+
+
Test script now ignores Blt test for Tcl/Tk 8.4.2, since it
+ causes Blt 2.4z to core dump. Blt needs to be fixed.
+
+
+
Changed Dialog test to work around problem caused by Tk 8.4.2
+ enforcing transient behaviour of windows. When activate() is
+ called on a dialog whose parent is withdrawn, then the dialog
+ window is made transient. Under old versions of Tk, the
+ transient dialog was displayed, but under 8.4.2 the dialog is
+ not displayed. Work around is to deiconify parent of dialog.
+ Copyright 1997-1999 Telstra Corporation Limited, Australia
+ Copyright 2000-2002 Really Good Software Pty Ltd, Australia
+
+
Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+
The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/counter1.gif b/Pmw/Pmw_1_2/doc/counter1.gif
new file mode 100644
index 00000000..64efe355
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/counter1.gif differ
diff --git a/Pmw/Pmw_1_2/doc/counter2.gif b/Pmw/Pmw_1_2/doc/counter2.gif
new file mode 100644
index 00000000..be894ed3
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/counter2.gif differ
diff --git a/Pmw/Pmw_1_2/doc/demosandtests.html b/Pmw/Pmw_1_2/doc/demosandtests.html
new file mode 100644
index 00000000..d7190a3e
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/demosandtests.html
@@ -0,0 +1,364 @@
+
+
+
+
+
+ Pmw demonstrations and tests
+
+
+
+
+
Pmw demonstrations and tests
+
+
+
+
+
+
+ Pmw comes with an extensive range of demonstrations and tests. The
+ demonstrations can be used to get a feel for what is provided by Pmw
+ and the demonstration code can be viewed to see examples of how to
+ use Pmw. The tests can be executed to check that there are no
+ problems with running Pmw in your environment.
+
+
+
+
+
Demonstrations
+
+ The Pmw demos directory contains demonstration scripts
+ showing many of the features of Pmw megawidgets. To view a
+ comprehensive package of all the demonstrations, including a view of
+ the source code, run the All.py script. Run
+ All.py -help for a short description of the script's
+ options.
+
+
+ All of the demonstrations may also be run separately. Most of the
+ demonstrations show some of the features of one of the Pmw
+ megawidgets. For example, to see a demonstration of the ButtonBox
+ megawidget, change into the demos directory and
+ run
+
+
+
+
+
+python ButtonBox.py
+
+
+
+
+
+ Other demonstrations, which show other features of Pmw include
+
+
+
+
+BltGraph.py demonstrates the Pmw interface to
+ the BLT graph and vector commands
+BltTabset.py demonstrates the Pmw interface to
+ the BLT tabset command
+Colors.py how to set color schemes
+ConfigClass.py how to configure the python class
+ of a megawidger component
+ErrorHandling.py how Pmw displays run time errors
+ in a window
+ExampleDemo.py template for new demonstrations
+Grid.py the Tkinter Grid geometry manager
+LogicalFont.py how to use standard values for fonts
+MessageInfo.py how to extend the Pmw MegaToplevel
+ class
+NestedDialogs.py how nested modal dialogs behave
+Resources.py how to use the option database to
+ modify Tk widget option defaults
+Resources_Pmw.py how to use the option database to
+ modify megawidget option defaults
+ShowBusy.py demonstrates the Pmw interface to
+ the BLT busy command
+SpecialEntry.py deriving from Pmw.EntryField
+Spectrum.py some of the Pmw color handling
+ functions
+SpeedTest.py tests the speed of creating Pmw
+ megawidgets
+TextDisplay.py how to extend the Pmw MegaWidget
+ class
+WidgetDestroy.py megawidget destruction
+
+
+
+
+Creating demonstrations of new megawidgets
+
+
+If you create a new megawidget you can create a demonstration for it
+by using the file
+ExampleDemo.py as a
+template. This template allows the demonstration to be run
+individually or to be automatically included as part of the
+demonstration package All.py. You should take a copy of
+the template and name the new file after your megawidget. You should
+then replace each instance of the word EXAMPLE with the
+name of your megawidget and replace the code in the
+__init__ method with code to create and initialise one or
+more instances of your megawidget, which should be a child of
+parent. You can add other methods as necessary.
+
+
+
+
+
Tests
+
+ The Pmw tests directory contains a test framework
+ and a set of test scripts for Pmw.
+ The tests cover the standard Tkinter module and most of the Pmw megawidgets.
+ The tests make a great
+ demonstration of the flexibility of the megawidgets. Simply change
+ into the tests directory and run
+ python All.py.
+
+
+ If all tests pass there should be no output printed to standard
+ output. If any of the tests fail, please send the test output to
+ the maintainer at
+ gregm@iname.com.
+
+
+
+
+ All of the tests may be run separately. Most of the tests test the
+ features of one of the Pmw megawidgets. For example, to execute the
+ test for the ButtonBox megawidget, run
+
+
+
+
+
+
+python ButtonBox_test.py
+
+
+
+
+
+ The Test.py file contains general testing functions and is imported
+ by all test files.
+ Other files, which test other features of Pmw include
+
+
+
+
+Blt_test.py BLT vector and graph interface
+Colors_test.py setting color schemes
+MegaWidget_test.py creation of megawidget classes
+Options_test.py option and component handling
+PmwBase_test.py more option and component handling
+Tkinter_test.py Tk widgets in the Tkinter module
+
+
+
+
+Creating tests for new megawidgets
+
+
+If you create a new megawidget you should create a test for it. There
+is no template file for creating tests, but by looking at the other
+Pmw tests (for example,
+ScrolledText_test.py) you
+will get some idea of how to create a test for your megawidget.
+
+
+
+
+The test files are designed to be run both individually or
+automatically by the test package All.py. Each test file
+must define the testData tuple. This consists of a
+sequence of 2-element tuples, each tuple being a test specification
+for one megawidget. Usually a file tests only one megawidget and so
+there is only one test specification. The first element in the
+specification is the megawidget class and the second is a sequence of
+(yet more) 2-element tuples. In each of these tuples, the first
+element is a sequence of individual tests to perform on an instance of
+the megawidget and the second element is a dictionary to use for
+the keyword arguments when creating the instance. Each individual
+test is a tuple, the meaning of which depends on the type of the first
+element, which may be either a string, a function or a method of the
+megawidget class, as explained below.
+
+
+
+
+
+
+If the first element is a string, then it is treated as an option of
+the megawidget and configure() is called to set the option to the
+value specified by the second element. After setting the option,
+cget() is called to query the option. If the test tuple has three
+elements, then the value returned by cget() must equal the value
+specified by the third element. Otherwise, the value returned must
+equal the value specified by the second element. For example,
+
+
+
+
+
+('vscrollmode', 'static'),
+('text_relief', 'sunken'),
+('vscrollmode', 'bogus', 'ValueError: bad vscrollmode ' +
+ 'option "bogus": should be static, dynamic, or none'),
+
+
+
+
+
+
+
+If the first element is a function or method, then the function or
+method is called. The arguments to the call are given by the second
+element. (As a special case, if the second element is not a tuple, it
+is used as the only argument to the call.) The test tuple may have 2,
+3 or 4 elements.
+
+
+
+
+
+If it has two elements, then the value returned by the call must be
+None. For example,
+
+
+If it has four elements, then the third element is a dictionary to use
+for the keyword arguments in the call and the value returned by the
+call must equal the value specified by the fourth element. For
+example,
+
+
+If is has three elements and the third element is a dictionary, then
+it is used for the keyword arguments in the call and the value
+returned by the call must be None. For example
+
+
+
+
+
+(c.configurepane, 'first', {'size' : 200}),
+
+
+
+
+
+
+
+If is has three elements and the third element is not a dictionary,
+then the value returned by the call must equal the value specified by
+the third element. For example,
+
+
+Some special functions and values supplied by the Test module that may
+be used in the tests include:
+
+
+
+
+Test.callback callback taking no arguments
+Test.callback1 callback taking one argument
+Test.callbackN callback taking any number of arguments
+
+Test.currentWidget returns the widget instance being tested
+Test.num_options returns number of options for the widget
+
+Test.earthris a sample Tkinter.PhotoImage
+Test.flagup a sample Tkinter.BitmapImage
+Test.floatvar a Tkinter.DoubleVar
+Test.stringvar a Tkinter.StringVar
+
+
+
+
+
+ To slow down a test (to see what is being displayed), add the
+ following line which sets the delay between tests to (say) 1000
+ milliseconds:
+
+
+
+
+
+Test.setdelay(1000)
+
+
+
+
+
+ To print information about what is being tested, add the line:
+
+
+ There are two aspects of Pmw, unrelated to megawidgets, that
+ require special attention. Firstly, Pmw is made up of many
+ sub-modules, potentially making access to its various classes and
+ functions cumbersome for the user. Secondly, Pmw is regularly
+ being modified and added to, thus requiring the release of new
+ versions. Therefore, techniques for making access to the
+ sub-modules easy and efficient and for dealing with the different
+ versions have been developed. These techniques are incorporated
+ into the dynamic loader which Pmw creates when it is first
+ imported.
+
+
The first purpose of the loader is to give access to all Pmw classes
+ and functions through a single entry point, the Pmw. prefix. For
+ example, to access the ComboBox class (which resides in one of the
+ sub-modules of Pmw), you just have to use Pmw.ComboBox. Without
+ the loader, this would be a more complicated reference, such as,
+ hypothetically, Pmw.PmwComboBox.ComboBox.
+
+
The second purpose of the loader is to delay the importing of the
+ sub-modules until they are needed. This improves the startup time
+ of applications which only use a few Pmw megawidgets. It also
+ allows more megawidgets to be added to the library without slowing
+ down applications which do not use them.
+
+
The third purpose of the loader is to allow a script using Pmw to
+ specify which version of Pmw it requires. This allows an
+ application to continue working correctly even after newer releases
+ of Pmw have been made which are not compatible with the version
+ expected by the application. Several versions of Pmw can be
+ installed at once, with the actual version used being specified by
+ each application. In addition, the loader can be configured to
+ search in one or more alpha versions of Pmw. These versions may
+ contain new megawidgets, or new versions of existing megawidgets,
+ that are currently not in the base releases.
+
+
Several functions are available to set and query the version of
+ Pmw being used. These are Pmw.setversion() and
+ Pmw.setalphaversions() which specify the version and alpha
+ versions (if any) to use for this session; Pmw.version() which
+ returns the version(s) being used by this session; and
+ Pmw.installedversions() which returns the version(s) of Pmw
+ currently installed. These are described in the
+ Pmw functions reference manual.
+
+
When Pmw is first imported, an instance of PmwLoader is created
+ and placed into sys.modules['Pmw']. From that point on, any
+ reference to attributes of the Pmw 'module' is handled by the
+ loader. The real Pmw package is stored in sys.modules['_Pmw'].
+
+
The loader searches the Pmw package base directory for
+ sub-directories with the prefixes Pmw_ and Alpha_, which
+ contain Pmw base releases and alpha releases. The version numbers
+ are given by the part of the directory name following the prefix.
+ These versions are available for use and are those returned by the
+ Pmw.installedversions function. The initial version is set to
+ the base release with the greatest version number. When the first
+ reference to a Pmw class or function is made, the loader reads the
+ files named Pmw.def in the current base version directory and
+ also in the alpha directories (if any). These files list all the
+ classes and functions supported by the version. Pmw attributes
+ are first searched for in the alpha directories and then in the
+ base version directory. The first directory which supports the
+ reference is used. In this way, alpha versions override base
+ versions.
+
+
The directory Alpha_99_9_example contains a simple example of
+ how to structure an alpha version. The following code can be used
+ to request that the alpha version be used and then creates an
+ instance of a new megawidget defined in the alpha version.
+
+
import Pmw
+ Pmw.setalphaversions('99.9.example')
+
+ # Create a standard message dialog using the base Pmw version.
+ ordinary = Pmw.MessageDialog(
+ message_text = 'Ordinary\nPmw Dialog')
+
+ # Create an example dialog using the alpha Pmw version.
+ alpha = Pmw.AlphaExample()
+
+
Freezing Pmw
+
+
Since the dynamic loader requires that Pmw be installed at run
+ time, it can not be used when freezing Pmw. In this case, a
+ single module containing all Pmw code is required, which can then
+ be frozen with the rest of the application's modules. The
+ bundlepmw.py script in the Pmw bin directory can be used to
+ create such a file. This script concatenates (almost) all Pmw
+ megawidget files into a single file, Pmw.py, which it writes to
+ the current directory. The script is called like this:
The last argument should be the path to the lib directory of the
+ required version of Pmw. By default, the Pmw.py file imports
+ the PmwBlt and PmwColor modules and so, to freeze an
+ application using Pmw, you will need to copy the files PmwBlt.py
+ and PmwColor.py to the application directory before freezing.
+
+
If you are sure that your application does not use any of the
+ Pmw.Blt or Pmw.Color functions, you can use the -noblt or
+ -nocolor options. In this case Pmw.py will be modified so
+ that it does not import these module(s) and so will not need to be
+ included when freezing the application.
+
+
If your application only uses a few Pmw megawidgets, you can
+ remove the references to the usused ones in the files list in
+ the bundlepmw.py code. To make the change, take a copy of the
+ script and modify it. This will make the Pmw.py file smaller.
+ However, be sure that you do not delete megawidgets that are
+ components or base classes of megawidgets that you use.
+ Pmw is a toolkit for building high-level compound widgets, or
+ megawidgets, constructed using other widgets as component parts.
+ It promotes consistent look and feel within and between graphical
+ applications, is highly configurable to your needs and is easy to
+ use.
+
+
Pmw consists of:
+
A few base classes, providing a foundation for building
+ megawidgets.
+
+
+
A library of flexible and extensible megawidgets built on
+ the base classes, such as buttonboxes, notebooks,
+ comboboxes, selection widgets, paned widgets, scrolled
+ widgets and dialog windows.
+
+
+
A lazy importer/dynamic loader which is automatically
+ invoked when Pmw is first imported. This gives unified
+ access to all Pmw classes and functions through the Pmw.
+ prefix. It also speeds up module loading time by only
+ importing Pmw sub-modules when needed.
+
+
+
Complete reference documentation, covering all classes and
+ functions including all megawidgets and their options,
+ methods and components. Helpful tutorial material is also
+ available.
+
+
+
A test framework and tests for Pmw megawidgets.
+
+
+
A slick demonstration of the megawidgets.
+
+
+
An interface to the BLT busy, graph and vector commands.
+
+
+
+
The interface to Pmw megawidgets is similar to basic Tk widgets, so it
+ is easy for developers to include both megawidgets and basic Tk
+ widgets in their graphical applications. In addition, Pmw
+ megawidgets may themselves be extended, using either inheritance or
+ composition.
+
+
The use of the Pmw megawidgets replaces common widget combinations
+ with higher level abstractions. This simplifies code, making it
+ more readable and maintainable. The ability to extend Pmw
+ megawidgets enables developers to create new megawidgets based on
+ previous work.
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/halfblueball.gif b/Pmw/Pmw_1_2/doc/halfblueball.gif
new file mode 100644
index 00000000..6977920d
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/halfblueball.gif differ
diff --git a/Pmw/Pmw_1_2/doc/howtobuild.html b/Pmw/Pmw_1_2/doc/howtobuild.html
new file mode 100644
index 00000000..4a408b48
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/howtobuild.html
@@ -0,0 +1,465 @@
+
+
+
+
+
+ How to build Pmw megawidgets
+
+
+
+
+
How to build Pmw megawidgets
+
+
+
+
+
+
+
Introduction
+
+ This document briefly describes how to design and code Pmw
+ megawidgets by inheriting from the Pmw base classes. It shows step
+ by step how to build a simple example megawidget. This megawidget
+ allows the user to select one of a range of numbers and it also
+ indicates if the selected number is greater than a given threshold.
+
+
+
+
+
Choosing the components
+
+
+ The megawidget will be built using a Tkinter.Scale widget to allow
+ the user to select a number in a range, and a Tkinter.Frame widget
+ to act as an indicator, displaying red (say) if the selected number
+ exceeds the threshold. It will look something like this:
+
+
+
+
+
+
+
+
+ The programmer using this megawidget will need access to the scale
+ widget, since they will need to set the scale's range. Therefore
+ the scale will be made a component of the megawidget. The
+ programmer will probably not need access to the indicator frame,
+ but, just in case the need arises to change the borderwidth or
+ relief of the indicator, we will make it a component too. This
+ illustrates a convention about components - for maximum
+ configurability, make all sub-widgets components.
+
+
+
+
+
Choosing the options
+
+
+ Apart from the component options now available through the scale and indicator
+ components, the megawidget will need a few options of its own. It
+ will need a threshold option to set the threshold.
+ It may also need options to set the colors of the indicator when the
+ selected value is both above and below the threshold. Other options
+ could be orient or indicatorpos to
+ specify the relative position of components and
+ margin, padx or
+ pady to specify spacing between and around the
+ components. For this example, we will define three options -
+ threshold, colors and
+ value. The colors option will be
+ a 2-element sequence specifying two colors (below threshold, above
+ threshold). The value option will be the initial
+ value of the scale.
+
+
+
+
+
Coding the megawidget
+
+
+ The first things to do are to decide on a name for the new
+ megawidget, decide which base class to inherit from and to begin to
+ write the constructor. Most Pmw megawidgets are derived from either
+ Pmw.MegaWidget, Pmw.MegaToplevel or Pmw.Dialog. In this case, since
+ the widget is not to be contained within its own toplevel window, we
+ will inherit from Pmw.MegaWidget. The constructors of megawidgets
+ take one argument (the widget to use as the parent of the
+ megawidget's hull, defaulting to the root window) and any number of
+ keyword arguments.
+
+
+
+
+class ThresholdScale(Pmw.MegaWidget):
+ """ Megawidget containing a scale and an indicator.
+ """
+
+ def __init__(self, parent = None, **kw):
+
+
+
+ Next, we need to define the options supplied by this megawidget.
+ Each option is specified by a 3-element sequence. The first element
+ is the option's name. The second element is the default value. The
+ third element is either a callback function,
+ Pmw.INITOPT or None. In the first
+ case, the function is called at the end of construction (during the
+ call to self.inialiseoptions) and also
+ whenever the option is set by a call to
+ configure. Pmw.INITOPT indicates that
+ the option is an initialisation option - it cannot be set by calling
+ configure. None indicates that the
+ option can be set by calling configure, but that there
+ is no callback function.
+
+
+
+
+ The call to self.defineoptions also includes the
+ keyword arguments passed in to the constructor. The value given to
+ any option specified in the keywords will override the default
+ value.
+
+
+ After defining the options, the constructor of the base class should
+ be called. The options need to be defined first so that a derived
+ class can redefine the default value of an option defined in a base
+ class. This is because the value specified by the derived class
+ must be made available before the base class constructor is called.
+ The keyword
+ arguments should not be passed into the base class constructor since
+ they have already been dealt with in the previous step.
+
+
+
+
+ # Initialise base class (after defining options).
+ Pmw.MegaWidget.__init__(self, parent)
+
+
+
+ Now we should create the components. The components are created as
+ children (or grandchildren ...) of the megawidget's interior.
+
+
+
+
+ # Create the components.
+ interior = self.interior()
+
+
+
+ The first component to create is the indicator. The
+ createcomponent method creates the sub-widget and
+ registers the widget as a component of this megawidget. It takes
+ five arguments plus any number of keyword arguments. The arguments
+ are name, aliases, group, class and constructor arguments. See the
+ Pmw.MegaArchetype reference manual)
+ for full details.
+
+
+ The scale component is created in a similar way. In this case, the
+ initial value of the scale is also set to the value of the
+ value initialisation option.
+
+
+
+
+ # Create the scale component.
+ self.scale = self.createcomponent('scale',
+ (), None,
+ Tkinter.Scale, (interior,),
+ command = self._doCommand,
+ tickinterval = 20,
+ length = 200,
+ from_ = 100,
+ to = 0,
+ showvalue = 0)
+ self.scale.grid()
+
+ value = self['value']
+ if value is not None:
+ self.scale.set(value)
+
+
+
+ At the end of the constructor, the initialiseoptions
+ method is called to check that all keyword arguments have been used
+ (that is, the caller did not specify any unknown or misspelled
+ options) and to call the option callback functions.
+
+
+
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+
+
+ All other methods must now be defined. In this case, only one
+ method is required - a method called whenever the scale changes and
+ which sets the indicator color according to the threshold.
+
+
+
+
+ def _doCommand(self, valueStr):
+ if self.scale.get() > self['threshold']:
+ color = self['colors'][1]
+ else:
+ color = self['colors'][0]
+ self.indicator.configure(background = color)
+
+
+
+ To complete the megawidget, methods from other classes can be
+ copied into this class. In this case, all Tkinter.Scale methods
+ not already defined by the megawidget are made available as methods
+ of this class and are forwarded to the scale component. Note that
+ the third argument to Pmw.forwardmethods is the name of
+ the instance variable referring to the Tkinter.Scale widget and not
+ the name of the component. This function is called outside of and
+ after the class definition.
+
+
+ Important note: If a megawidget defines options
+ using defineoptions(), then this method must be
+ called in the megawidget constructor before the call to the base
+ class constructor and a matching call to
+ initialiseoptions() must made at the end of the
+ constructor. For example:
+
+
+ The code below creates two of our example megawidgets. The first is
+ created with default values for all options. The second is created
+ with new values for the options. It also redefines some of the
+ options of the components.
+
+
+ The complete code for this example can be seen
+ here.
+
+
+
+
+
Exercises
+
+
+ These exercises build on the example presented so far.
+
+
+
+
+
+ Change the call to create mega1 so that the scale
+ widget displays the current value next to the slider. (You may
+ need to look at the Tk scale manual page to find which option to
+ the scale component to set.) You will be able to
+ do this without modifying the ThresholdScale class code.
+
+
+
+ Add a Tkinter.Label component between the indicator and scale
+ components. Modify the _doCommand method so that it
+ displays the current value of the scale in this label.
+
+
+
+ Modify the colors and threshold
+ options so that they both accept a tuple. Now implement multiple
+ thresholds, so that the indicator displays one of several colors,
+ depending on the value of the scale.
+
+
+
+ Add an orient initialisation option and lay out
+ the components horizontally or vertically depending on its value.
+
+
+
+ Read the description of the createlabel() method in
+ the Pmw.MegaArchetype reference
+ manual and add labelpos and
+ labelmargin initialisation options which allow
+ the creation of a label for the megawidget.
+
+
+
+
+
+ An example of how these changes can be made can be seen
+ here.
+
+
+
+
+
Contributing your megawidgets to Pmw
+
+
+ If you have completed a megawidget that may be useful to others, you
+ may like to consider contributing it to Pmw. See
+ Contributions welcome for
+ how to contribute.
+
+
+
+
+
Pmw coding conventions
+
+
+As a final note, the Pmw code makes an attempt to follow these coding
+conventions.
+
+
+
+
+ Class names: initial of each word is upper case (including first word).
+
+
+
+ Public method and function names: all in lower case.
+
+
+
+ Megawidget options: all in lower case.
+
+
+
+ Megawidget component names: all in lower case.
+
+
+
+ Function arguments: initial of each word is upper case (except first word).
+
+
+
+ Private names: initial of each word is upper case (except first
+ word if not a class)
+
+
+
+ Underscores as word separators are only used when overriding
+ Tkinter methods of same name.
+
+
+
+ Indent is four spaces.
+
+
+
+ Continuation lines are indented by eight spaces, so that they
+ won't be confused with a following nested code block.
+ Continuation lines should be used when a statement, which would
+ normally be written on one line, is longer than 80 characters.
+ Examples are "if" statements which contain many conditions and
+ function calls with many arguments.
+
+
+
+
+ Surround = with spaces when used with keyword
+ parameters in function calls.
+
+
+
+
+ Multi-line function calls should have one keyword parameter per
+ line.
+
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/howtouse.html b/Pmw/Pmw_1_2/doc/howtouse.html
new file mode 100644
index 00000000..f7e43b92
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/howtouse.html
@@ -0,0 +1,719 @@
+
+
+
+
+
+ How to use Pmw megawidgets
+
+
+
+
+
How to use Pmw megawidgets
+
+
+
+
+
+
+
Introduction
+
+ This document briefly describes the features of the Pmw megawidget
+ toolkit and how to use the megawidgets. Using examples, it
+ describes those features common to all Pmw megawidgets. For a
+ description of individual Pmw megawidgets see the
+ reference manuals.
+ For complete information on general Pmw megawidget functionality see the
+ Pmw.MegaArchetype reference manual.
+ For a lot more example code, run any of the files in the
+ Pmw demos directory.
+
+
+
+
+ A simple example of a megawidget is a counter. This widget
+ contains an entry field and two small arrow buttons. Users may
+ enter a value directly into the entry field or they may use the
+ buttons to increment and decrement the value displayed without
+ having to use the keyboard. Having this and other megawidgets in
+ your toolbox allows you to choose the best graphical interface for
+ your application.
+
+
+
+
Getting started
+
+Initialisation of Pmw
+
+
+ To run the examples in the tutorial, make sure that the
+ Pmw lib directory is in sys.path. You
+ should be able to cut and paste the examples into an interactive
+ python session, or you can copy them to a file and run the file with
+ python.
+
+
+
+ The following two lines should be entered before any of the
+ examples. These import and initialise Pmw.
+ For more information on Pmw.initialise() see the
+ Pmw functions reference manual.
+
+
+
+
+
+
+import Pmw
+root = Pmw.initialise()
+
+
+
+
+
+ If necessary, you can have more control over how Tkinter and Pmw are
+ initialised by using this form of initialisation:
+
+
+ Now that you have the formalities out of the way, you can create and
+ pack a counter megawidget (see
+ Pmw.Counter reference manual) using
+ its default configuration like this:
+
+
+ Now enter a number and click on the arrow buttons to see the number
+ increment or decrement. The result looks something like this:
+
+
+
+
+
+
+
+
+ The above example creates the counter as a child of the root window.
+ If you want to create it as a child of another window (for example,
+ a Tkinter.Frame widget called 'frame'), add the parent as an
+ argument to the constructor:
+
+
+
+
+
+
+counter1a = Pmw.Counter(frame)
+
+
+
+
+
+
Methods
+
+ Once a megawidget has been created, you can call any of its other
+ methods in a similar way to Tk widgets. The following sets the value
+ of the counter and then increments it:
+
+
+
+
+
+counter1.setentry(41)
+counter1.increment()
+
+
+
+
+
+
Options
+
+ Like any widget, a megawidget may have options to allow it to be
+ configured for a particular use. Options allow the megawidget user
+ to modify the appearance and behaviour of the megawidget. The
+ counter megawidget has several such options. One of them,
+ datatype, specifies how the counter should count up
+ and down, such as, for example, by integers, reals, times or dates.
+ The default value is 'numeric', which means the
+ counter expects integers to be entered and will support
+ incrementing and decrementing by whole numbers.
+
+
+
+
+ Another option is
+ increment, which specifies how many units should be
+ added or subtracted when the counter is incremented or decremented.
+ Using these options, you can create a time counter, supporting the
+ format HH:MM:SS, and counting in minutes, like
+ this (note also the call to the setentry method to set
+ the contents of the entry field):
+
+
+ Many megawidget options can be modified using the
+ configure() method. For example, you can change the
+ value of the increment option to 10 minutes like
+ this:
+
+
+
+
+
+
+counter2.configure(increment = 60 * 10)
+
+
+
+
+Initialisation options
+
+
+ Some megawidget options can only be set when creating the megawidget.
+ These options can not be set by calling the configure()
+ method, but they can be queried in all the usual ways. For example,
+ the counter has an orient initialisation option
+ which specifies whether the arrow buttons should appear to the
+ left and right of the entry field ('horizontal')
+ or above and below ('vertical'). You can create a
+ numeric counter with arrow buttons above and below the entry
+ field like this:
+
+
+ You can query the value of megawidget options (initialisation or
+ not) in similar ways as for normal Tkinter widgets. For example,
+ the following code prints the values of some of the counter options.
+
+
+ When a Tk widget option is queried, its value is always
+ returned as a string, regardless of the type used when setting the
+ option. However, when a Pmw megawidget option is queried, a
+ reference to the object used when setting the option is returned.
+ In other words it is not always a string. For example, the type
+ returned by cget('increment') above was integer.
+
+
+
+
+
Components
+
+ Megawidgets are made up of other widgets, which we call
+ components. Each component is known by a logical name and
+ may be either a simple Tk widget, or may itself be a megawidget.
+ Pmw gives the megawidget user access to not only the functionality
+ supported directly by the megawidget through its options and methods,
+ but also to the components of the megawidget and their options and
+ methods. To access a component directly, use the
+ component() method. For example, to call method
+ doit of component comp
+ of megawidget mega:
+
+
+
+
+
+
+mega.component('comp').doit()
+
+
+
+
+Component options
+
+
+ There is a short-hand way to access the options of components, by
+ using the notation component_option. This allows, for
+ example, a counter megawidget to be configured with different
+ colored backgrounds for each of its arrow button components (these
+ components are called downarrow and
+ uparrow):
+
+
+ All megawidgets are enclosed in a containing widget which is created
+ automatically by the Pmw base classes. For normal megawidgets the
+ container is a Tkinter Frame widget. For megawidgets which are
+ toplevel windows, the container is a Tkinter Toplevel widget. The
+ containing widget is accessible as the hull
+ component.
+
+
+
+
+ To access options of the containing widget use the form
+ hull_option. For example to create a
+ counter megawidget with a wide sunken border around it:
+
+
+ Some megawidgets, such as Dialog and LabeledWidget, also have a
+ frame into which users can pack other widgets. This frame may be a
+ component but can also be accessed with the interior()
+ method. For the Pmw.MegaToplevel and Pmw.MegaWidget classes, the
+ interior widget is the same as the hull widget. For other
+ megawidgets, the hull is the outer, containing widget and the
+ interior is the empty frame which can be used to extend the
+ megawidget by including extra internal widgets.
+
+
+
+Sub components and aliases
+
+
+ Components may themselves be megawidgets and so their
+ (sub-)components can be referred to using the notation
+ component_sub-component. For example, the
+ entryfield component of the counter is a
+ Pmw.EntryField megawidget (which handles the input validation). In
+ turn, this has a Tkinter.Entry component named
+ entry. Therefore, you can change the background of
+ the counter's Tkinter.Entry widget with:
+
+
+ Each megawidget component is an instance of some python class. The
+ default class of each component is given in the reference manual.
+ By using the special pyclass component option, you
+ can specify a different python class to use when creating the
+ component. For example, to create a Pmw.Counter megawidget which
+ has a Tkinter.Button as its label, rather than the default
+ Tkinter.Label:
+
+
+ Since a Pmw megawidget is a normal python class, it both inherits
+ methods from its base classes and also may have other methods
+ defined for it in the usual way.
+ Pmw also supports a third way that a megawidget may gain methods -
+ by 'forwarding' methods to one or more of its subwidgets. This is
+ also known as 'delegating'.
+ For example, a Pmw.Counter megawidget delegates the methods related
+ to its Pmw.EntryField component, entryfield, to the
+ component. It does not have to explicitely define methods which
+ call the component methods.
+ This is why we can call counter2.setentry() - since
+ setentry() is a method of the Pmw.EntryField
+ component, it is available to the Pmw.Counter.
+
+
+
+ Methods already defined by a class or its base classes take
+ precedence over delegated methods. For example, Pmw.Counter
+ inherits a cget method from Pmw.MegaArchetype.
+ Therefore, this method is not delegated to the cget
+ method of Pmw.EntryField.
+
+
+
+
+
Extending Pmw megawidgets
+
+
+ There are several ways of extending Pmw megawidgets. Firstly, the
+ flexibility of the options and components allows the widget's
+ appearance and behaviour to be greatly modified. Secondly, widgets
+ of the user's choice can be added inside some megawidgets by using
+ the interior() method. The Pmw classes MegaToplevel, MegaWidget,
+ Dialog and LabeledWidget are particularly designed to be extended in
+ this way. For example, to create a dialog window containing a
+ counter:
+
+
+ A third way to extend megawidgets is to inherit from (or subclass)
+ them. See How to build Pmw
+ megawidgets for information on how to use inheritance to extend
+ a megawidget by adding new options. For simpler cases, where new
+ methods are to be added to an existing megawidget and/or the default
+ values for some options are to be changed, normal subclassing can be
+ used. For example, to create new classes based on a Pmw.Counter,
+ one with a new method getminutes() and one with a
+ default datatype of 'time' and a white entry background:
+
+
+ The following code is a small example of how to use Pmw megawidgets.
+ It is a complete program which displays three ways for the user to
+ enter a value - using an up-down counter, an entry field with
+ validation and a dropdown combobox.
+
+
+ The following also shows how to use Pmw megawidgets. It displays a
+ RadioSelect megawidget and an exit button packed into the root
+ window.
+
+
+
+
+
+
+import Tkinter
+import Pmw
+
+def callback(tag):
+ # This is called whenever the user clicks on a
+ # button in the RadioSelect widget.
+ print tag, 'was pressed.'
+
+# Initialise Tkinter and Pmw.
+root = Pmw.initialise(fontScheme = 'pmw1')
+root.title('Pmw RadioSelect demonstration')
+
+# Create and pack a RadioSelect widget.
+radio = Pmw.RadioSelect(
+ command = callback,
+ labelpos = 'w',
+ label_text = 'Food group:')
+radio.pack(padx = 20, pady = 20)
+
+# Add some buttons to the RadioSelect.
+for text in ('Fruit', 'Vegetables', 'Cereals', 'Legumes'):
+ radio.add(text)
+radio.invoke('Vegetables')
+
+# Create an exit button.
+exit = Tkinter.Button(text = 'Exit', command = root.destroy)
+exit.pack(pady = 20)
+
+# Let's go.
+root.mainloop()
+
+
+
+
+
+
+
+
+
+
Using the Tk option database
+
+ There are several ways to use the Tk option database to customise a
+ Pmw application. Firstly you can customise all the basic Tk widgets
+ in the usual way. For example, to set the background of all
+ Tkinter.Label widgets (whether a megawidget component or not):
+
+
+
+
+
+
+root.option_add('*Label.background', 'pink')
+
+
+
+
+
+ To set the background of all Pmw.EntryField label
+ components:
+
+
+ The above option settings affect basic Tk widgets and, since it is
+ built into the Tk widgets, this functionality is always available.
+ However, to be able to use the Tk option database to set the default
+ values for Pmw megawidget options, Pmw.initialise()
+ must be called with useTkOptionDb = 1. If this is not
+ done, Pmw does not query the Tk option database for megawidget
+ option defaults. This is the default behaviour because there is a
+ slight performance penalty for using the Tk option database.
+
+
+
+
+ Assuming useTkOptionDb has been set, the default
+ buttonbox position of all Pmw.Dialog megawidgets can be changed
+ with:
+
+
+
+
+
+
+root.option_add('*Dialog.buttonboxpos', 'e')
+
+
+
+
+
+ To set the label position of all Pmw.EntryField megawidgets, thus giving
+ them a label component by default:
+
+
+Pmw is a toolkit for building high-level compound widgets in Python
+using the Tkinter module.
+
+
+
+It consists of a set of base classes and a library of
+flexible and extensible megawidgets built on this foundation. These
+megawidgets include notebooks, comboboxes, selection widgets, paned
+widgets, scrolled widgets, dialog windows, etc.
+
+
+
+
+ Pmw project home page
+ on SourceForge - contains CVS source repository, bug tracking,
+ release distributions, mailing list, etc
+
+
+ Pmw-general
+ mailing list - subscribe to this list to get announcements of
+ Pmw releases and general discussion on Pmw
+
+
+ A User's Guide
+ to Pmw.Blt
+ - an excellent tutorial and reference covering the Pmw interface
+ to the powerful Blt graph widget, written by Bjørn Ove Thue
+ and Hans Petter Langtangen. You can also download the full
+ HTML document for local viewing.
+
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/porting.html b/Pmw/Pmw_1_2/doc/porting.html
new file mode 100644
index 00000000..64a7cb5d
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/porting.html
@@ -0,0 +1,325 @@
+
+
+
+
+
+ Porting between different versions of Pmw
+
+
+
+
+
Porting between different versions of Pmw
+
+
+ This document contains a brief guide to porting existing code
+ between different versions of Pmw. It includes significant
+ functionality changes but does not include bug fixes or compatible
+ enhancements. For details of all changes, see
+ Changes to Pmw versions.
+
+
Porting from 0.8.5 to 1.0, 1.1 and 1.2
+
+
Bug fix, documention and new features only. No
+ backwards-incompatible changes.
+
+
+
Porting from 0.8.4 to 0.8.5
+
+
Bug fix release only. No interface changes.
+
+
+
Porting from 0.8.3 to 0.8.4
+
+
Change the setnaturalpagesize() method of Pmw.NoteBook to
+ setnaturalsize() (to be consistent with Pmw.PanedWidget).
+
+
+
Change Pmw.excludefrombusycursor() to Pmw.setbusycursorattributes().
+ Replace busyCursorName option of Pmw.initialise() with
+ cursorName attribute of Pmw.setbusycursorattributes().
+
+
+
Several rarely used key bindings for Pmw.ScrolledListBox were
+ removed, changing the behaviour of the megawidget.
+
+
+
Porting from 0.8.1 to 0.8.3
+
+
The megawidgets Pmw.NoteBookR and Pmw.NoteBookS have been
+ replaced by a new Pmw.NoteBook. The interfaces are not
+ compatible, so see the Pmw.NoteBook reference manual for
+ details.
+
+
+
Change the get() method of Pmw.OptionMenu to getcurselection()
+ and the remove() method of Pmw.PanedWidget to delete().
+
+
+
If you use 'end', 'default' or None in calls to the
+ index() method of several megawidgets, change these to
+ Pmw.END, Pmw.DEFAULT and Pmw.SELECT, respectively.
+
+
+
The exclude argument has been removed from Pmw.showbusycursor().
+ Use Pmw.excludefrombusycursor() instead.
+
+
+
The names of some of the positional arguments in the following
+ methods have changed: MegaArchetype.createcomponent(),
+ ButtonBox.insert(), ButtonBox.add(), MenuBar.addcascademenu(),
+ MenuBar.addmenuitem() and RadioSelect.add().
+
+
+
The Pmw.maxfontwidth() function has been removed. Use the
+ font_measure() Tkinter method, or if that has not yet been
+ implemented:
The Pmw.fontexists() function has been removed. This is
+ because, since Tk8.0, all fonts exist, so it no longer has
+ any meaning.
+
+
+
Porting from 0.8 to 0.8.1
+
+
The Blt.Graph now supports blt2.4i which is not backwards
+ compatible with blt2.1.
+
+
+
Porting from 0.7 to 0.8
+
+
The format argument of Pmw.datestringtojdn() now defaults to
+ 'ymd'. If you want to display dates with year, month and day
+ in a different order, add a format option to
+ Pmw.datestringtojdn() or to the datatype option of Pmw.Counter
+ or the validate option of Pmw.EntryField.
+
+
+
The justify() method from Pmw.ScrolledListBox has been removed.
+ Use the xview() or yview() methods instead.
+
+
+
Replace the getFrame() method of Pmw.ScrolledFrame with the
+ interior() method.
+
+
+
Replace the ringpadx and ringpady options of Pmw.Group by
+ padding the megawidget itself or by padding the children of the
+ megawidget.
+
+
+
Replace the canvasbind() and canvasunbind() methods of
+ Pmw.Balloon with tagbind() and tagunbind().
+
+
+
The return value of Pmw.EntryField command callback is now
+ ignored. Previously, if the callback destroyed the megawidget,
+ it was required to return the string 'break', to work around a
+ problem in the event handling mechanism in Tkinter. With python
+ 1.5.2, Tkinter has been fixed. Therefore, user-supplied
+ callback functions should use Pmw.hulldestroyed to check if the
+ megawidget has been destroyed before performing any operations
+ on it.
+
+
+
If you require the 'pmw1' fontScheme when running under
+ Microsoft Windows and Macintosh, you will need to set the Tk
+ font options manually.
+
+
+
Porting from 0.6 to 0.7
+
+
Replace the maxwidth option of Pmw.EntryField with the 'max'
+ field of the validate option.
+
+
+
To specify that there should be no validation performed for a
+ Pmw.EntryField, the validate option must be None, not '' as
+ before.
+
+
+
The date and time values of the Pmw.EntryField validate option
+ (such as 'date_dmy' and 'time24', etc) are no longer supported.
+ Instead use a dictionary as the value of the validate option
+ with 'date' or 'time' in the 'validator' field. Include
+ other fields in the dictionary to further specify the
+ validation.
+
+
+
Pmw.Counter no longer supports the old date and time values for
+ the datatype option. Use a dictionary with a 'counter'
+ field of 'date' or 'time' and other fields to further
+ specify the counting.
+
+
+
Pmw.Counter no longer supports the min and max options. Use
+ the Pmw.EntryField validate option instead.
+
+
+
The bbox method of Pmw.ScrolledListBox now refers to the bbox
+ method of the listbox component, not the hull component.
+
+
+
By default, Pmw.MenuBar now automatically adds hotkeys to menus
+ and menu items for keyboard traversal. To turn this off, use the
+ hotkeys = 0 option.
+
+
+
The createcomponent() method now disallows the creation of
+ component names containing an underscore. If any component
+ names contain an underscore, rename them.
+
+
+
Porting from 0.5 to 0.6
+
+
To port applications using Pmw version 0.5 to version 0.6, make
+ sure you are using python1.5. Then, simply change any lines in
+ your application like this:
+
+
from PmwLazy import Pmw
+
+
to this:
+
+
import Pmw
+
+
Also, if you have added the lib directory of a specific version
+ of Pmw to sys.path or PYTHONPATH, this can be removed, as long
+ as Pmw can now be found from the default path, such as in the
+ python site-packages directory.
+
+
Porting from 0.2 to 0.4
+
+
To get Pmw.0.2 default fonts (helvetica with bold italic menus
+ and italic scales) initialise with:
+
Pmw.initialise(fontScheme = 'pmw1')
+
+
If no fontScheme is given, the standard Tk default fonts are used.
+
+
+
+
Remove all calls to setdefaultresources(), usual(), keep(),
+ renameoptions(), ignore() and defineoptiontypes().
+
+
+
Move call to defineoptions() to before call to base class
+ constructor, create optiondefs tuple from self.defineoptions
+ arguments, then call defineoptions().
+
+
+
Remove resource class and name from optiondefs.
+
+
+
The last element in the optiondefs tuple (callback function)
+ must be given (may be None).
Use createcomponent() to create components - this replaces the
+ calls to the component widget constructor and to
+ registercomponent().
+
+
+
Do not inherit from Pmw.LabeledWidget. Instead, replace with
+ Pmw.MegaWidget with labelpos and labelmargin options and a call
+ to self.createlabel(). If calling createlabel(), must replace
+ pack() with grid().
+
+
+
When calling a megawidget constructor, include subcomponent name when
+ setting subcomponent options (eg labeltext -> label_text)
+
+
+
The items option of ScrolledListBox is an initialisation option
+ only - use setlist() method after initialisation.
+
+
+
The autorelief option for Counter, EntryField, ScrolledText,
+ TextDialog has been removed.
+
+
+
ScrolledListBox.getcurselection() always returns a tuple of strings,
+ possibly of zero length.
+
+
+
Counter increment is always initialised to 1.
+
+
+
The 'time' Counter datatype option has been replaced by
+ 'timeN' and 'time24'.
+
+
+
The 'time' EntryField validate option has been replaced by
+ 'timeN' and 'time24'.
+
+
+
Replace call to initialise() with initialiseoptions(), removing
+ "kw" arg. This should always be the last line in a megawidget
+ constructor.
+
+
+
Replace hide() with withdraw().
+
+
+
Now need iconpos option for MessageDialogs with icon_bitmap option set.
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/scale1.gif b/Pmw/Pmw_1_2/doc/scale1.gif
new file mode 100644
index 00000000..5cf5d60b
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/scale1.gif differ
diff --git a/Pmw/Pmw_1_2/doc/scale2.gif b/Pmw/Pmw_1_2/doc/scale2.gif
new file mode 100644
index 00000000..5682715e
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/scale2.gif differ
diff --git a/Pmw/Pmw_1_2/doc/starting.html b/Pmw/Pmw_1_2/doc/starting.html
new file mode 100644
index 00000000..be447450
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/starting.html
@@ -0,0 +1,382 @@
+
+
+
+
+
+ Getting started with Pmw
+
+
+
+
+
Getting started with Pmw
+
+
+
+
+
+
+
Introduction
+
+This document describes how to fetch and install Pmw, and how to run
+the demonstrations and tests.
+
+
+
+
+
Requirements
+
+Pmw.1.2 requires the _tkinter and Tkinter modules. It works
+with python versions 1.5.2 and greater (tested up to 2.2.1) and Tk
+versions 8.0 and greater (tested up to 8.3.2).
+
+
+
+
+If the BLT extension to Tk is present, Pmw will use the BLT busy
+command during modal dialogs to display a clock cursor. Also, the
+Pmw.Blt interface to the BLT busy, graph, stripchart, tabset and
+vector commands will be available. BLT versions 2.4i and greater are
+supported (tested up to 2.4u). You can find BLT at
+http://www.tcltk.com/blt/.
+
+
+
+
+
Distribution and installation
+
+Releases of the Pmw distribution are available via http from
+http://download.sourceforge.net/pmw/. This release is available
+as
+Pmw.1.2.tar.gz, released on 5 August 2003.
+This is a compressed tar file. Under Linux, Unix, etc, you will need to
+unpack it using tar and you may also need to use
+gzip or gunzip to uncompress it.
+Under Microsoft Windows, you will need a program such as WinZip (http://www.winzip.com) that can
+unpack the gzipped tar files. You may need to change the suffix of
+the file to .tgz for WinZip to recognise it.
+
+
+
+
+
+This will unpack into a directory named Pmw. You now need to put this
+directory somewhere python can find it, preferably in one of the
+standard places, such as in the site-packages directory
+(eg: /usr/lib/python2.2/site-packages/Pmw) or the
+sys.prefix directory (eg: C:\Program
+Files\Python\Pmw or /usr/lib/python2.2).
+
+
+
+
+
+For example, under Unix, assuming you have placed the tar file in the
+/tmp directory, you can simply run the following
+commands:
+
+
+
+If you do not have write permission for these standard directories,
+place the Pmw
+directory somewhere on your PYTHONPATH or
+sys.path. If this is not possible, place the Pmw
+directory somewhere else and add the parent directory to your
+PYTHONPATH or sys.path.
+
+
+
+
+
+If you have previously installed Pmw version 0.6 or later, then the
+new version can share the same Pmw directory as the
+previous versions. You will need to perform the tar
+extraction in the directory containing (that is, the parent directory
+of) the existing Pmw directory. By default, your
+applications will use the most recent version of Pmw. If required,
+the function Pmw.setversion() can be used to specify a
+version to be used. See the reference manual for details. If you are
+no longer using the older versions, you can safely remove the
+corresponding subdirectories from the Pmw directory.
+
+
+
+
+
+If you need assistance in installing BLT under Unix, please contact me
+(gregm@iname.com) and I
+will try to help. For other operating systems, such as Microsoft or
+Macintosh, you should try asking the python newsgroup. If anyone can
+give me a description of how to install BLT under other operating
+systems please contribute it and I will place it here.
+
+
+
+
+
Documentation
+
+The doc directory for each Pmw version contains all the
+documentation for that version of Pmw. See the local home page for a complete list of documents. The
+files in this directory are also available from the official Pmw home page.
+
+
+
+
+An excellent tutorial and reference covering the Pmw interface to the
+powerful Blt graph widget, "A User's Guide to
+Pmw.Blt" written by Bjørn Ove Thue and Hans Petter Langtangen, is
+available. You can also download the full
+HTML document for local viewing.
+
+
+
+
Demonstrations and tests
+
+ A good way to get an overview of the functionality provided by Pmw
+ is to run the demonstrations and tests and look at the demonstration
+ code. To view a comprehensive demonstration of many of the features
+ of Pmw run the All.py script, which can be found in the
+ demos subdirectory of each version of Pmw.
+
+
+
+
+ You do not have to install Pmw to run the demonstrations and tests,
+ simply change into the appropriate directory and run the file
+ All.py. See Demonstrations and tests for more
+ information about running the demonstrations and tests and how to
+ create your own.
+
+
+
+
+Note that there are some bugs in later versions of BLT (at least 2.4t
+and 2.4u) which cause some tests of Pmw.Blt.Graph to crash with
+python2.0 under Linux. These tests have been commented out (until BLT
+is fixed).
+
+
+
+
Contributions welcome
+
+
+If you create some whiz-bang megawidgets and would like to contribute
+them to Pmw, they will be most welcome. You should be able to get
+some idea of the coding style used in Pmw code by reading How to build Pmw megawidgets and by looking
+at the Pmw library code itself in the lib directory of
+each Pmw version.
+
+
+
+
+If you would like to contribute a megawidget, it would be preferable if it
+also came with a simple demonstration and a test script. See Demonstrations and tests for information
+about how to create new demonstrations and tests.
+
+
+
+Each megawidget should also have a reference manual describing its
+options, components and methods.
+
+
+
+
+
+
Generating the documentation
+
+
+The released reference manuals are
+automatically generated by merging specially marked-up text with the
+output from megawidget query methods, such as
+components(), options() and
+componentaliases(), and various other introspective
+devices. If you are interested to see how the documentation is generated,
+you can fetch the marked-up text and the python script to convert the
+text to html from
+
+http://download.sourceforge.net/pmw/Pmw.1.2.docsrc.tar.gz
+. Download this
+file into the Pmw/Pmw_1_2 directory of the Pmw source
+tree. Unzip and untar the file. This will create a
+docsrc sub-directory of Pmw/Pmw_1_2. If
+you want to keep the documentation which came with the Pmw
+distribution, rename the old doc directory. Then change
+directory to docsrc and run createmanuals.py.
+After printing lots of warnings about documentation that has not been
+written yet, this will create a new doc directory
+containing all the html documentation.
+
+
+
+Here is an example set of commands to unpack the documentation source
+and regenerate the documentation, assuming you have downloaded the
+source in the Pmw/Pmw_1_2 directory:
+
+If running under Unix, you will need to run the
+createmanuals.py script with a valid DISPLAY environment
+variable, since it creates each megawidget and then queries it for its
+options, components, etc. This is because Tk (and hence Tkinter)
+requires a connection to an X server to run.
+
+
+
+
+
Future plans and bugs
+
+
+The todo list contains a long list of of
+suggestions, bugs and enhancements for Pmw. If you are interested in
+doing any of these, please let the maintainer
+(gregm@iname.com) know.
+Some of the items in the todo list may be considered bugs. There are
+also some other problems due to idiosyncrasies in the implementation
+of Tk.
+
+
+
+
+
Licence
+
+
+The official Pmw licence (see copyright)
+basically lets you do anything with Pmw as long as you don't hurt anyone.
+There is also another licence, the "Postcard Licence":
+
+
+"I'd like to get a postcard from you! I'm interested in who is using
+Pmw, where you live and where in the world Pmw is doing it's job"
+
+
+Please send me an e-mail to
+gregm@iname.com
+to get my postal address.
+
+
+
+
Acknowledgements
+
+
+The initial ideas for Pmw were blatantly stolen from the itcl
+extensions
+[incr Tk]
+by Michael McLennan and
+[incr Widgets]
+by Mark Ulferts. Several of the megawidgets are direct translations
+from the itcl to python.
+
+
+
+The base classes and most megawidgets were written by Greg McFarlane
+and Peter Munnings. Contributed megawidgets include: Pmw.TimeCounter
+by Joe VanAndel, Pmw.Group and an early version of Pmw.NoteBook by Case Roole,
+Pmw.ScrolledCanvas, Pmw.ScrolledFrame and another early version of
+Pmw.NoteBook by Joe Saltiel
+and Pmw.OptionMenu by Roman Sulzhyk. A big thank you to the following
+people for their bug reports, fixes, enhancements and suggestions:
+
+David Ascher,
+Robin Becker,
+Siggy Brentrup,
+Mark Colclough,
+Jerome Gay,
+Clemens Hintze,
+Rob Hooft
+Jack Jansen,
+Jonathan Kelly,
+Magnus Kessler,
+Matthias Klose,
+Andreas Kostyrka,
+Fredrik Lundh,
+Magnus Lycka,
+Graham Matthews,
+Dieter Maurer,
+Michael McLay,
+Daniel Michelson,
+Georg Mischler,
+Rob Pearson,
+Case Roole,
+Joe Saltiel,
+Roman Sulzhyk,
+Shen Wang,
+Chris Wright,
+ and
+Guido van Rossum.
+
+Special thanks to Case Roole and Michael McLay for help with getting
+Pmw to work with python packages and many other nifty features.
+
+My deepest apologies if I have forgotten anyone. Please let me know.
+
+
+
+
+The Pmw home page and project site is made available courtesy of
+SourceForge.
+
+
+
+
+The current maintainer is Greg McFarlane. I monitor the Pmw
+discussion and announcement mailing list so please send any
+problems, comments, suggestions or enhancements to the list. You may
+also contact me directly at gregm@iname.com.
+
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/todo.html b/Pmw/Pmw_1_2/doc/todo.html
new file mode 100644
index 00000000..9ca6889f
--- /dev/null
+++ b/Pmw/Pmw_1_2/doc/todo.html
@@ -0,0 +1,1111 @@
+
+
+
+
+
+ Pmw todo list
+
+
+
+
+
Pmw todo list
+
+
+This is a long list of suggestions and enhancements for Pmw. If
+you are interested in doing any of these, please let the Pmw maintainer
+(gregm@iname.com) know.
+
+
New Pmw megawidgets
+
Multicolumn listbox.
+
Useful features - smooth scrolling, embedded images, different
+ fonts and colours, text correctly masked when it is longer than
+ its column width, interactive resizing of columns.
+
+
Probably should be implemented as canvas widget rather than by
+ using multiple frames or multiple listboxes. There would be a
+ lot of work needed to position all the elements - you can't just
+ pack or grid them.
+
+
+
+
File dialog.
+
+
+
Main window class (App class), with menu bar, information line
+ with status boxes and an about box. (See iwidgets' mainwindow
+ class for example.) This should handle creation of multiple main
+ windows, recycling of unused main windows and should exit if
+ last open main window is closed.
+
+
+
Searchable text megawidget.
+
+
+
Tree browser.
+
+
+
Check out Doug Hellmann's contributed megawidgets at
+ <http://www.mindspring.com/~doughellmann/Projects/PmwContribD> or
+ <http://members.home.net/doughellmann/PmwContribD/>
+ and integrate into Pmw.
+
+
+
+
Changes to current megawidgets
+
MegaToplevel
+
Modify activate() geometry argument to allow window positioning
+ relative to the pointer, another window or the screen and
+ allow the centering of the window relative to the
+ positioning point or by a specified offset. Also add the
+ ability to position the window so that the mouse is over a
+ particular widget in the toplevel.
+
Should handle all combinations of
+
when (always/first)
+ where (center/geometry/mouse)
+ parent (screen/window)
+
+ and None (don't position)
+
+
+
Check Tix4.1.0/library/DialogS.tcl center method for how to
+ center over another window
+
+
Check iwidget's shell.itk for code to center widget over
+ screen or another widget.
+
+
See Pmw.Balloon code for how to position over pointer.
+
+
Tcl code to center over another (parent) window:
+
# center client relative to master (default xoff, yoff = -1)
+ set geomaster [split [wm geometry $master] "x+"]
+ set geoclient [split [wm geometry $client] "x+"]
+
+ if {$xoff == -1} {
+ set xoff [expr (
+ ([lindex $geomaster 0] - [lindex $geoclient 0]) / 2)]
+ }
+ set newxpos [expr [lindex $geomaster 2] + $xoff]
+
+ if {$yoff == -1} {
+ set yoff [expr (
+ ([lindex $geomaster 1] - [lindex $geoclient 1]) / 2)]
+ }
+ set newypos [expr [lindex $geomaster 3] + $yoff]
+
+ wm geometry $client +$newxpos+$newypos
+
+
+
More tcl code to center dialog over another (parent) window:
+
(args: parent dlg)
+ # First, display the dialog offscreen to get dimensions.
+ set screenW [winfo screenwidth $parent]
+ set screenH [winfo screenheight $parent]
+ set w [expr $screenW + 1]
+ wm geometry $dlg +$w+0
+ update
+
+ # Get relative center of parent.
+ set w [winfo width $parent]
+ set h [winfo height $parent]
+ set w [expr $w/2]
+ set h [expr $h/2]
+
+ # Get and add screen offset of parent.
+ set w [expr $w + [winfo rootx $parent]]
+ set h [expr $h + [winfo rooty $parent]]
+
+ # Get dimensions of dialog.
+ set dlgW [winfo width $dlg]
+ set dlgH [winfo height $dlg]
+
+ # Make adjustments for actual dimensions of dialog.
+ set w [expr $w - $dlgW / 2]
+ set h [expr $h - $dlgH / 2]
+
+ # Let's keep the entire dialog onscreen at all times.
+ # Center in screen if things are awry.
+ set recenter 0
+ if { $w < 0 } { set recenter 1 }
+ if { $h < 0 } { set recenter 1 }
+ if { [expr $w + $dlgW] > $screenW } { set recenter 1 }
+ if { [expr $h + $dlgH] > $screenH } { set recenter 1 }
+ if { $recenter } {
+ set w [expr ($screenW -$dlgW) / 2]
+ set h [expr ($screenH - $dlgH) / 2]
+ }
+
+ wm geometry $dlg +$w+$h
+
+
+
+
+
Add geometry argument to show() (same as activate() above).
+
+
+
+
Dialog
+
Add label (header?) to Dialog class. May not be necessary, or
+ too complicated.
+
+
+
+
ButtonBox
+
When a horizontal ButtonBox is stretched, the left button
+ stays anchored to the left edge and there is too much space
+ between the last button and the right edge.
+
+
+
Add an option to either evenly space the buttons across the
+ button box, or to keep them together and justify them to the
+ left, right or center. Check that deleting buttons works
+ correctly.
+
+
+
+
ComboBox
+
Remove arrowrelief option from ComboBox and do what counter
+ does: gets value of arrow's relief just before sinking it,
+ then restores it later.
+
+
+
Change bindings: remove all bindings from arrow key and remove
+ arrow key from <tab> focus sequence; only implement these
+ bindings on the entry widget:
+
Up popup dropdown list, scroll up if already displayed
+ Down popup dropdown list, scroll down if already displayed
+ Esc popdown dropdown list, return entry to previous value
+ Enter popdown dropdown list, execute current selection
+
+
Remove bindings from listbox and scrollbar(s), so that all
+ bindings are via the entry widget?
+
+
+
+
When entering keys when list is displayed, scroll list to
+ first entry beginning with entered keys. If no match,
+ scroll list to top.
+
+
+
Remove many of the arrow bindings from Pmw.ComboBox - there
+ are just too many key bindings on the arrow button. There
+ is no need for it to respond to keys such as the up/down
+ keys when the adjacent Entry widget already does so. I
+ propose to remove all Pmw.ComboBox arrow button key bindings
+ except for <space>, which can be used to bring up the
+ dropdown list. The Entry widget behaviour would remain
+ unchanged: when it has focus, you can use the up/down keys
+ to go to the next/previous entries and then use <Return> to
+ invoke the selection command.
+
Alternatively, make the bindings the same as the MS-Windows
+ combobox. (Use the url entry field in Navigator or IE as an
+ example of MS-Windows behaviour). These have been reported
+ to be:
+
All mouse actions are exclusively triggered by the left
+ button.
+
+
+
Right button displays "Direkthilfe" on my german system
+ ("Direct Help"). This is a floating button, that
+ triggers display of a tool tip like the |?| button that
+ appears next to the |x| at the right end of the title
+ bar of some native windows dialogs.
+
+
+
The arrow is very slim (acutally flat: width/height is
+ about 2/1)
+
+
+
Entry and popup have the same color ("window color")
+
+
+
The popup has a 1 pixel dark border, no spacing between
+ popup and scrollbar.
+
+
+
If the box has the focus, the full entry is displayed in
+ "selected" style.
+
+
+
If the box has the focus, up and left keys rotate items
+ up, down and right keys rotate items down, all with
+ immediate effect.
+
+
+
If the box has the focus, keys a-z (not case sensitive)
+ rotate through the items with same first character, with
+ immediate effect.
+
+
+
No separate focus for the arrowbutton
+
+
+
Discussing how the combobox behaves with arrow keys when
+ it has the focus: "The concept is almost identical to
+ what you already have, just gives more visual feedback.
+ In your current implementation you allow to rotate
+ through the values with the up and down arrow keys,
+ showing the strings in the entryfield, and accepting the
+ values when the user presses the spacebar (hmmm, how can
+ I exit this without moving back to the original value
+ manually?). On Windows, the choice is not shown in the
+ entryfield, but the popup opens when you press the up or
+ down arrow keys, as if you clicked on the arrowbutton,
+ and you then navigate the values in the listbox. This
+ avoids the display of not finally selected values in the
+ entryfield and is a lot more obvious and less confusing.
+ The current behaviour certainly confused me, which is
+ why I first proposed the changes to the moveup/down
+ methods." (Georg Mischler)
+
+
+
+
Also, check bindings on other megawidgets for consistency.
+
+
+
+
Modify Pmw.ComboBox so that the width of the entry widget is
+ forced to be the same as the width of the dropdown listbox.
+ If the "width" option to the standard listbox is 0, Tk sets
+ the requested width of the listbox to be just large enough
+ to hold the widest element in the listbox. Using this
+ option, I can see that listbox.winfo_reqwidth() is changing
+ as I insert items into an unmapped listbox. The question
+ is, how do I get notified of these events so that I can set
+ the width of the entry?
+
The problem is that the listbox is in another toplevel which
+ has not yet been displayed, so I can't bind to <Configure>
+ to determine its width.
+
+
One suggestion is to override the insert and delete methods
+ of the Listbox class. The problem with this is what if the
+ font changed, or the borderwidth, etc? You would need to
+ override and check many more methods.
+
+
+
+
Add ability to tearoff dropdown list (suggested by Dean N.
+ Williams).
+
+
+
Should be able to disable/enable arrow button.
+
+
+
+
Counter
+
Add option for different increment/decrement behaviour. For
+ example, assuming increment is 1:
+
Current behaviour - move to the next multiple of the
+ increment, eg: 1.0 -> 2.0, 1.234 -> 2.0
+
+
+
Add or subtract the increment to whatever is displayed,
+ eg: 1.0 -> 2.0, 1.234 -> 2.234
+
+
+
Move to the next multiple of the increment, offset by some value.
+ eg: (if offset is 0.5) 0.5 -> 1.5, 1.234 -> 1.5, 1.678 -> 2.5
+
+
+
+
+
Add wrap option (to wrap around at limits) (then don't need
+ time24 arg to 'time' datatype).
+
+
+
Add a state option to disable Counter.
+
+
+
Add option to Counter to allow the buttons to be on the same
+ side, one on top of the other, like Tix, Itcl, Motif,
+ Windows 95, etc. There should probably also be an option to
+ lay the current large buttons on the same side of the entry
+ field, next to each other.
+
+
+
Redo TimeCounter using vertical Counter, add limitcommand
+ option to Counter to allow overflow from seconds to minutes
+ to hours
Potential construction speed up if Canvas arrows are replaced
+ by Label with Bitmap or BitmapImage. The hard part would be
+ to make the bitmap change size depending on size of Label.
+
+
+
Pmw.drawarrow should draw arrows which look like Tk cascade
+ menu arrows.
+
+
+
+
EntryField
+
Can it be modified to change all entered characters to upper
+ or lower case automatically? Or first-upper or
+ first-of-each-word-upper?
+
+
+
If the validity of the currently displayed text is ERROR,
+ allow any changes, even those which result in invalid text.
+ This is useful when invalid data has been given to the
+ value option and the user is trying to correct it.
+
+
+
+
LabeledWidget
+
Add tix-style border.
+
+
+
+
MenuBar
+
Maybe Pmw.MenuBar should also have (optional) balloon help
+ for menu items as well as menu buttons. I am not sure
+ whether users would find this useful.
+
+
+
The status help hints do not appear when using F10/arrow
+ keys.
+
+
+
Look at the Tk8.0 menu demo and check the help bindings for
+ ideas, in particular, how can you get help when using
+ keyboard bindings.
+
+
+
Check the new menu features in Tk8.0 for creating "native"
+ menu bars and the special ".help" menu.
+
+
+
Add index() method.
+
+
+
Add a 'position' option to addmenu and deletemenu methods.
+ This option should accept an index number, a menuName or
+ Pmw.END.
+
+
+
Look at itcl menubar for ideas.
+
+
+
+
Balloon
+
Positioning of the balloon with respect to the target
+ widget or canvas item: There are a number of ways that
+ Pmw.Balloon could be improved. For example, currently the
+ the top left corner of the balloon is positioned relative to
+ the bottom left corner of the target, offset by the
+ [xy]offset options. These options apply to all targets -
+ they can not be set differently for different targets.
+
To make it more configurable, the user should be able to
+ specify, for each target:
+
the base position in the target relative to which the
+ balloon should be placed (n, s, e, w, nw, sw, ne, se, c)
+ (Currently sw)
+
+
+
the x and y offsets (Default (20, 1))
+
+
+
the position in the balloon that should be placed at the
+ offset position (n, s, e, w, nw, sw, ne, se, c)
+ (Currently nw)
+
Note, if this is anything other than nw,
+ update_idletasks() will need to be called to get the
+ size of the balloon before it is positioned - there is a
+ possibility that this may cause weird ugly flashing.
+
+
+
+
whether either the base x or y position should be taken
+ relative to the current mouse position rather than as
+ one of the corners of the target. This would be useful
+ for large targets, such as text widgets, or strange
+ shaped canvas items. This could be specified using
+ special base positions, such as (nm, sm, em, wm). For
+ example, for 'sm', the x base position is the mouse x
+ position and y base position is the bottom (south) edge
+ of the target.
+
+
+
+
The user should be able to specify global defaults for all
+ of these, as well as be able to override them for each
+ target. The Pmw.Balloon options and their defaults could
+ be:
+
basepoint sw # Position on target.
+ anchor nw # Position on the balloon
+ xoffset 20 # x distance between basepoint and anchor
+ yoffset 1 # y distance between basepoint and anchor
+
+
+
To be able to override these, the bind() and tagbind()
+ methods would have to accept these as additional arguments.
+ Each would default to None, in which case the default values
+ at the time the balloon is deiconified would be used.
+
+
I'm not sure about how to handle the case when the balloon
+ is configured to come up under the mouse. When this happens
+ the balloon flashes on and off continuously. This can
+ happen now if you set the yoffset to a negative number.
+ Should the balloon widget detect this and do something about
+ it?
+
+
+
+
Add showballoon(x, y, text) method to Balloon and use in
+ balloon help for a listbox:
+
On 3 Dec, Michael Lackhoff wrote:
+
+
And another question:
+ Is it possible to create a balloon-help for the entries
+ in the listbox? Not all the information is in the
+ listbox and it would be nice if a balloon help could
+ give addtional information.
+
+
Rather than popup a balloon help window as the mouse moves
+ over items in the listbox, I think it would be better if it
+ pops up after you clicked on an item (or a short time
+ afterwards). Pmw.Balloon displays the balloon help a short
+ time after the mouse enters a widget, so is not directly
+ usable in this case. However, a method could be added to
+ Pmw.Balloon to request it to popup the balloon at a
+ particular x,y position. This method could be called from
+ the listbox_focus method above. Something like:
text = self.indexlist.getcurselection()
+ # expand text to whatever you want:
+ text = 'This is ' + text
+ self.balloon.showballoon(x, y, text)
+
+
+
The Pmw.Balloon showballoon() method would have to set a
+ timer which sometime later calls another method which
+ displays the text. You would also need to bind
+ <ButtonRelease-1> to a hideballoon() method which withdraws
+ the popup.
+
+
+
+
The balloon can be displayed off-screen if the window is
+ near the edge of the screen. Add a fix so that the balloon
+ always stays on the screen (but does not popup under the
+ mouse, otherwise it will immediately pop down).
+
+
+
Add a fix so that the balloon does not disappear if the
+ mouse enters it. Could do this by setting a short timer on
+ the Leave event before withdrawing the balloon and if there
+ is an Enter event on the balloon itself, do not withdraw it.
+
+
+
For tagged items in text widgets, the balloon is placed
+ relative to the character in the tagged item closest to the
+ mouse. This is not consistent: in the other cases
+ (including canvas), the balloon is placed relative to the
+ bottom left corner of the widget or canvas item. This
+ should also be the case for text items.
+
+
+
Is the new (in Tk8) "<<MenuSelect>>" event useful for
+ balloon and/or status help.
+
+
+
+
MessageBar
+
Finish logmessage functionality.
+
+
+
Add colours and fonts to MessageBar message types. For
+ example, systemerror message types could have bold font on a
+ red background.
+
+
+
Add message logging history view (like the ddd debugger).
+
+
+
+
NoteBook
+
Notebook should recalculate layout if the requested size of a tab
+ changes (eg font size, text, etc).
+
+
+
The tabpos option should accept s, e and w as well as n.
+
+
+
Possible new options (borrowed from iwidgets):
+
equaltabs
+
If set to true, causes horizontal tabs to be equal in
+ in width and vertical tabs to equal in height.
+
+
Specifies whether to force tabs to be equal sized or
+ not. A value of true means constrain tabs to be equal
+ sized. A value of false allows each tab to size based
+ on the text label size. The value may have any of the
+ forms accepted by the Tcl_GetBoolean, such as true,
+ false, 0, 1, yes, or no.
+
+
For horizontally positioned tabs (tabpos is either s or
+ n), true forces all tabs to be equal width (the width
+ being equal to the longest label plus any padX speci-
+ fied). Horizontal tabs are always equal in height.
+
+
For vertically positioned tabs (tabpos is either w or
+ e), true forces all tabs to be equal height (the height
+ being equal to the height of the label with the largest
+ font). Vertically oriented tabs are always equal in
+ width.
+
+
Could have a special value which sets equal sized and
+ also forces tabs to completely fill notebook width
+ (apparently like
+ Windows).
+
+
+
+
tabgap
+
Specifies the amount of pixel space to place between
+ each tab. Value may be any pixel offset value. In addi-
+ tion, a special keyword overlap can be used as the
+ value to achieve a standard overlap of tabs. This value
+ may have any of the forms acceptable to Tk_GetPixels.
+
+
+
+
raiseselect
+
Sets whether to raise selected tabs slightly (2 pixels).
+
+
Specifes whether to slightly raise the selected tab
+ from the rest of the tabs. The selected tab is drawn 2
+ pixels closer to the outside of the tabnotebook than
+ the unselected tabs. A value of true says to raise
+ selected tabs, a value of false turns this feature off.
+ The default is false. The value may have any of the
+ forms accepted by the Tcl_GetBoolean, such as true,
+ false, 0, 1, yes, or no.
+
+
+
+
bevelamount
+
Specifies pixel size of tab corners. 0 means no corners.
+
+
+
+
+
+
There should be a way to temporarily hide a page, without
+ deleting it (like pack_forget). (Suggested by Michel Sanner)
+
+
+
+
OptionMenu
+
Should accept focus and obey up and down arrow keys.
+
+
+
+
PanedWidget
+
Add index() method
+
+
+
Modify all methods so that they accept Pmw.END as a pane
+ identifier as well as an index or a name.
+
+
+
Check iwidgets pane and panedwindow classes.
+
+
+
+
RadioSelect
+
Add insert() and delete() methods.
+
+
+
The index method should have forInsert argument.
+
+
+
Add Pmw.SELECT to index() method. For single selectmode
+ this returns an integer, for multiple selectmode this
+ returns a list of integers.
+
+
+
Add option to set background color on selected buttons.
+ Maybe should also be able set selected foreground as well.
+ Any others?
+
+
+
+
LogicalFont
+
Add boldFixed fonts,
+
+
+
Search for closest size font if no exact match.
+
+
+
Maybe replace with Tk8.0 font mechanism.
+
+
+
Can the Tk8.0 font measuring functionality be used in Pmw somehow?
+
+
+
+
Scrolled widgets
+
Can some common scrolling methods be factored out, either as
+ a base class, "ScrolledMixin" mixin class or as helper functions?
+ Candidate methods: constructor, destroy, interior, _hscrollMode,
+ _vscrollMode, _configureScrollCommands, _scrollXNow, _scrollYNow,
+ _scrollBothLater, _scrollBothNow, _toggleHorizScrollbar,
+ _toggleVertScrollbar.
+
+
+
ScrolledField should have optional arrow buttons, so that it
+ can still be scrolled even if the mouse does not have a
+ middle button.
+
+
+
+
Miscellaneous
+
Add a button to the Pmw "Stack trace window" which
+ optionally removes all grabs:
+
I normally interact with the "Stack trace window"
+ immediately, and dismiss it afterwards. In many cases
+ where a bug appears like this, the rest of the application
+ is still functional (many of the problems appearing at
+ this stage of development of my application are unforeseen
+ exceptions communicating with a robot on the other end of
+ a socket, not affecting the GUI per se). For that reason
+ I'd prefer if the "stack trace window" would push another
+ grab on the grab stack (if any grabs are active at the
+ moment the exception occurs). Could the window have an
+ extra "Terminate application" option for this case?
+
+
+
+
need to handle component option queries in configure():
+
foo = Pmw.AboutDialog(applicationname = 'abc XYZ')
+ foo.component('message').configure('text') - works
+ foo.cget('message_text') - works
+ foo.configure('message_text') - doesn't
+
+
+
+
Implement bindings (ComboBox, etc) via a dictionary lookup,
+ to allow people to invent new bindings, such as for
+ handicapped users. (Suggested by Michael McLay)
+
+
+
Modify bundlepmw.py so that it checks Pmw.def to see that no
+ files have been missed.
+
+
+
Potential cheap speedup by adding this to each module, or
+ inside functions if it has a loop containing calls to
+ builtins:
+
from __builtin__ import *
+
+
+
+
Look at how update_idletasks and after_* are used in Pmw -
+ are they consistent? could it be improved? What are the
+ problems of using these on other bits of an application
+ (such as when the size of the toplevel is being determined
+ for the window manager).
+
+
+
If lots of errors occur (such as in a fast time callback)
+ the error window may not appear, since Tk will wait until it
+ is idle - which may never occur. The solution is to call
+ update_idletask when updating the error window, but only
+ after a short time has passed. This will provide better
+ user response. However, it may not be possible to do this
+ if some python interpretes (omppython, for example) do not
+ handle calls to update_idletasks at certain times.
+
+
+
In the Pmw FAQ, in the "Why don't Pmw megawidgets have a
+ 'state' option?" section, it mentions several Pmw
+ megawidgets that can not be disabled. Fix them.
+
+
+
Add RCSID version string to all files.
+
+
+
When raising exceptions use the third argument to raise:
+
raise SimulationException, msg, sys.exc_info()[2]
+
+
+
+
When update_idletasks is called all pending changes are
+ flushed to the window system server. However, it may take
+ some time for the server to display the changes. If it is
+ required that the display be up-to-date, update_idletasks
+ should be followed by a call that blocks until processed by
+ the server and a reply received. This may be useful in
+ Pmw.busycallback to ensure the busy cursor remains visible
+ until the display is actually modified.
+
+
+
There is a small bug which appears only with Tk8.0 (the bug
+ is not apparent with Tk4.2). If a dialog is activated and
+ pops up directly over the cursor and the dialog has a
+ default button, then pressing the <strong>Return</strong>
+ key will not invoke the default button. If you move the
+ mouse out of and then back into the dialog, pressing the
+ <strong>Return</strong> key will work. This behaviour has
+ been noticed in Tcl-only programs, so it is probably a bug
+ in Tk. (Tested on Solaris.)
+
+
+
Modify PmwBlt.py to use blt2.4 instead of blt8.0.unoff.
+ Nick Belshaw <nickb@earth.ox.ac.uk> is looking at wrapping
+ the new BLT StripChart and TabSet into Pmw.
+
+
+
Perhaps Pmw should have its own exception defined, like
+ TkInters's TclError, perhaps called PmwError.
+
+
+
This one is caused by a bug in the implementation of Tcl/Tk
+ for Microsoft Windows NT (and maybe other Microsoft
+ products). Mouse release events can get lost if the
+ grab_set and grab_release commands are used and the mouse
+ goes outside of the window while the mouse button is down.
+ This can occur while Pmw modal dialogs are active. Below
+ is some Tkinter-only code which demonstrates the problem.
+ Maybe there is a work around.
+
# Test script to demonstrate bug in Tk
+ #implementation of grab under NT.
+
+ # Click on "Dialog" to bring up the modal
+ # dialog window. Then button down on the scale,
+ # move the mouse outside the window,
+ # then button up. The scale slider will still
+ # be sunken and clicks on the "OK" button
+ # will be ineffective.
+
+ import Tkinter
+
+ def activate():
+ waitVar.set(0)
+ toplevel.deiconify()
+ toplevel.wait_visibility()
+ toplevel.grab_set() # Problem here
+ toplevel.focus_set()
+ toplevel.wait_variable(waitVar)
+
+ def deactivate():
+ toplevel.withdraw()
+ toplevel.grab_release() # and here
+ waitVar.set(1)
+
+ root = Tkinter.Tk()
+ toplevel = Tkinter.Toplevel()
+ waitVar = Tkinter.IntVar()
+ toplevel.withdraw()
+ scale = Tkinter.Scale(toplevel, orient='horizontal', length=200)
+ scale.pack()
+ button = Tkinter.Button(toplevel, text='OK', command=deactivate)
+ button.pack()
+
+ button = Tkinter.Button(text='Dialog', command=activate)
+ button.pack()
+ button = Tkinter.Button(text='Exit', command=root.destroy)
+ button.pack()
+
+ root.mainloop()
+
+
+
+
+
+
Documentation
+
Document how to get Pmw working on a Mac, for example:
+
Unzip and untar
+
This depends on what you use to unpack the tar file. If
+ you use (macgzip and) SunTar you have to tell it that files
+ with ".py" extensions are text files (in the
+ preferences/file type section). If you use stuffit
+ expander: this can be made to do the conversion
+ correctly, but it could be that this only works if you set
+ the .py extension correctly in Internet Config.
+
+
Where do you untar Pmw?
+
+
+
How do you get line terminators correct (carriage
+ return/line feed)?
+
+
+
Is there any problem with file name case? (mixed
+ upper/lower case)
+
+
+
Is there any problem with file name length?
+
+
+
(Joseph Saltiel says: It was the same type of operation
+ as in Windows/Unix. Run a program that unzips it and
+ untars it. It seems to get case and length right on its
+ own.)
+
+
+
+
Let python know where Pmw is
+
If Pmw is in its own folder you will have to add the
+ parent of that folder to the sys paths in Edit
+ PythonPaths. If it is in the Python home folder, you
+ do not need to do this.
+
+
+
Make sure that the Pmw folder is called "Pmw" and not
+ something else. Since Pmw is a package, python expects
+ to find a "Pmw" folder somewhere in sys.path.
+
+
+
(Joseph Saltiel says: With the Python distribution on the
+ Mac there is an application called editPythonPrefs, when
+ you run it it gives you a list of a paths. These paths
+ are similiar to the PYTHONPATH variable. I just added the
+ path to Pmw at the bottom of this list.)
+
+
+
+
+
+
Document general ideas about building guis, eg:
+
When I write gui applications, I usually defer creation of windows
+ as much as possible - this means that the application starts up
+ quickly because it usually only has to create the main window.
+ Whenever another window is required for the first time, it is
+ created then. When the user has finished with the window, the
+ window is withdrawn, not deleted, so that next time it is required
+ it much faster to come up.
+
+
In summary - don't create a window until you need and
+ don't destroy a window if you may want it again.
+
+
The amount of memory required to keep the windows should not be
+ very much - except for very long running programs where the user
+ may create thousands of different windows.
Add to doco something like: "Another way to extend a Pmw
+ megawidget is to specify a non-default type for one of the
+ components. For example text_pytype = FontText."
+
+
+
Document pyclass and pyclass = None (options for null components
+ are ignored; the only time this can be used is with the
+ Group's tag component - all
+ other's use the component widget in some way)
+
+
+
Create index of all Pmw methods, functions, options, components.
+
+
+
Add description of how to run the Pmw demos without installing.
+
+
+
Add description of how to install Pmw.
+
+
+
Describe grid structure of megawidgets, so that it is possible
+ to extend megawidgets by adding new widgets into the interior
+ (hence avoiding a childsite in most megawidgets)
+
+
+
Document error display and difference between callback and
+ binding error reports.
+
+
+
Document difference between 'Helvetica 12' and 'Helvetica size: 12'
+ in logicalfont.
+
+
+
Add to howtouse, to describe using the option database to set
+ options for a specific megawidget:
Create man pages as well as html (modify createmanuals to produce both).
+
+
+
Maybe something with html frames like: itcl2.2/html/index.html
+
+
+
Add to starting.html a note that Pmw is a python "package" and add
+ a pointer to python documentation on packages.
+
+
+
Document scrolled widget implementations, explaining why they
+ are all slightly different (because the underlying widgets which
+ are being scrolled have different behaviors).
+
+
+
Make copyright clearer. Maybe borrow python's?
+
+
+
+
Demos
+
Check for missing demos.
+
+
+
In all demos can move the three lines beginning with "Import Pmw
+ from the sibling directory", to inside "if __name__" clause.
+ Also, "sibling directory" is now incorrect. Also, add note that
+ this is only necessary when running demos without installing Pmw.
+
+
+
Change demo/All.py so that it displays the traceback if it
+ cannot load or run a demo (easier for users to report errors).
+
+
+
Add option to demo/All.py: "Display demos in separate window"
+ to allow resizing of sub-demos
+
+
+
TimeCounter and Spectrum demos beep when they come up, using:
+
root.option_add('*EntryField*value', 'VALUE')
+
+
+
+
In demos, add title = 'blah' to top of file and replace
+ root.title(..) with root.title(title) at bottom.
+
+
+
Add comprehensive speed test demo which creates one or more of
+ each (common) megawidget. Remove old SpeedTest demo.
+
+
+
Check demos work when called from ptui. (Changes have to do
+ with calling compile/exec where __name__ is not the name of the
+ All.py script, but is '__builtin__')
+
+
+
PromptDialog demo should not remember password.
+
+
+
Finish Counter, Radioselect demos.
+
+
+
Modify the All demo so that you can reload a demo module.
+
+
+
The syntax-coloured code viewer looks strange on Microsoft NT,
+ because the size of the fonts differ. Check out Guido's
+ idle-0.1 text colouring for Pmw code viewer.
+
+
+
Document restrictions on adding bindings to a megawidget: you
+ probably need to bind to components of the megawidget and also
+ check that you are not destroying bindings set up by the
+ megawidget itself.
+
+
+
Add a demo that demonstrates setting the color scheme at run time.
+
+
+
+
Tests
+
Check for missing tests, such as TimeCounter, RadioSelect,
+ SelectionDialog, MessageBar, MenuBar, ComboBoxDialog, Balloon.
+
+
+
Create test for useTkOptionDb option to Pmw.initialise().
+
+
+
Check that destroyed widgets' python classes are garbage
+ collected (add test and/or demo).
+
+
+
Add tests for changecolor, setscheme, etc.
+
+
+
Need Resources test.
+
+
+
Create tests for deriving from Pmw classes (eg ComboBox).
+
+
+
+
Ideas
+
Add more Tix (www.xpi.com/tix/screenshot.html) and iwidgets widgets.
+
+
+
Look at spinner.itk for how to do vertical orientation on
+ same side for Counter.
+
+
+
Investigate these new features in Tk8.0 and see if they could be
+ used in Pmw:
+
embedded images in text widgets
+ destroy command ignores windows that don't exist
+
+
+
+
+
+
diff --git a/Pmw/Pmw_1_2/doc/transdove.gif b/Pmw/Pmw_1_2/doc/transdove.gif
new file mode 100644
index 00000000..a9d83cdc
Binary files /dev/null and b/Pmw/Pmw_1_2/doc/transdove.gif differ
diff --git a/Pmw/Pmw_1_2/lib/Pmw.def b/Pmw/Pmw_1_2/lib/Pmw.def
new file mode 100644
index 00000000..5965c118
--- /dev/null
+++ b/Pmw/Pmw_1_2/lib/Pmw.def
@@ -0,0 +1,58 @@
+# [Emacs: -*- python -*-]
+# --- This is the Pmw definition file ---
+#
+# It is invoked by the Pmw dynamic loader in Pmw.__init__.
+#
+# widgets : tuple with the names of those widget classes that are
+# stacked in a module of the same name.
+# widgetclasses : dictionary from names of widget classes to module names.
+# functions : dictionary from function names to modules names.
+# modules : tuple of module names that don't contain widget classes
+# of the same name.
+#
+
+# Widgets whose name is the same as its module.
+_widgets = (
+ 'AboutDialog', 'Balloon', 'ButtonBox', 'ComboBox',
+ 'ComboBoxDialog', 'Counter', 'CounterDialog', 'Dialog',
+ 'EntryField', 'Group', 'HistoryText', 'LabeledWidget',
+ 'MainMenuBar', 'MenuBar', 'MessageBar',
+ 'MessageDialog', 'NoteBook', 'OptionMenu', 'PanedWidget',
+ 'PromptDialog', 'RadioSelect', 'ScrolledCanvas', 'ScrolledField',
+ 'ScrolledFrame', 'ScrolledListBox', 'ScrolledText', 'SelectionDialog',
+ 'TextDialog', 'TimeCounter',
+)
+
+# Widgets whose name is not the same as its module.
+_extraWidgets = {
+}
+
+_functions = {
+ 'logicalfont' : 'LogicalFont',
+ 'logicalfontnames' : 'LogicalFont',
+ 'aboutversion' : 'AboutDialog',
+ 'aboutcopyright' : 'AboutDialog',
+ 'aboutcontact' : 'AboutDialog',
+ 'datestringtojdn' : 'TimeFuncs',
+ 'timestringtoseconds' : 'TimeFuncs',
+ 'setyearpivot' : 'TimeFuncs',
+ 'ymdtojdn' : 'TimeFuncs',
+ 'jdntoymd' : 'TimeFuncs',
+ 'stringtoreal' : 'TimeFuncs',
+ 'aligngrouptags' : 'Group',
+ 'OK' : 'EntryField',
+ 'ERROR' : 'EntryField',
+ 'PARTIAL' : 'EntryField',
+ 'numericvalidator' : 'EntryField',
+ 'integervalidator' : 'EntryField',
+ 'hexadecimalvalidator' : 'EntryField',
+ 'realvalidator' : 'EntryField',
+ 'alphabeticvalidator' : 'EntryField',
+ 'alphanumericvalidator' : 'EntryField',
+ 'timevalidator' : 'EntryField',
+ 'datevalidator' : 'EntryField',
+}
+
+_modules = (
+ 'Color', 'Blt',
+)
diff --git a/Pmw/Pmw_1_2/lib/PmwAboutDialog.py b/Pmw/Pmw_1_2/lib/PmwAboutDialog.py
new file mode 100644
index 00000000..fe78d276
--- /dev/null
+++ b/Pmw/Pmw_1_2/lib/PmwAboutDialog.py
@@ -0,0 +1,52 @@
+import Pmw
+
+class AboutDialog(Pmw.MessageDialog):
+ # Window to display version and contact information.
+
+ # Class members containing resettable 'default' values:
+ _version = ''
+ _copyright = ''
+ _contact = ''
+
+ def __init__(self, parent = None, **kw):
+
+ # Define the megawidget options.
+ INITOPT = Pmw.INITOPT
+ optiondefs = (
+ ('applicationname', '', INITOPT),
+ ('iconpos', 'w', None),
+ ('icon_bitmap', 'info', None),
+ ('buttons', ('Close',), None),
+ ('defaultbutton', 0, None),
+ )
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MessageDialog.__init__(self, parent)
+
+ applicationname = self['applicationname']
+ if not kw.has_key('title'):
+ self.configure(title = 'About ' + applicationname)
+
+ if not kw.has_key('message_text'):
+ text = applicationname + '\n\n'
+ if AboutDialog._version != '':
+ text = text + 'Version ' + AboutDialog._version + '\n'
+ if AboutDialog._copyright != '':
+ text = text + AboutDialog._copyright + '\n\n'
+ if AboutDialog._contact != '':
+ text = text + AboutDialog._contact
+
+ self.configure(message_text=text)
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+def aboutversion(value):
+ AboutDialog._version = value
+
+def aboutcopyright(value):
+ AboutDialog._copyright = value
+
+def aboutcontact(value):
+ AboutDialog._contact = value
diff --git a/Pmw/Pmw_1_2/lib/PmwBalloon.py b/Pmw/Pmw_1_2/lib/PmwBalloon.py
new file mode 100644
index 00000000..e1f88683
--- /dev/null
+++ b/Pmw/Pmw_1_2/lib/PmwBalloon.py
@@ -0,0 +1,365 @@
+import os
+import string
+import Tkinter
+import Pmw
+
+class Balloon(Pmw.MegaToplevel):
+ def __init__(self, parent = None, **kw):
+
+ # Define the megawidget options.
+ optiondefs = (
+ ('initwait', 500, None), # milliseconds
+ ('label_background', 'lightyellow', None),
+ ('label_foreground', 'black', None),
+ ('label_justify', 'left', None),
+ ('master', 'parent', None),
+ ('relmouse', 'none', self._relmouse),
+ ('state', 'both', self._state),
+ ('statuscommand', None, None),
+ ('xoffset', 20, None), # pixels
+ ('yoffset', 1, None), # pixels
+ ('hull_highlightthickness', 1, None),
+ ('hull_highlightbackground', 'black', None),
+ )
+ self.defineoptions(kw, optiondefs)
+
+ # Initialise the base class (after defining the options).
+ Pmw.MegaToplevel.__init__(self, parent)
+
+ self.withdraw()
+ self.overrideredirect(1)
+
+ # Create the components.
+ interior = self.interior()
+ self._label = self.createcomponent('label',
+ (), None,
+ Tkinter.Label, (interior,))
+ self._label.pack()
+
+ # The default hull configuration options give a black border
+ # around the balloon, but avoids a black 'flash' when the
+ # balloon is deiconified, before the text appears.
+ if not kw.has_key('hull_background'):
+ self.configure(hull_background = \
+ str(self._label.cget('background')))
+
+ # Initialise instance variables.
+ self._timer = None
+
+ # The widget or item that is currently triggering the balloon.
+ # It is None if the balloon is not being displayed. It is a
+ # one-tuple if the balloon is being displayed in response to a
+ # widget binding (value is the widget). It is a two-tuple if
+ # the balloon is being displayed in response to a canvas or
+ # text item binding (value is the widget and the item).
+ self._currentTrigger = None
+
+ # Check keywords and initialise options.
+ self.initialiseoptions()
+
+ def destroy(self):
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ Pmw.MegaToplevel.destroy(self)
+
+ def bind(self, widget, balloonHelp, statusHelp = None):
+
+ # If a previous bind for this widget exists, remove it.
+ self.unbind(widget)
+
+ if balloonHelp is None and statusHelp is None:
+ return
+
+ if statusHelp is None:
+ statusHelp = balloonHelp
+ enterId = widget.bind('',
+ lambda event, self = self, w = widget,
+ sHelp = statusHelp, bHelp = balloonHelp:
+ self._enter(event, w, sHelp, bHelp, 0))
+
+ # Set Motion binding so that if the pointer remains at rest
+ # within the widget until the status line removes the help and
+ # then the pointer moves again, then redisplay the help in the
+ # status line.
+ # Note: The Motion binding only works for basic widgets, and
+ # the hull of megawidgets but not for other megawidget components.
+ motionId = widget.bind('',
+ lambda event = None, self = self, statusHelp = statusHelp:
+ self.showstatus(statusHelp))
+
+ leaveId = widget.bind('', self._leave)
+ buttonId = widget.bind('', self._buttonpress)
+
+ # Set Destroy binding so that the balloon can be withdrawn and
+ # the timer can be cancelled if the widget is destroyed.
+ destroyId = widget.bind('', self._destroy)
+
+ # Use the None item in the widget's private Pmw dictionary to
+ # store the widget's bind callbacks, for later clean up.
+ if not hasattr(widget, '_Pmw_BalloonBindIds'):
+ widget._Pmw_BalloonBindIds = {}
+ widget._Pmw_BalloonBindIds[None] = \
+ (enterId, motionId, leaveId, buttonId, destroyId)
+
+ def unbind(self, widget):
+ if hasattr(widget, '_Pmw_BalloonBindIds'):
+ if widget._Pmw_BalloonBindIds.has_key(None):
+ (enterId, motionId, leaveId, buttonId, destroyId) = \
+ widget._Pmw_BalloonBindIds[None]
+ # Need to pass in old bindings, so that Tkinter can
+ # delete the commands. Otherwise, memory is leaked.
+ widget.unbind('', enterId)
+ widget.unbind('', motionId)
+ widget.unbind('', leaveId)
+ widget.unbind('', buttonId)
+ widget.unbind('', destroyId)
+ del widget._Pmw_BalloonBindIds[None]
+
+ if self._currentTrigger is not None and len(self._currentTrigger) == 1:
+ # The balloon is currently being displayed and the current
+ # trigger is a widget.
+ triggerWidget = self._currentTrigger[0]
+ if triggerWidget == widget:
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self.clearstatus()
+ self._currentTrigger = None
+
+ def tagbind(self, widget, tagOrItem, balloonHelp, statusHelp = None):
+
+ # If a previous bind for this widget's tagOrItem exists, remove it.
+ self.tagunbind(widget, tagOrItem)
+
+ if balloonHelp is None and statusHelp is None:
+ return
+
+ if statusHelp is None:
+ statusHelp = balloonHelp
+ enterId = widget.tag_bind(tagOrItem, '',
+ lambda event, self = self, w = widget,
+ sHelp = statusHelp, bHelp = balloonHelp:
+ self._enter(event, w, sHelp, bHelp, 1))
+ motionId = widget.tag_bind(tagOrItem, '',
+ lambda event = None, self = self, statusHelp = statusHelp:
+ self.showstatus(statusHelp))
+ leaveId = widget.tag_bind(tagOrItem, '', self._leave)
+ buttonId = widget.tag_bind(tagOrItem, '', self._buttonpress)
+
+ # Use the tagOrItem item in the widget's private Pmw dictionary to
+ # store the tagOrItem's bind callbacks, for later clean up.
+ if not hasattr(widget, '_Pmw_BalloonBindIds'):
+ widget._Pmw_BalloonBindIds = {}
+ widget._Pmw_BalloonBindIds[tagOrItem] = \
+ (enterId, motionId, leaveId, buttonId)
+
+ def tagunbind(self, widget, tagOrItem):
+ if hasattr(widget, '_Pmw_BalloonBindIds'):
+ if widget._Pmw_BalloonBindIds.has_key(tagOrItem):
+ (enterId, motionId, leaveId, buttonId) = \
+ widget._Pmw_BalloonBindIds[tagOrItem]
+ widget.tag_unbind(tagOrItem, '', enterId)
+ widget.tag_unbind(tagOrItem, '', motionId)
+ widget.tag_unbind(tagOrItem, '', leaveId)
+ widget.tag_unbind(tagOrItem, '', buttonId)
+ del widget._Pmw_BalloonBindIds[tagOrItem]
+
+ if self._currentTrigger is None:
+ # The balloon is not currently being displayed.
+ return
+
+ if len(self._currentTrigger) == 1:
+ # The current trigger is a widget.
+ return
+
+ if len(self._currentTrigger) == 2:
+ # The current trigger is a canvas item.
+ (triggerWidget, triggerItem) = self._currentTrigger
+ if triggerWidget == widget and triggerItem == tagOrItem:
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self.clearstatus()
+ self._currentTrigger = None
+ else: # The current trigger is a text item.
+ (triggerWidget, x, y) = self._currentTrigger
+ if triggerWidget == widget:
+ currentPos = widget.index('@%d,%d' % (x, y))
+ currentTags = widget.tag_names(currentPos)
+ if tagOrItem in currentTags:
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self.clearstatus()
+ self._currentTrigger = None
+
+ def showstatus(self, statusHelp):
+ if self['state'] in ('status', 'both'):
+ cmd = self['statuscommand']
+ if callable(cmd):
+ cmd(statusHelp)
+
+ def clearstatus(self):
+ self.showstatus(None)
+
+ def _state(self):
+ if self['state'] not in ('both', 'balloon', 'status', 'none'):
+ raise ValueError, 'bad state option ' + repr(self['state']) + \
+ ': should be one of \'both\', \'balloon\', ' + \
+ '\'status\' or \'none\''
+
+ def _relmouse(self):
+ if self['relmouse'] not in ('both', 'x', 'y', 'none'):
+ raise ValueError, 'bad relmouse option ' + repr(self['relmouse'])+ \
+ ': should be one of \'both\', \'x\', ' + '\'y\' or \'none\''
+
+ def _enter(self, event, widget, statusHelp, balloonHelp, isItem):
+
+ # Do not display balloon if mouse button is pressed. This
+ # will only occur if the button was pressed inside a widget,
+ # then the mouse moved out of and then back into the widget,
+ # with the button still held down. The number 0x1f00 is the
+ # button mask for the 5 possible buttons in X.
+ buttonPressed = (event.state & 0x1f00) != 0
+
+ if not buttonPressed and balloonHelp is not None and \
+ self['state'] in ('balloon', 'both'):
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+
+ self._timer = self.after(self['initwait'],
+ lambda self = self, widget = widget, help = balloonHelp,
+ isItem = isItem:
+ self._showBalloon(widget, help, isItem))
+
+ if isItem:
+ if hasattr(widget, 'canvasx'):
+ # The widget is a canvas.
+ item = widget.find_withtag('current')
+ if len(item) > 0:
+ item = item[0]
+ else:
+ item = None
+ self._currentTrigger = (widget, item)
+ else:
+ # The widget is a text widget.
+ self._currentTrigger = (widget, event.x, event.y)
+ else:
+ self._currentTrigger = (widget,)
+
+ self.showstatus(statusHelp)
+
+ def _leave(self, event):
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self.clearstatus()
+ self._currentTrigger = None
+
+ def _destroy(self, event):
+
+ # Only withdraw the balloon and cancel the timer if the widget
+ # being destroyed is the widget that triggered the balloon.
+ # Note that in a Tkinter Destroy event, the widget field is a
+ # string and not a widget as usual.
+
+ if self._currentTrigger is None:
+ # The balloon is not currently being displayed
+ return
+
+ if len(self._currentTrigger) == 1:
+ # The current trigger is a widget (not an item)
+ triggerWidget = self._currentTrigger[0]
+ if str(triggerWidget) == event.widget:
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self.clearstatus()
+ self._currentTrigger = None
+
+ def _buttonpress(self, event):
+ if self._timer is not None:
+ self.after_cancel(self._timer)
+ self._timer = None
+ self.withdraw()
+ self._currentTrigger = None
+
+ def _showBalloon(self, widget, balloonHelp, isItem):
+
+ self._label.configure(text = balloonHelp)
+
+ # First, display the balloon offscreen to get dimensions.
+ screenWidth = self.winfo_screenwidth()
+ screenHeight = self.winfo_screenheight()
+ self.geometry('+%d+0' % (screenWidth + 1))
+ self.update_idletasks()
+
+ if isItem:
+ # Get the bounding box of the current item.
+ bbox = widget.bbox('current')
+ if bbox is None:
+ # The item that triggered the balloon has disappeared,
+ # perhaps by a user's timer event that occured between
+ # the event and the 'initwait' timer calling
+ # this method.
+ return
+
+ # The widget is either a text or canvas. The meaning of
+ # the values returned by the bbox method is different for
+ # each, so use the existence of the 'canvasx' method to
+ # distinguish between them.
+ if hasattr(widget, 'canvasx'):
+ # The widget is a canvas. Place balloon under canvas
+ # item. The positions returned by bbox are relative
+ # to the entire canvas, not just the visible part, so
+ # need to convert to window coordinates.
+ leftrel = bbox[0] - widget.canvasx(0)
+ toprel = bbox[1] - widget.canvasy(0)
+ bottomrel = bbox[3] - widget.canvasy(0)
+ else:
+ # The widget is a text widget. Place balloon under
+ # the character closest to the mouse. The positions
+ # returned by bbox are relative to the text widget
+ # window (ie the visible part of the text only).
+ leftrel = bbox[0]
+ toprel = bbox[1]
+ bottomrel = bbox[1] + bbox[3]
+ else:
+ leftrel = 0
+ toprel = 0
+ bottomrel = widget.winfo_height()
+
+ xpointer, ypointer = widget.winfo_pointerxy() # -1 if off screen
+
+ if xpointer >= 0 and self['relmouse'] in ('both', 'x'):
+ x = xpointer
+ else:
+ x = leftrel + widget.winfo_rootx()
+ x = x + self['xoffset']
+
+ if ypointer >= 0 and self['relmouse'] in ('both', 'y'):
+ y = ypointer
+ else:
+ y = bottomrel + widget.winfo_rooty()
+ y = y + self['yoffset']
+
+ edges = (string.atoi(str(self.cget('hull_highlightthickness'))) +
+ string.atoi(str(self.cget('hull_borderwidth')))) * 2
+ if x + self._label.winfo_reqwidth() + edges > screenWidth:
+ x = screenWidth - self._label.winfo_reqwidth() - edges
+
+ if y + self._label.winfo_reqheight() + edges > screenHeight:
+ if ypointer >= 0 and self['relmouse'] in ('both', 'y'):
+ y = ypointer
+ else:
+ y = toprel + widget.winfo_rooty()
+ y = y - self._label.winfo_reqheight() - self['yoffset'] - edges
+
+ Pmw.setgeometryanddeiconify(self, '+%d+%d' % (x, y))
diff --git a/Pmw/Pmw_1_2/lib/PmwBase.py b/Pmw/Pmw_1_2/lib/PmwBase.py
new file mode 100644
index 00000000..da38e9a4
--- /dev/null
+++ b/Pmw/Pmw_1_2/lib/PmwBase.py
@@ -0,0 +1,1933 @@
+# Pmw megawidget base classes.
+
+# This module provides a foundation for building megawidgets. It
+# contains the MegaArchetype class which manages component widgets and
+# configuration options. Also provided are the MegaToplevel and
+# MegaWidget classes, derived from the MegaArchetype class. The
+# MegaToplevel class contains a Tkinter Toplevel widget to act as the
+# container of the megawidget. This is used as the base class of all
+# megawidgets that are contained in their own top level window, such
+# as a Dialog window. The MegaWidget class contains a Tkinter Frame
+# to act as the container of the megawidget. This is used as the base
+# class of all other megawidgets, such as a ComboBox or ButtonBox.
+#
+# Megawidgets are built by creating a class that inherits from either
+# the MegaToplevel or MegaWidget class.
+
+import os
+import string
+import sys
+import traceback
+import types
+import Tkinter
+
+# Special values used in index() methods of several megawidgets.
+END = ['end']
+SELECT = ['select']
+DEFAULT = ['default']
+
+# Constant used to indicate that an option can only be set by a call
+# to the constructor.
+INITOPT = ['initopt']
+_DEFAULT_OPTION_VALUE = ['default_option_value']
+_useTkOptionDb = 0
+
+# Symbolic constants for the indexes into an optionInfo list.
+_OPT_DEFAULT = 0
+_OPT_VALUE = 1
+_OPT_FUNCTION = 2
+
+# Stacks
+
+_busyStack = []
+ # Stack which tracks nested calls to show/hidebusycursor (called
+ # either directly or from activate()/deactivate()). Each element
+ # is a dictionary containing:
+ # 'newBusyWindows' : List of windows which had busy_hold called
+ # on them during a call to showbusycursor().
+ # The corresponding call to hidebusycursor()
+ # will call busy_release on these windows.
+ # 'busyFocus' : The blt _Busy window which showbusycursor()
+ # set the focus to.
+ # 'previousFocus' : The focus as it was when showbusycursor()
+ # was called. The corresponding call to
+ # hidebusycursor() will restore this focus if
+ # the focus has not been changed from busyFocus.
+
+_grabStack = []
+ # Stack of grabbed windows. It tracks calls to push/popgrab()
+ # (called either directly or from activate()/deactivate()). The
+ # window on the top of the stack is the window currently with the
+ # grab. Each element is a dictionary containing:
+ # 'grabWindow' : The window grabbed by pushgrab(). The
+ # corresponding call to popgrab() will release
+ # the grab on this window and restore the grab
+ # on the next window in the stack (if there is one).
+ # 'globalMode' : True if the grabWindow was grabbed with a
+ # global grab, false if the grab was local
+ # and 'nograb' if no grab was performed.
+ # 'previousFocus' : The focus as it was when pushgrab()
+ # was called. The corresponding call to
+ # popgrab() will restore this focus.
+ # 'deactivateFunction' :
+ # The function to call (usually grabWindow.deactivate) if
+ # popgrab() is called (usually from a deactivate() method)
+ # on a window which is not at the top of the stack (that is,
+ # does not have the grab or focus). For example, if a modal
+ # dialog is deleted by the window manager or deactivated by
+ # a timer. In this case, all dialogs above and including
+ # this one are deactivated, starting at the top of the
+ # stack.
+
+ # Note that when dealing with focus windows, the name of the Tk
+ # widget is used, since it may be the '_Busy' window, which has no
+ # python instance associated with it.
+
+#=============================================================================
+
+# Functions used to forward methods from a class to a component.
+
+# Fill in a flattened method resolution dictionary for a class (attributes are
+# filtered out). Flattening honours the MI method resolution rules
+# (depth-first search of bases in order). The dictionary has method names
+# for keys and functions for values.
+def __methodDict(cls, dict):
+
+ # the strategy is to traverse the class in the _reverse_ of the normal
+ # order, and overwrite any duplicates.
+ baseList = list(cls.__bases__)
+ baseList.reverse()
+
+ # do bases in reverse order, so first base overrides last base
+ for super in baseList:
+ __methodDict(super, dict)
+
+ # do my methods last to override base classes
+ for key, value in cls.__dict__.items():
+ # ignore class attributes
+ if type(value) == types.FunctionType:
+ dict[key] = value
+
+def __methods(cls):
+ # Return all method names for a class.
+
+ # Return all method names for a class (attributes are filtered
+ # out). Base classes are searched recursively.
+
+ dict = {}
+ __methodDict(cls, dict)
+ return dict.keys()
+
+# Function body to resolve a forwarding given the target method name and the
+# attribute name. The resulting lambda requires only self, but will forward
+# any other parameters.
+__stringBody = (
+ 'def %(method)s(this, *args, **kw): return ' +
+ 'apply(this.%(attribute)s.%(method)s, args, kw)')
+
+# Get a unique id
+__counter = 0
+def __unique():
+ global __counter
+ __counter = __counter + 1
+ return str(__counter)
+
+# Function body to resolve a forwarding given the target method name and the
+# index of the resolution function. The resulting lambda requires only self,
+# but will forward any other parameters. The target instance is identified
+# by invoking the resolution function.
+__funcBody = (
+ 'def %(method)s(this, *args, **kw): return ' +
+ 'apply(this.%(forwardFunc)s().%(method)s, args, kw)')
+
+def forwardmethods(fromClass, toClass, toPart, exclude = ()):
+ # Forward all methods from one class to another.
+
+ # Forwarders will be created in fromClass to forward method
+ # invocations to toClass. The methods to be forwarded are
+ # identified by flattening the interface of toClass, and excluding
+ # methods identified in the exclude list. Methods already defined
+ # in fromClass, or special methods with one or more leading or
+ # trailing underscores will not be forwarded.
+
+ # For a given object of class fromClass, the corresponding toClass
+ # object is identified using toPart. This can either be a String
+ # denoting an attribute of fromClass objects, or a function taking
+ # a fromClass object and returning a toClass object.
+
+ # Example:
+ # class MyClass:
+ # ...
+ # def __init__(self):
+ # ...
+ # self.__target = TargetClass()
+ # ...
+ # def findtarget(self):
+ # return self.__target
+ # forwardmethods(MyClass, TargetClass, '__target', ['dangerous1', 'dangerous2'])
+ # # ...or...
+ # forwardmethods(MyClass, TargetClass, MyClass.findtarget,
+ # ['dangerous1', 'dangerous2'])
+
+ # In both cases, all TargetClass methods will be forwarded from
+ # MyClass except for dangerous1, dangerous2, special methods like
+ # __str__, and pre-existing methods like findtarget.
+
+
+ # Allow an attribute name (String) or a function to determine the instance
+ if type(toPart) != types.StringType:
+
+ # check that it is something like a function
+ if callable(toPart):
+
+ # If a method is passed, use the function within it
+ if hasattr(toPart, 'im_func'):
+ toPart = toPart.im_func
+
+ # After this is set up, forwarders in this class will use
+ # the forwarding function. The forwarding function name is
+ # guaranteed to be unique, so that it can't be hidden by subclasses
+ forwardName = '__fwdfunc__' + __unique()
+ fromClass.__dict__[forwardName] = toPart
+
+ # It's not a valid type
+ else:
+ raise TypeError, 'toPart must be attribute name, function or method'
+
+ # get the full set of candidate methods
+ dict = {}
+ __methodDict(toClass, dict)
+
+ # discard special methods
+ for ex in dict.keys():
+ if ex[:1] == '_' or ex[-1:] == '_':
+ del dict[ex]
+ # discard dangerous methods supplied by the caller
+ for ex in exclude:
+ if dict.has_key(ex):
+ del dict[ex]
+ # discard methods already defined in fromClass
+ for ex in __methods(fromClass):
+ if dict.has_key(ex):
+ del dict[ex]
+
+ for method, func in dict.items():
+ d = {'method': method, 'func': func}
+ if type(toPart) == types.StringType:
+ execString = \
+ __stringBody % {'method' : method, 'attribute' : toPart}
+ else:
+ execString = \
+ __funcBody % {'forwardFunc' : forwardName, 'method' : method}
+
+ exec execString in d
+
+ # this creates a method
+ fromClass.__dict__[method] = d[method]
+
+#=============================================================================
+
+def setgeometryanddeiconify(window, geom):
+ # To avoid flashes on X and to position the window correctly on NT
+ # (caused by Tk bugs).
+
+ if os.name == 'nt' or \
+ (os.name == 'posix' and sys.platform[:6] == 'cygwin'):
+ # Require overrideredirect trick to stop window frame
+ # appearing momentarily.
+ redirect = window.overrideredirect()
+ if not redirect:
+ window.overrideredirect(1)
+ window.deiconify()
+ if geom is not None:
+ window.geometry(geom)
+ # Call update_idletasks to ensure NT moves the window to the
+ # correct position it is raised.
+ window.update_idletasks()
+ window.tkraise()
+ if not redirect:
+ window.overrideredirect(0)
+ else:
+ if geom is not None:
+ window.geometry(geom)
+
+ # Problem!? Which way around should the following two calls
+ # go? If deiconify() is called first then I get complaints
+ # from people using the enlightenment or sawfish window
+ # managers that when a dialog is activated it takes about 2
+ # seconds for the contents of the window to appear. But if
+ # tkraise() is called first then I get complaints from people
+ # using the twm window manager that when a dialog is activated
+ # it appears in the top right corner of the screen and also
+ # takes about 2 seconds to appear.
+
+ #window.tkraise()
+ # Call update_idletasks to ensure certain window managers (eg:
+ # enlightenment and sawfish) do not cause Tk to delay for
+ # about two seconds before displaying window.
+ #window.update_idletasks()
+ #window.deiconify()
+
+ window.deiconify()
+ if window.overrideredirect():
+ # The window is not under the control of the window manager
+ # and so we need to raise it ourselves.
+ window.tkraise()
+
+#=============================================================================
+
+class MegaArchetype:
+ # Megawidget abstract root class.
+
+ # This class provides methods which are inherited by classes
+ # implementing useful bases (this class doesn't provide a
+ # container widget inside which the megawidget can be built).
+
+ def __init__(self, parent = None, hullClass = None):
+
+ # Mapping from each megawidget option to a list of information
+ # about the option
+ # - default value
+ # - current value
+ # - function to call when the option is initialised in the
+ # call to initialiseoptions() in the constructor or
+ # modified via configure(). If this is INITOPT, the
+ # option is an initialisation option (an option that can
+ # be set by the call to the constructor but can not be
+ # used with configure).
+ # This mapping is not initialised here, but in the call to
+ # defineoptions() which precedes construction of this base class.
+ #
+ # self._optionInfo = {}
+
+ # Mapping from each component name to a tuple of information
+ # about the component.
+ # - component widget instance
+ # - configure function of widget instance
+ # - the class of the widget (Frame, EntryField, etc)
+ # - cget function of widget instance
+ # - the name of the component group of this component, if any
+ self.__componentInfo = {}
+
+ # Mapping from alias names to the names of components or
+ # sub-components.
+ self.__componentAliases = {}
+
+ # Contains information about the keywords provided to the
+ # constructor. It is a mapping from the keyword to a tuple
+ # containing:
+ # - value of keyword
+ # - a boolean indicating if the keyword has been used.
+ # A keyword is used if, during the construction of a megawidget,
+ # - it is defined in a call to defineoptions() or addoptions(), or
+ # - it references, by name, a component of the megawidget, or
+ # - it references, by group, at least one component
+ # At the end of megawidget construction, a call is made to
+ # initialiseoptions() which reports an error if there are
+ # unused options given to the constructor.
+ #
+ # After megawidget construction, the dictionary contains
+ # keywords which refer to a dynamic component group, so that
+ # these components can be created after megawidget
+ # construction and still use the group options given to the
+ # constructor.
+ #
+ # self._constructorKeywords = {}
+
+ # List of dynamic component groups. If a group is included in
+ # this list, then it not an error if a keyword argument for
+ # the group is given to the constructor or to configure(), but
+ # no components with this group have been created.
+ # self._dynamicGroups = ()
+
+ if hullClass is None:
+ self._hull = None
+ else:
+ if parent is None:
+ parent = Tkinter._default_root
+
+ # Create the hull.
+ self._hull = self.createcomponent('hull',
+ (), None,
+ hullClass, (parent,))
+ _hullToMegaWidget[self._hull] = self
+
+ if _useTkOptionDb:
+ # Now that a widget has been created, query the Tk
+ # option database to get the default values for the
+ # options which have not been set in the call to the
+ # constructor. This assumes that defineoptions() is
+ # called before the __init__().
+ option_get = self.option_get
+ _VALUE = _OPT_VALUE
+ _DEFAULT = _OPT_DEFAULT
+ for name, info in self._optionInfo.items():
+ value = info[_VALUE]
+ if value is _DEFAULT_OPTION_VALUE:
+ resourceClass = string.upper(name[0]) + name[1:]
+ value = option_get(name, resourceClass)
+ if value != '':
+ try:
+ # Convert the string to int/float/tuple, etc
+ value = eval(value, {'__builtins__': {}})
+ except:
+ pass
+ info[_VALUE] = value
+ else:
+ info[_VALUE] = info[_DEFAULT]
+
+ def destroy(self):
+ # Clean up optionInfo in case it contains circular references
+ # in the function field, such as self._settitle in class
+ # MegaToplevel.
+
+ self._optionInfo = {}
+ if self._hull is not None:
+ del _hullToMegaWidget[self._hull]
+ self._hull.destroy()
+
+ #======================================================================
+ # Methods used (mainly) during the construction of the megawidget.
+
+ def defineoptions(self, keywords, optionDefs, dynamicGroups = ()):
+ # Create options, providing the default value and the method
+ # to call when the value is changed. If any option created by
+ # base classes has the same name as one in , the
+ # base class's value and function will be overriden.
+
+ # This should be called before the constructor of the base
+ # class, so that default values defined in the derived class
+ # override those in the base class.
+
+ if not hasattr(self, '_constructorKeywords'):
+ # First time defineoptions has been called.
+ tmp = {}
+ for option, value in keywords.items():
+ tmp[option] = [value, 0]
+ self._constructorKeywords = tmp
+ self._optionInfo = {}
+ self._initialiseoptions_counter = 0
+ self._initialiseoptions_counter = self._initialiseoptions_counter + 1
+
+ if not hasattr(self, '_dynamicGroups'):
+ self._dynamicGroups = ()
+ self._dynamicGroups = self._dynamicGroups + tuple(dynamicGroups)
+ self.addoptions(optionDefs)
+
+ def addoptions(self, optionDefs):
+ # Add additional options, providing the default value and the
+ # method to call when the value is changed. See
+ # "defineoptions" for more details
+
+ # optimisations:
+ optionInfo = self._optionInfo
+ optionInfo_has_key = optionInfo.has_key
+ keywords = self._constructorKeywords
+ keywords_has_key = keywords.has_key
+ FUNCTION = _OPT_FUNCTION
+
+ for name, default, function in optionDefs:
+ if '_' not in name:
+ # The option will already exist if it has been defined
+ # in a derived class. In this case, do not override the
+ # default value of the option or the callback function
+ # if it is not None.
+ if not optionInfo_has_key(name):
+ if keywords_has_key(name):
+ value = keywords[name][0]
+ optionInfo[name] = [default, value, function]
+ del keywords[name]
+ else:
+ if _useTkOptionDb:
+ optionInfo[name] = \
+ [default, _DEFAULT_OPTION_VALUE, function]
+ else:
+ optionInfo[name] = [default, default, function]
+ elif optionInfo[name][FUNCTION] is None:
+ optionInfo[name][FUNCTION] = function
+ else:
+ # This option is of the form "component_option". If this is
+ # not already defined in self._constructorKeywords add it.
+ # This allows a derived class to override the default value
+ # of an option of a component of a base class.
+ if not keywords_has_key(name):
+ keywords[name] = [default, 0]
+
+ def createcomponent(self, componentName, componentAliases,
+ componentGroup, widgetClass, *widgetArgs, **kw):
+ # Create a component (during construction or later).
+
+ if self.__componentInfo.has_key(componentName):
+ raise ValueError, 'Component "%s" already exists' % componentName
+
+ if '_' in componentName:
+ raise ValueError, \
+ 'Component name "%s" must not contain "_"' % componentName
+
+ if hasattr(self, '_constructorKeywords'):
+ keywords = self._constructorKeywords
+ else:
+ keywords = {}
+ for alias, component in componentAliases:
+ # Create aliases to the component and its sub-components.
+ index = string.find(component, '_')
+ if index < 0:
+ self.__componentAliases[alias] = (component, None)
+ else:
+ mainComponent = component[:index]
+ subComponent = component[(index + 1):]
+ self.__componentAliases[alias] = (mainComponent, subComponent)
+
+ # Remove aliases from the constructor keyword arguments by
+ # replacing any keyword arguments that begin with *alias*
+ # with corresponding keys beginning with *component*.
+
+ alias = alias + '_'
+ aliasLen = len(alias)
+ for option in keywords.keys():
+ if len(option) > aliasLen and option[:aliasLen] == alias:
+ newkey = component + '_' + option[aliasLen:]
+ keywords[newkey] = keywords[option]
+ del keywords[option]
+
+ componentPrefix = componentName + '_'
+ nameLen = len(componentPrefix)
+ for option in keywords.keys():
+ if len(option) > nameLen and option[:nameLen] == componentPrefix:
+ # The keyword argument refers to this component, so add
+ # this to the options to use when constructing the widget.
+ kw[option[nameLen:]] = keywords[option][0]
+ del keywords[option]
+ else:
+ # Check if this keyword argument refers to the group
+ # of this component. If so, add this to the options
+ # to use when constructing the widget. Mark the
+ # keyword argument as being used, but do not remove it
+ # since it may be required when creating another
+ # component.
+ index = string.find(option, '_')
+ if index >= 0 and componentGroup == option[:index]:
+ rest = option[(index + 1):]
+ kw[rest] = keywords[option][0]
+ keywords[option][1] = 1
+
+ if kw.has_key('pyclass'):
+ widgetClass = kw['pyclass']
+ del kw['pyclass']
+ if widgetClass is None:
+ return None
+ if len(widgetArgs) == 1 and type(widgetArgs[0]) == types.TupleType:
+ # Arguments to the constructor can be specified as either
+ # multiple trailing arguments to createcomponent() or as a
+ # single tuple argument.
+ widgetArgs = widgetArgs[0]
+ widget = apply(widgetClass, widgetArgs, kw)
+ componentClass = widget.__class__.__name__
+ self.__componentInfo[componentName] = (widget, widget.configure,
+ componentClass, widget.cget, componentGroup)
+
+ return widget
+
+ def destroycomponent(self, name):
+ # Remove a megawidget component.
+
+ # This command is for use by megawidget designers to destroy a
+ # megawidget component.
+
+ self.__componentInfo[name][0].destroy()
+ del self.__componentInfo[name]
+
+ def createlabel(self, parent, childCols = 1, childRows = 1):
+
+ labelpos = self['labelpos']
+ labelmargin = self['labelmargin']
+ if labelpos is None:
+ return
+
+ label = self.createcomponent('label',
+ (), None,
+ Tkinter.Label, (parent,))
+
+ if labelpos[0] in 'ns':
+ # vertical layout
+ if labelpos[0] == 'n':
+ row = 0
+ margin = 1
+ else:
+ row = childRows + 3
+ margin = row - 1
+ label.grid(column=2, row=row, columnspan=childCols, sticky=labelpos)
+ parent.grid_rowconfigure(margin, minsize=labelmargin)
+ else:
+ # horizontal layout
+ if labelpos[0] == 'w':
+ col = 0
+ margin = 1
+ else:
+ col = childCols + 3
+ margin = col - 1
+ label.grid(column=col, row=2, rowspan=childRows, sticky=labelpos)
+ parent.grid_columnconfigure(margin, minsize=labelmargin)
+
+ def initialiseoptions(self, dummy = None):
+ self._initialiseoptions_counter = self._initialiseoptions_counter - 1
+ if self._initialiseoptions_counter == 0:
+ unusedOptions = []
+ keywords = self._constructorKeywords
+ for name in keywords.keys():
+ used = keywords[name][1]
+ if not used:
+ # This keyword argument has not been used. If it
+ # does not refer to a dynamic group, mark it as
+ # unused.
+ index = string.find(name, '_')
+ if index < 0 or name[:index] not in self._dynamicGroups:
+ unusedOptions.append(name)
+ if len(unusedOptions) > 0:
+ if len(unusedOptions) == 1:
+ text = 'Unknown option "'
+ else:
+ text = 'Unknown options "'
+ raise KeyError, text + string.join(unusedOptions, ', ') + \
+ '" for ' + self.__class__.__name__
+
+ # Call the configuration callback function for every option.
+ FUNCTION = _OPT_FUNCTION
+ for info in self._optionInfo.values():
+ func = info[FUNCTION]
+ if func is not None and func is not INITOPT:
+ func()
+
+ #======================================================================
+ # Method used to configure the megawidget.
+
+ def configure(self, option=None, **kw):
+ # Query or configure the megawidget options.
+ #
+ # If not empty, *kw* is a dictionary giving new
+ # values for some of the options of this megawidget or its
+ # components. For options defined for this megawidget, set
+ # the value of the option to the new value and call the
+ # configuration callback function, if any. For options of the
+ # form _