From 4523e2d8899a00de7ff7b56b56a44fc1afbdd151 Mon Sep 17 00:00:00 2001 From: eficas <> Date: Tue, 17 May 2005 11:54:51 +0000 Subject: [PATCH] *** empty log message *** --- Accas/A_AU_PLUS_UN.py | 29 + Accas/__init__.py | 1 + Aster/Cata/Macro/__init__.py | 3 + Aster/Cata/Macro/calc_fonction_ops.py | 322 +++ Aster/Cata/Macro/calc_precont_ops.py | 28 +- Aster/Cata/Macro/impr_fonction_ops.py | 55 +- Aster/Cata/Macro/impr_table_ops.py | 21 +- Aster/Cata/Macro/info_fonction_ops.py | 252 +++ Aster/Cata/Macro/macr_ascouf_calc_ops.py | 43 +- Aster/Cata/Macro/macr_ascouf_mail_ops.py | 6 +- Aster/Cata/Macro/macr_aspic_calc_ops.py | 48 +- Aster/Cata/Macro/macr_cabri_mail_ops.py | 16 +- Aster/Cata/Macro/macr_fiab_impr_ops.py | 20 +- Aster/Cata/Macro/macr_lign_coupe_ops.py | 266 ++- Aster/Cata/Macro/macr_recal_ops.py | 5 +- Aster/Cata/Macro/macro_cara_poutre_ops.py | 684 ------ Aster/Cata/Macro/macro_matr_asse_ops.py | 69 +- Aster/Cata/Macro/pre_gmsh_ops.py | 61 - Aster/Cata/Macro/reca_algo.py | 3 +- Aster/Cata/Macro/recal.py | 8 +- Pmw/Alpha_99_9_example/__init__.py | 1 + Pmw/Alpha_99_9_example/lib/Pmw.def | 9 + Pmw/Alpha_99_9_example/lib/PmwAlphaExample.py | 24 + Pmw/Alpha_99_9_example/lib/__init__.py | 1 + Pmw/Pmw_1_2/__init__.py | 1 + Pmw/Pmw_1_2/bin/bundlepmw.py | 169 ++ Pmw/Pmw_1_2/contrib/DirBrowser.py | 306 +++ Pmw/Pmw_1_2/contrib/MCListbox.py | 706 ++++++ Pmw/Pmw_1_2/contrib/PmwFileDialog.py | 498 +++++ Pmw/Pmw_1_2/contrib/PmwFullTimeCounter.py | 492 +++++ Pmw/Pmw_1_2/contrib/PmwVerticalGauge.py | 253 +++ Pmw/Pmw_1_2/contrib/README | 10 + Pmw/Pmw_1_2/contrib/TreeBrowser.py | 732 +++++++ Pmw/Pmw_1_2/demos/AboutDialog.py | 43 + Pmw/Pmw_1_2/demos/All.py | 310 +++ Pmw/Pmw_1_2/demos/Args.py | 191 ++ Pmw/Pmw_1_2/demos/Balloon.py | 185 ++ Pmw/Pmw_1_2/demos/BltGraph.py | 241 ++ Pmw/Pmw_1_2/demos/BltTabset.py | 101 + Pmw/Pmw_1_2/demos/ButtonBox.py | 56 + Pmw/Pmw_1_2/demos/Colors.py | 50 + Pmw/Pmw_1_2/demos/ComboBox.py | 76 + Pmw/Pmw_1_2/demos/ComboBoxDialog.py | 44 + Pmw/Pmw_1_2/demos/ConfigClass.py | 76 + Pmw/Pmw_1_2/demos/Counter.py | 121 ++ Pmw/Pmw_1_2/demos/CounterDialog.py | 60 + Pmw/Pmw_1_2/demos/DemoVersion.py | 36 + Pmw/Pmw_1_2/demos/Dialog.py | 89 + Pmw/Pmw_1_2/demos/EntryField.py | 98 + Pmw/Pmw_1_2/demos/ErrorHandling.py | 42 + Pmw/Pmw_1_2/demos/ExampleDemo.py | 33 + Pmw/Pmw_1_2/demos/Grid.py | 44 + Pmw/Pmw_1_2/demos/Group.py | 93 + Pmw/Pmw_1_2/demos/HistoryText.py | 102 + Pmw/Pmw_1_2/demos/LabeledWidget.py | 46 + Pmw/Pmw_1_2/demos/LogicalFont.py | 84 + Pmw/Pmw_1_2/demos/MainMenuBar.py | 176 ++ Pmw/Pmw_1_2/demos/MenuBar.py | 166 ++ Pmw/Pmw_1_2/demos/MessageBar.py | 85 + Pmw/Pmw_1_2/demos/MessageDialog.py | 102 + Pmw/Pmw_1_2/demos/MessageInfo.py | 108 + Pmw/Pmw_1_2/demos/MultiLineLabel.py | 73 + Pmw/Pmw_1_2/demos/NestedDialogs.py | 71 + Pmw/Pmw_1_2/demos/NoteBook.py | 52 + Pmw/Pmw_1_2/demos/NoteBook_2.py | 224 ++ Pmw/Pmw_1_2/demos/NoteBook_3.py | 26 + Pmw/Pmw_1_2/demos/OptionMenu.py | 66 + Pmw/Pmw_1_2/demos/PanedWidget.py | 103 + Pmw/Pmw_1_2/demos/PanedWidget_2.py | 65 + Pmw/Pmw_1_2/demos/PromptDialog.py | 62 + Pmw/Pmw_1_2/demos/RadioSelect.py | 116 + Pmw/Pmw_1_2/demos/Resources.py | 74 + Pmw/Pmw_1_2/demos/Resources_Pmw.py | 110 + Pmw/Pmw_1_2/demos/ScrolledCanvas.py | 124 ++ Pmw/Pmw_1_2/demos/ScrolledField.py | 51 + Pmw/Pmw_1_2/demos/ScrolledFrame.py | 157 ++ Pmw/Pmw_1_2/demos/ScrolledListBox.py | 118 + Pmw/Pmw_1_2/demos/ScrolledText.py | 99 + Pmw/Pmw_1_2/demos/ScrolledText_2.py | 99 + Pmw/Pmw_1_2/demos/SelectionDialog.py | 47 + Pmw/Pmw_1_2/demos/ShowBusy.py | 48 + Pmw/Pmw_1_2/demos/SpecialCounter.py | 68 + Pmw/Pmw_1_2/demos/SpecialEntry.py | 170 ++ Pmw/Pmw_1_2/demos/Spectrum.py | 166 ++ Pmw/Pmw_1_2/demos/SpeedTest.py | 60 + Pmw/Pmw_1_2/demos/SubClassing.py | 128 ++ Pmw/Pmw_1_2/demos/TextDialog.py | 75 + Pmw/Pmw_1_2/demos/TextDisplay.py | 78 + Pmw/Pmw_1_2/demos/TimeCounter.py | 40 + Pmw/Pmw_1_2/demos/WidgetDestroy.py | 36 + Pmw/Pmw_1_2/doc/AboutDialog.gif | Bin 0 -> 4081 bytes Pmw/Pmw_1_2/doc/AboutDialog.html | 286 +++ Pmw/Pmw_1_2/doc/Balloon.gif | Bin 0 -> 4660 bytes Pmw/Pmw_1_2/doc/Balloon.html | 429 ++++ Pmw/Pmw_1_2/doc/Blt.html | 135 ++ Pmw/Pmw_1_2/doc/ButtonBox.gif | Bin 0 -> 964 bytes Pmw/Pmw_1_2/doc/ButtonBox.html | 306 +++ Pmw/Pmw_1_2/doc/Color.html | 326 +++ Pmw/Pmw_1_2/doc/ComboBox.gif | Bin 0 -> 4556 bytes Pmw/Pmw_1_2/doc/ComboBox.html | 363 ++++ Pmw/Pmw_1_2/doc/ComboBoxDialog.gif | Bin 0 -> 3484 bytes Pmw/Pmw_1_2/doc/ComboBoxDialog.html | 286 +++ Pmw/Pmw_1_2/doc/Counter.gif | Bin 0 -> 2212 bytes Pmw/Pmw_1_2/doc/Counter.html | 455 ++++ Pmw/Pmw_1_2/doc/CounterDialog.gif | Bin 0 -> 2769 bytes Pmw/Pmw_1_2/doc/CounterDialog.html | 299 +++ Pmw/Pmw_1_2/doc/Dialog.gif | Bin 0 -> 2855 bytes Pmw/Pmw_1_2/doc/Dialog.html | 286 +++ Pmw/Pmw_1_2/doc/EntryField.gif | Bin 0 -> 2228 bytes Pmw/Pmw_1_2/doc/EntryField.html | 545 +++++ Pmw/Pmw_1_2/doc/ExampleDemo.py | 33 + Pmw/Pmw_1_2/doc/Group.gif | Bin 0 -> 2155 bytes Pmw/Pmw_1_2/doc/Group.html | 226 ++ Pmw/Pmw_1_2/doc/HistoryText.gif | Bin 0 -> 2298 bytes Pmw/Pmw_1_2/doc/HistoryText.html | 427 ++++ Pmw/Pmw_1_2/doc/LabeledWidget.gif | Bin 0 -> 887 bytes Pmw/Pmw_1_2/doc/LabeledWidget.html | 170 ++ Pmw/Pmw_1_2/doc/MainMenuBar.gif | Bin 0 -> 518 bytes Pmw/Pmw_1_2/doc/MainMenuBar.html | 421 ++++ Pmw/Pmw_1_2/doc/MegaArchetype.html | 459 ++++ Pmw/Pmw_1_2/doc/MegaToplevel.html | 267 +++ Pmw/Pmw_1_2/doc/MegaWidget.html | 83 + Pmw/Pmw_1_2/doc/MenuBar.gif | Bin 0 -> 518 bytes Pmw/Pmw_1_2/doc/MenuBar.html | 399 ++++ Pmw/Pmw_1_2/doc/MessageBar.gif | Bin 0 -> 435 bytes Pmw/Pmw_1_2/doc/MessageBar.html | 302 +++ Pmw/Pmw_1_2/doc/MessageDialog.gif | Bin 0 -> 3374 bytes Pmw/Pmw_1_2/doc/MessageDialog.html | 326 +++ Pmw/Pmw_1_2/doc/NoteBook.gif | Bin 0 -> 2585 bytes Pmw/Pmw_1_2/doc/NoteBook.html | 344 +++ Pmw/Pmw_1_2/doc/OptionMenu.gif | Bin 0 -> 2354 bytes Pmw/Pmw_1_2/doc/OptionMenu.html | 289 +++ Pmw/Pmw_1_2/doc/PanedWidget.gif | Bin 0 -> 1917 bytes Pmw/Pmw_1_2/doc/PanedWidget.html | 345 +++ Pmw/Pmw_1_2/doc/PmwFunctions.html | 766 +++++++ Pmw/Pmw_1_2/doc/PromptDialog.gif | Bin 0 -> 1959 bytes Pmw/Pmw_1_2/doc/PromptDialog.html | 293 +++ Pmw/Pmw_1_2/doc/RadioSelect.gif | Bin 0 -> 4476 bytes Pmw/Pmw_1_2/doc/RadioSelect.html | 405 ++++ Pmw/Pmw_1_2/doc/ScrolledCanvas.gif | Bin 0 -> 2931 bytes Pmw/Pmw_1_2/doc/ScrolledCanvas.html | 352 +++ Pmw/Pmw_1_2/doc/ScrolledField.gif | Bin 0 -> 615 bytes Pmw/Pmw_1_2/doc/ScrolledField.html | 187 ++ Pmw/Pmw_1_2/doc/ScrolledFrame.gif | Bin 0 -> 3926 bytes Pmw/Pmw_1_2/doc/ScrolledFrame.html | 479 ++++ Pmw/Pmw_1_2/doc/ScrolledListBox.gif | Bin 0 -> 1855 bytes Pmw/Pmw_1_2/doc/ScrolledListBox.html | 379 ++++ Pmw/Pmw_1_2/doc/ScrolledText.gif | Bin 0 -> 12007 bytes Pmw/Pmw_1_2/doc/ScrolledText.html | 409 ++++ Pmw/Pmw_1_2/doc/ScrolledText_test.py | 116 + Pmw/Pmw_1_2/doc/SelectionDialog.gif | Bin 0 -> 3204 bytes Pmw/Pmw_1_2/doc/SelectionDialog.html | 281 +++ Pmw/Pmw_1_2/doc/TextDialog.gif | Bin 0 -> 4953 bytes Pmw/Pmw_1_2/doc/TextDialog.html | 301 +++ Pmw/Pmw_1_2/doc/TimeCounter.gif | Bin 0 -> 1077 bytes Pmw/Pmw_1_2/doc/TimeCounter.html | 363 ++++ Pmw/Pmw_1_2/doc/blue_line.gif | Bin 0 -> 981 bytes Pmw/Pmw_1_2/doc/blueball.gif | Bin 0 -> 318 bytes Pmw/Pmw_1_2/doc/bugs.html | 378 ++++ Pmw/Pmw_1_2/doc/changes.html | 1741 +++++++++++++++ Pmw/Pmw_1_2/doc/copyright.html | 57 + Pmw/Pmw_1_2/doc/counter1.gif | Bin 0 -> 541 bytes Pmw/Pmw_1_2/doc/counter2.gif | Bin 0 -> 1333 bytes Pmw/Pmw_1_2/doc/demosandtests.html | 364 ++++ Pmw/Pmw_1_2/doc/dynamicloader.html | 147 ++ Pmw/Pmw_1_2/doc/example.py | 79 + Pmw/Pmw_1_2/doc/example1.gif | Bin 0 -> 1546 bytes Pmw/Pmw_1_2/doc/example2.gif | Bin 0 -> 1556 bytes Pmw/Pmw_1_2/doc/exercises.py | 123 ++ Pmw/Pmw_1_2/doc/features.html | 87 + Pmw/Pmw_1_2/doc/halfblueball.gif | Bin 0 -> 299 bytes Pmw/Pmw_1_2/doc/howtobuild.html | 465 ++++ Pmw/Pmw_1_2/doc/howtouse.html | 719 ++++++ Pmw/Pmw_1_2/doc/index.html | 131 ++ Pmw/Pmw_1_2/doc/porting.html | 325 +++ Pmw/Pmw_1_2/doc/refindex.html | 79 + Pmw/Pmw_1_2/doc/scale1.gif | Bin 0 -> 1016 bytes Pmw/Pmw_1_2/doc/scale2.gif | Bin 0 -> 1943 bytes Pmw/Pmw_1_2/doc/starting.html | 382 ++++ Pmw/Pmw_1_2/doc/todo.html | 1111 ++++++++++ Pmw/Pmw_1_2/doc/transdove.gif | Bin 0 -> 438 bytes Pmw/Pmw_1_2/lib/Pmw.def | 58 + Pmw/Pmw_1_2/lib/PmwAboutDialog.py | 52 + Pmw/Pmw_1_2/lib/PmwBalloon.py | 365 ++++ Pmw/Pmw_1_2/lib/PmwBase.py | 1933 +++++++++++++++++ Pmw/Pmw_1_2/lib/PmwBlt.py | 643 ++++++ Pmw/Pmw_1_2/lib/PmwButtonBox.py | 224 ++ Pmw/Pmw_1_2/lib/PmwColor.py | 361 +++ Pmw/Pmw_1_2/lib/PmwComboBox.py | 382 ++++ Pmw/Pmw_1_2/lib/PmwComboBoxDialog.py | 60 + Pmw/Pmw_1_2/lib/PmwCounter.py | 373 ++++ Pmw/Pmw_1_2/lib/PmwCounterDialog.py | 54 + Pmw/Pmw_1_2/lib/PmwDialog.py | 184 ++ Pmw/Pmw_1_2/lib/PmwEntryField.py | 458 ++++ Pmw/Pmw_1_2/lib/PmwGroup.py | 113 + Pmw/Pmw_1_2/lib/PmwHistoryText.py | 145 ++ Pmw/Pmw_1_2/lib/PmwLabeledWidget.py | 34 + Pmw/Pmw_1_2/lib/PmwLoader.py | 174 ++ Pmw/Pmw_1_2/lib/PmwLogicalFont.py | 191 ++ Pmw/Pmw_1_2/lib/PmwMainMenuBar.py | 225 ++ Pmw/Pmw_1_2/lib/PmwMenuBar.py | 243 +++ Pmw/Pmw_1_2/lib/PmwMessageBar.py | 143 ++ Pmw/Pmw_1_2/lib/PmwMessageDialog.py | 73 + Pmw/Pmw_1_2/lib/PmwNoteBook.py | 617 ++++++ Pmw/Pmw_1_2/lib/PmwOptionMenu.py | 146 ++ Pmw/Pmw_1_2/lib/PmwPanedWidget.py | 627 ++++++ Pmw/Pmw_1_2/lib/PmwPromptDialog.py | 51 + Pmw/Pmw_1_2/lib/PmwRadioSelect.py | 234 ++ Pmw/Pmw_1_2/lib/PmwScrolledCanvas.py | 289 +++ Pmw/Pmw_1_2/lib/PmwScrolledField.py | 53 + Pmw/Pmw_1_2/lib/PmwScrolledFrame.py | 395 ++++ Pmw/Pmw_1_2/lib/PmwScrolledListBox.py | 376 ++++ Pmw/Pmw_1_2/lib/PmwScrolledText.py | 443 ++++ Pmw/Pmw_1_2/lib/PmwSelectionDialog.py | 55 + Pmw/Pmw_1_2/lib/PmwTextDialog.py | 38 + Pmw/Pmw_1_2/lib/PmwTimeCounter.py | 381 ++++ Pmw/Pmw_1_2/lib/PmwTimeFuncs.py | 146 ++ Pmw/Pmw_1_2/lib/__init__.py | 1 + Pmw/Pmw_1_2/tests/AboutDialog_test.py | 59 + Pmw/Pmw_1_2/tests/All.py | 35 + Pmw/Pmw_1_2/tests/Blt_test.py | 356 +++ Pmw/Pmw_1_2/tests/ButtonBox_test.py | 71 + Pmw/Pmw_1_2/tests/Colors_test.py | 46 + Pmw/Pmw_1_2/tests/ComboBox_test.py | 184 ++ Pmw/Pmw_1_2/tests/CounterDialog_test.py | 98 + Pmw/Pmw_1_2/tests/Counter_test.py | 188 ++ Pmw/Pmw_1_2/tests/Dialog_test.py | 122 ++ Pmw/Pmw_1_2/tests/EntryField_test.py | 109 + Pmw/Pmw_1_2/tests/LabeledWidget_test.py | 49 + Pmw/Pmw_1_2/tests/ManualTests.py | 488 +++++ Pmw/Pmw_1_2/tests/MegaWidget_test.py | 129 ++ Pmw/Pmw_1_2/tests/MessageDialog_test.py | 58 + Pmw/Pmw_1_2/tests/NoteBook_test.py | 173 ++ Pmw/Pmw_1_2/tests/OptionMenu_test.py | 53 + Pmw/Pmw_1_2/tests/Options_test.py | 304 +++ Pmw/Pmw_1_2/tests/PanedWidget_test.py | 39 + Pmw/Pmw_1_2/tests/PmwBase_test.py | 181 ++ Pmw/Pmw_1_2/tests/PromptDialog_test.py | 81 + Pmw/Pmw_1_2/tests/RadioSelect_test.py | 112 + Pmw/Pmw_1_2/tests/ScrolledCanvas_test.py | 105 + Pmw/Pmw_1_2/tests/ScrolledField_test.py | 32 + Pmw/Pmw_1_2/tests/ScrolledFrame_test.py | 98 + Pmw/Pmw_1_2/tests/ScrolledListBox_test.py | 151 ++ Pmw/Pmw_1_2/tests/ScrolledText_test.py | 116 + Pmw/Pmw_1_2/tests/SelectionDialog_test.py | 69 + Pmw/Pmw_1_2/tests/Test.py | 521 +++++ Pmw/Pmw_1_2/tests/TestVersion.py | 19 + Pmw/Pmw_1_2/tests/TextDialog_test.py | 53 + Pmw/Pmw_1_2/tests/Tkinter_test.py | 393 ++++ Pmw/Pmw_1_2/tests/earthris.gif | Bin 0 -> 6343 bytes Pmw/Pmw_1_2/tests/flagup.bmp | 27 + Pmw/README | 10 + Pmw/__init__.py | 40 + 253 files changed, 42861 insertions(+), 980 deletions(-) create mode 100644 Accas/A_AU_PLUS_UN.py create mode 100644 Aster/Cata/Macro/calc_fonction_ops.py create mode 100644 Aster/Cata/Macro/info_fonction_ops.py delete mode 100644 Aster/Cata/Macro/macro_cara_poutre_ops.py delete mode 100644 Aster/Cata/Macro/pre_gmsh_ops.py create mode 100644 Pmw/Alpha_99_9_example/__init__.py create mode 100644 Pmw/Alpha_99_9_example/lib/Pmw.def create mode 100644 Pmw/Alpha_99_9_example/lib/PmwAlphaExample.py create mode 100644 Pmw/Alpha_99_9_example/lib/__init__.py create mode 100644 Pmw/Pmw_1_2/__init__.py create mode 100755 Pmw/Pmw_1_2/bin/bundlepmw.py create mode 100644 Pmw/Pmw_1_2/contrib/DirBrowser.py create mode 100644 Pmw/Pmw_1_2/contrib/MCListbox.py create mode 100644 Pmw/Pmw_1_2/contrib/PmwFileDialog.py create mode 100644 Pmw/Pmw_1_2/contrib/PmwFullTimeCounter.py create mode 100644 Pmw/Pmw_1_2/contrib/PmwVerticalGauge.py create mode 100644 Pmw/Pmw_1_2/contrib/README create mode 100644 Pmw/Pmw_1_2/contrib/TreeBrowser.py create mode 100644 Pmw/Pmw_1_2/demos/AboutDialog.py create mode 100755 Pmw/Pmw_1_2/demos/All.py create mode 100644 Pmw/Pmw_1_2/demos/Args.py create mode 100644 Pmw/Pmw_1_2/demos/Balloon.py create mode 100644 Pmw/Pmw_1_2/demos/BltGraph.py create mode 100644 Pmw/Pmw_1_2/demos/BltTabset.py create mode 100644 Pmw/Pmw_1_2/demos/ButtonBox.py create mode 100644 Pmw/Pmw_1_2/demos/Colors.py create mode 100644 Pmw/Pmw_1_2/demos/ComboBox.py create mode 100644 Pmw/Pmw_1_2/demos/ComboBoxDialog.py create mode 100644 Pmw/Pmw_1_2/demos/ConfigClass.py create mode 100644 Pmw/Pmw_1_2/demos/Counter.py create mode 100644 Pmw/Pmw_1_2/demos/CounterDialog.py create mode 100644 Pmw/Pmw_1_2/demos/DemoVersion.py create mode 100644 Pmw/Pmw_1_2/demos/Dialog.py create mode 100644 Pmw/Pmw_1_2/demos/EntryField.py create mode 100644 Pmw/Pmw_1_2/demos/ErrorHandling.py create mode 100644 Pmw/Pmw_1_2/demos/ExampleDemo.py create mode 100644 Pmw/Pmw_1_2/demos/Grid.py create mode 100644 Pmw/Pmw_1_2/demos/Group.py create mode 100644 Pmw/Pmw_1_2/demos/HistoryText.py create mode 100644 Pmw/Pmw_1_2/demos/LabeledWidget.py create mode 100644 Pmw/Pmw_1_2/demos/LogicalFont.py create mode 100644 Pmw/Pmw_1_2/demos/MainMenuBar.py create mode 100644 Pmw/Pmw_1_2/demos/MenuBar.py create mode 100644 Pmw/Pmw_1_2/demos/MessageBar.py create mode 100644 Pmw/Pmw_1_2/demos/MessageDialog.py create mode 100644 Pmw/Pmw_1_2/demos/MessageInfo.py create mode 100644 Pmw/Pmw_1_2/demos/MultiLineLabel.py create mode 100644 Pmw/Pmw_1_2/demos/NestedDialogs.py create mode 100644 Pmw/Pmw_1_2/demos/NoteBook.py create mode 100644 Pmw/Pmw_1_2/demos/NoteBook_2.py create mode 100644 Pmw/Pmw_1_2/demos/NoteBook_3.py create mode 100644 Pmw/Pmw_1_2/demos/OptionMenu.py create mode 100644 Pmw/Pmw_1_2/demos/PanedWidget.py create mode 100644 Pmw/Pmw_1_2/demos/PanedWidget_2.py create mode 100644 Pmw/Pmw_1_2/demos/PromptDialog.py create mode 100644 Pmw/Pmw_1_2/demos/RadioSelect.py create mode 100644 Pmw/Pmw_1_2/demos/Resources.py create mode 100644 Pmw/Pmw_1_2/demos/Resources_Pmw.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledCanvas.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledField.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledFrame.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledListBox.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledText.py create mode 100644 Pmw/Pmw_1_2/demos/ScrolledText_2.py create mode 100644 Pmw/Pmw_1_2/demos/SelectionDialog.py create mode 100644 Pmw/Pmw_1_2/demos/ShowBusy.py create mode 100644 Pmw/Pmw_1_2/demos/SpecialCounter.py create mode 100644 Pmw/Pmw_1_2/demos/SpecialEntry.py create mode 100644 Pmw/Pmw_1_2/demos/Spectrum.py create mode 100644 Pmw/Pmw_1_2/demos/SpeedTest.py create mode 100644 Pmw/Pmw_1_2/demos/SubClassing.py create mode 100644 Pmw/Pmw_1_2/demos/TextDialog.py create mode 100644 Pmw/Pmw_1_2/demos/TextDisplay.py create mode 100644 Pmw/Pmw_1_2/demos/TimeCounter.py create mode 100644 Pmw/Pmw_1_2/demos/WidgetDestroy.py create mode 100644 Pmw/Pmw_1_2/doc/AboutDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/AboutDialog.html create mode 100644 Pmw/Pmw_1_2/doc/Balloon.gif create mode 100644 Pmw/Pmw_1_2/doc/Balloon.html create mode 100644 Pmw/Pmw_1_2/doc/Blt.html create mode 100644 Pmw/Pmw_1_2/doc/ButtonBox.gif create mode 100644 Pmw/Pmw_1_2/doc/ButtonBox.html create mode 100644 Pmw/Pmw_1_2/doc/Color.html create mode 100644 Pmw/Pmw_1_2/doc/ComboBox.gif create mode 100644 Pmw/Pmw_1_2/doc/ComboBox.html create mode 100644 Pmw/Pmw_1_2/doc/ComboBoxDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/ComboBoxDialog.html create mode 100644 Pmw/Pmw_1_2/doc/Counter.gif create mode 100644 Pmw/Pmw_1_2/doc/Counter.html create mode 100644 Pmw/Pmw_1_2/doc/CounterDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/CounterDialog.html create mode 100644 Pmw/Pmw_1_2/doc/Dialog.gif create mode 100644 Pmw/Pmw_1_2/doc/Dialog.html create mode 100644 Pmw/Pmw_1_2/doc/EntryField.gif create mode 100644 Pmw/Pmw_1_2/doc/EntryField.html create mode 100644 Pmw/Pmw_1_2/doc/ExampleDemo.py create mode 100644 Pmw/Pmw_1_2/doc/Group.gif create mode 100644 Pmw/Pmw_1_2/doc/Group.html create mode 100644 Pmw/Pmw_1_2/doc/HistoryText.gif create mode 100644 Pmw/Pmw_1_2/doc/HistoryText.html create mode 100644 Pmw/Pmw_1_2/doc/LabeledWidget.gif create mode 100644 Pmw/Pmw_1_2/doc/LabeledWidget.html create mode 100644 Pmw/Pmw_1_2/doc/MainMenuBar.gif create mode 100644 Pmw/Pmw_1_2/doc/MainMenuBar.html create mode 100644 Pmw/Pmw_1_2/doc/MegaArchetype.html create mode 100644 Pmw/Pmw_1_2/doc/MegaToplevel.html create mode 100644 Pmw/Pmw_1_2/doc/MegaWidget.html create mode 100644 Pmw/Pmw_1_2/doc/MenuBar.gif create mode 100644 Pmw/Pmw_1_2/doc/MenuBar.html create mode 100644 Pmw/Pmw_1_2/doc/MessageBar.gif create mode 100644 Pmw/Pmw_1_2/doc/MessageBar.html create mode 100644 Pmw/Pmw_1_2/doc/MessageDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/MessageDialog.html create mode 100644 Pmw/Pmw_1_2/doc/NoteBook.gif create mode 100644 Pmw/Pmw_1_2/doc/NoteBook.html create mode 100644 Pmw/Pmw_1_2/doc/OptionMenu.gif create mode 100644 Pmw/Pmw_1_2/doc/OptionMenu.html create mode 100644 Pmw/Pmw_1_2/doc/PanedWidget.gif create mode 100644 Pmw/Pmw_1_2/doc/PanedWidget.html create mode 100644 Pmw/Pmw_1_2/doc/PmwFunctions.html create mode 100644 Pmw/Pmw_1_2/doc/PromptDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/PromptDialog.html create mode 100644 Pmw/Pmw_1_2/doc/RadioSelect.gif create mode 100644 Pmw/Pmw_1_2/doc/RadioSelect.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledCanvas.gif create mode 100644 Pmw/Pmw_1_2/doc/ScrolledCanvas.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledField.gif create mode 100644 Pmw/Pmw_1_2/doc/ScrolledField.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledFrame.gif create mode 100644 Pmw/Pmw_1_2/doc/ScrolledFrame.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledListBox.gif create mode 100644 Pmw/Pmw_1_2/doc/ScrolledListBox.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledText.gif create mode 100644 Pmw/Pmw_1_2/doc/ScrolledText.html create mode 100644 Pmw/Pmw_1_2/doc/ScrolledText_test.py create mode 100644 Pmw/Pmw_1_2/doc/SelectionDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/SelectionDialog.html create mode 100644 Pmw/Pmw_1_2/doc/TextDialog.gif create mode 100644 Pmw/Pmw_1_2/doc/TextDialog.html create mode 100644 Pmw/Pmw_1_2/doc/TimeCounter.gif create mode 100644 Pmw/Pmw_1_2/doc/TimeCounter.html create mode 100644 Pmw/Pmw_1_2/doc/blue_line.gif create mode 100644 Pmw/Pmw_1_2/doc/blueball.gif create mode 100644 Pmw/Pmw_1_2/doc/bugs.html create mode 100644 Pmw/Pmw_1_2/doc/changes.html create mode 100644 Pmw/Pmw_1_2/doc/copyright.html create mode 100644 Pmw/Pmw_1_2/doc/counter1.gif create mode 100644 Pmw/Pmw_1_2/doc/counter2.gif create mode 100644 Pmw/Pmw_1_2/doc/demosandtests.html create mode 100644 Pmw/Pmw_1_2/doc/dynamicloader.html create mode 100644 Pmw/Pmw_1_2/doc/example.py create mode 100644 Pmw/Pmw_1_2/doc/example1.gif create mode 100644 Pmw/Pmw_1_2/doc/example2.gif create mode 100644 Pmw/Pmw_1_2/doc/exercises.py create mode 100644 Pmw/Pmw_1_2/doc/features.html create mode 100644 Pmw/Pmw_1_2/doc/halfblueball.gif create mode 100644 Pmw/Pmw_1_2/doc/howtobuild.html create mode 100644 Pmw/Pmw_1_2/doc/howtouse.html create mode 100644 Pmw/Pmw_1_2/doc/index.html create mode 100644 Pmw/Pmw_1_2/doc/porting.html create mode 100644 Pmw/Pmw_1_2/doc/refindex.html create mode 100644 Pmw/Pmw_1_2/doc/scale1.gif create mode 100644 Pmw/Pmw_1_2/doc/scale2.gif create mode 100644 Pmw/Pmw_1_2/doc/starting.html create mode 100644 Pmw/Pmw_1_2/doc/todo.html create mode 100644 Pmw/Pmw_1_2/doc/transdove.gif create mode 100644 Pmw/Pmw_1_2/lib/Pmw.def create mode 100644 Pmw/Pmw_1_2/lib/PmwAboutDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwBalloon.py create mode 100644 Pmw/Pmw_1_2/lib/PmwBase.py create mode 100644 Pmw/Pmw_1_2/lib/PmwBlt.py create mode 100644 Pmw/Pmw_1_2/lib/PmwButtonBox.py create mode 100644 Pmw/Pmw_1_2/lib/PmwColor.py create mode 100644 Pmw/Pmw_1_2/lib/PmwComboBox.py create mode 100644 Pmw/Pmw_1_2/lib/PmwComboBoxDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwCounter.py create mode 100644 Pmw/Pmw_1_2/lib/PmwCounterDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwEntryField.py create mode 100644 Pmw/Pmw_1_2/lib/PmwGroup.py create mode 100644 Pmw/Pmw_1_2/lib/PmwHistoryText.py create mode 100644 Pmw/Pmw_1_2/lib/PmwLabeledWidget.py create mode 100644 Pmw/Pmw_1_2/lib/PmwLoader.py create mode 100644 Pmw/Pmw_1_2/lib/PmwLogicalFont.py create mode 100644 Pmw/Pmw_1_2/lib/PmwMainMenuBar.py create mode 100644 Pmw/Pmw_1_2/lib/PmwMenuBar.py create mode 100644 Pmw/Pmw_1_2/lib/PmwMessageBar.py create mode 100644 Pmw/Pmw_1_2/lib/PmwMessageDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwNoteBook.py create mode 100644 Pmw/Pmw_1_2/lib/PmwOptionMenu.py create mode 100644 Pmw/Pmw_1_2/lib/PmwPanedWidget.py create mode 100644 Pmw/Pmw_1_2/lib/PmwPromptDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwRadioSelect.py create mode 100644 Pmw/Pmw_1_2/lib/PmwScrolledCanvas.py create mode 100644 Pmw/Pmw_1_2/lib/PmwScrolledField.py create mode 100644 Pmw/Pmw_1_2/lib/PmwScrolledFrame.py create mode 100644 Pmw/Pmw_1_2/lib/PmwScrolledListBox.py create mode 100644 Pmw/Pmw_1_2/lib/PmwScrolledText.py create mode 100644 Pmw/Pmw_1_2/lib/PmwSelectionDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwTextDialog.py create mode 100644 Pmw/Pmw_1_2/lib/PmwTimeCounter.py create mode 100644 Pmw/Pmw_1_2/lib/PmwTimeFuncs.py create mode 100644 Pmw/Pmw_1_2/lib/__init__.py create mode 100644 Pmw/Pmw_1_2/tests/AboutDialog_test.py create mode 100755 Pmw/Pmw_1_2/tests/All.py create mode 100644 Pmw/Pmw_1_2/tests/Blt_test.py create mode 100644 Pmw/Pmw_1_2/tests/ButtonBox_test.py create mode 100644 Pmw/Pmw_1_2/tests/Colors_test.py create mode 100644 Pmw/Pmw_1_2/tests/ComboBox_test.py create mode 100644 Pmw/Pmw_1_2/tests/CounterDialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/Counter_test.py create mode 100644 Pmw/Pmw_1_2/tests/Dialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/EntryField_test.py create mode 100644 Pmw/Pmw_1_2/tests/LabeledWidget_test.py create mode 100755 Pmw/Pmw_1_2/tests/ManualTests.py create mode 100644 Pmw/Pmw_1_2/tests/MegaWidget_test.py create mode 100644 Pmw/Pmw_1_2/tests/MessageDialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/NoteBook_test.py create mode 100644 Pmw/Pmw_1_2/tests/OptionMenu_test.py create mode 100644 Pmw/Pmw_1_2/tests/Options_test.py create mode 100644 Pmw/Pmw_1_2/tests/PanedWidget_test.py create mode 100644 Pmw/Pmw_1_2/tests/PmwBase_test.py create mode 100644 Pmw/Pmw_1_2/tests/PromptDialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/RadioSelect_test.py create mode 100644 Pmw/Pmw_1_2/tests/ScrolledCanvas_test.py create mode 100644 Pmw/Pmw_1_2/tests/ScrolledField_test.py create mode 100644 Pmw/Pmw_1_2/tests/ScrolledFrame_test.py create mode 100644 Pmw/Pmw_1_2/tests/ScrolledListBox_test.py create mode 100644 Pmw/Pmw_1_2/tests/ScrolledText_test.py create mode 100644 Pmw/Pmw_1_2/tests/SelectionDialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/Test.py create mode 100644 Pmw/Pmw_1_2/tests/TestVersion.py create mode 100644 Pmw/Pmw_1_2/tests/TextDialog_test.py create mode 100644 Pmw/Pmw_1_2/tests/Tkinter_test.py create mode 100644 Pmw/Pmw_1_2/tests/earthris.gif create mode 100644 Pmw/Pmw_1_2/tests/flagup.bmp create mode 100644 Pmw/README create mode 100644 Pmw/__init__.py 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. +# +# 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 types +import Tkinter +import Pmw + + +class _Branching: + def __init__(self): + # List of branch names + self._nodeNames = [] + + # Map from branch name to branch info + # branch Either _LeafNode or _BranchNode widget of the branch + # nodetype Either 'TreeNode' or 'LeafNode' + self._nodeAttrs = {} + + def addbranch(self, branchName = None, **kw): + kw['indent'] = self['indent'] + return apply(self._insertnode, + ('tree', branchName, len(self._nodeNames), + self._treeRoot), + kw) + + def addleaf(self, leafName = None, **kw): + return apply(self._insertnode, + ('leaf', leafName, len(self._nodeNames), + self._treeRoot), + kw) + + def insertbranch(self, branchName = None, before = 0, **kw): + kw['indent'] = self['indent'] + return apply(self._insertnode, + ('tree', branchName, before, self._treeRoot), + kw) + + def insertleaf(self, leafName = None, before = 0, **kw): + return apply(self._insertnode, + ('leaf', leafName, before, self._treeRoot), + kw) + + def _insertnode(self, type, nodeName, before, treeRoot, **kw): + if 'selectbackground' not in kw.keys(): + kw['selectbackground'] = self['selectbackground'] + + if 'selectforeground' not in kw.keys(): + kw['selectforeground'] = self['selectforeground'] + + if 'background' not in kw.keys(): + kw['background'] = self['background'] + + if 'foreground' not in kw.keys(): + kw['foreground'] = self['foreground'] + + if nodeName == None: + nodeName = self._nodeName + ".%d" % (len(self._nodeNames) + 1) + + if self._nodeAttrs.has_key(nodeName): + msg = 'Node "%s" already exists.' % nodeName + raise ValueError, msg + + # Do this early to catch bad spec before creating any items. + beforeIndex = self.index(before, 1) + attributes = {} + + last = (beforeIndex == len(self._nodeNames)) + if last and len(self._nodeNames) > 0: + # set the previous node to not last + self._nodeAttrs[self._nodeNames[-1]]['branch']._setlast(0) + + if(type == 'tree'): + node = apply(self.createcomponent, ('branch%d'%len(self._nodeNames), + (), None, + _BranchNode, + self._branchFrame, + nodeName, + treeRoot, + self, + last, + ), kw) + attributes['nodetype'] = 'TreeNode' + else: + node = apply(self.createcomponent, ('leaf%d'%len(self._nodeNames), + (), None, + _LeafNode, + self._branchFrame, + nodeName, + treeRoot, + self, + last, + ), kw) + attributes['nodetype'] = 'LeafNode' + + if len(self._nodeNames) == beforeIndex: + node.pack(anchor='w') + else: + bname = self._nodeNames[beforeIndex] + battrs = self._nodeAttrs[bname] + node.pack(anchor='w', before=battrs['branch']) + + attributes['branch'] = node + + self._nodeAttrs[nodeName] = attributes + self._nodeNames.insert(beforeIndex, nodeName) + self._sizechange() + return node + + def delete(self, *nodes): + curSel = self._treeRoot.curselection()[0] + for node in nodes: + index = self.index(node) + name = self._nodeNames.pop(index) + dnode = self._nodeAttrs[name]['branch'] + del self._nodeAttrs[name] + if dnode == curSel: + self._treeRoot._unhightlightnode(dnode) + dnode.destroy() + self._sizechange() + + def destroy(self): + for node in len(self._nodeNames): + self.delete(node) + Pmw.MegaWidget.destroy(self) + + def index(self, index, forInsert = 0): + if isinstance(index, _LeafNode): + index = index._nodeName + listLength = len(self._nodeNames) + if type(index) == types.IntType: + if forInsert and index <= listLength: + return index + elif not forInsert and index < listLength: + return index + else: + raise ValueError, 'index "%s" is out of range' % index + elif type(index) == types.StringType: + if index in self._nodeNames: + return self._nodeNames.index(index) + raise ValueError, 'bad branch or leaf name: %s' % index + elif index is Pmw.END: + if forInsert: + return listLength + elif listLength > 0: + return listLength - 1 + else: + raise ValueError, 'TreeNode has no branches' + #elif index is Pmw.SELECT: + # if listLength == 0: + # raise ValueError, 'TreeNode has no branches' + # return self._pageNames.index(self.getcurselection()) + else: + validValues = 'a name, a number, Pmw.END, Pmw.SELECT, or a reference to a TreeBrowser Leaf or Branch' + raise ValueError, \ + 'bad index "%s": must be %s' % (index, validValues) + + def getnodenames(self): + return self._nodeNames + + def getnode(self, node): + nodeName = self._nodeNames[self.index(node)] + return self._nodeAttrs[nodeName]['branch'] + + +class _LeafNode(Pmw.MegaWidget): + + def __init__(self, parent, nodeName, treeRoot, parentnode, last = 1, **kw): + colors = Pmw.Color.getdefaultpalette(parent) + + self._nodeName = nodeName + self._treeRoot = treeRoot + self._parentNode = parentnode + + self._last = last + # Define the megawidget options. + INITOPT = Pmw.INITOPT + optiondefs = ( + ('selectbackground', colors['selectBackground'], INITOPT), + ('selectforeground', colors['selectForeground'], INITOPT), + ('background', colors['background'], INITOPT), + ('foreground', colors['foreground'], INITOPT), + ('selectcommand', None, None), + ('deselectcommand', None, None), + ('labelpos', 'e', INITOPT), + ('labelmargin', 0, INITOPT), + ('label', None, None), + ) + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaWidget.__init__(self, parent) + + # Create the components + interior = self._hull + + + labelpos = self['labelpos'] + + if self['label'] == None: + self._labelWidget = self.createcomponent('labelwidget', + (), None, + Pmw.LabeledWidget, + (interior,), + #background = self['background'], + #foreground = self['foreground'], + ) + else: + self._labelWidget = self.createcomponent('labelwidget', + (), None, + Pmw.LabeledWidget, + (interior,), + label_background = self['background'], + label_foreground = self['foreground'], + labelpos = labelpos, + labelmargin = self['labelmargin'], + label_text = self['label'], + ) + self._labelWidget.component('label').bind('', + self._selectevent) + + self._labelWidget.grid(column = 1, row = 0, sticky = 'w') + + self._labelWidget.update() + + self._labelheight = self._labelWidget.winfo_height() + + self._lineCanvas = self.createcomponent('linecanvas', + (), None, + Tkinter.Canvas, + (interior,), + width = self._labelheight, + height = self._labelheight, + ) + self._lineCanvas.grid( column = 0, row = 0, sticky = 'news') + self._lineCanvas.update() + + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + + self._lineCanvas.create_line(cw/2, ch/2, cw, ch/2, tag='hline') + if last: + self._lineCanvas.create_line(cw/2, 0, cw/2, ch/2, tag='vline') + else: + self._lineCanvas.create_line(cw/2, 0, cw/2, ch, tag='vline') + + # Check keywords and initialise options. + self.initialiseoptions() + + + def interior(self): + return self._labelWidget.interior() + + def select(self): + self._highlight() + + def getname(self): + return self._nodeName + + def getlabel(self): + return self['label'] + + def _selectevent(self, event): + self._highlight() + + def _highlight(self): + self._treeRoot._highlightnode(self) + #self._subHull.configure(background = self._selectbg, relief = 'raised') + if self['label'] != None: + self._labelWidget.configure(label_background = self['selectbackground']) + self._labelWidget.configure(label_foreground = self['selectforeground']) + #self._viewButton.configure(background = self._selectbg) + cmd = self['selectcommand'] + if callable(cmd): + cmd(self) + + def _unhighlight(self): + #self._subHull.configure(background = self._bg, relief = 'flat') + if self['label'] != None: + self._labelWidget.configure(label_background = self['background']) + self._labelWidget.configure(label_foreground = self['foreground']) + #self._viewButton.configure(background = self._bg) + cmd = self['deselectcommand'] + if callable(cmd): + cmd(self) + + def _setlast(self, last): + self._last = last + + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + + if last: + self._lineCanvas.create_line(cw/2, 0, cw/2, ch/2, tag='vline') + else: + self._lineCanvas.create_line(cw/2, 0, cw/2, ch, tag='vline') + + +class _BranchNode(_LeafNode, _Branching): #Pmw.MegaWidget): + + def __init__(self, parent, nodeName, treeRoot, parentnode, last = 1, **kw): + # Define the megawidget options. + INITOPT = Pmw.INITOPT + optiondefs = ( + ('view', 'collapsed', None), + ('expandcommand', None, None), + ('collapsecommand', None, None), + ('indent', 0, INITOPT) + ) + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + apply(_LeafNode.__init__, + (self, parent, nodeName, treeRoot, parentnode, last), + kw) + _Branching.__init__(self) + + # Create the components + interior = self._hull + + # Create the expand/collapse button + self._viewButton = self.createcomponent('viewbutton', (), None, + Tkinter.Canvas, + (interior,), + background = self['background'], + width = self._labelheight - 4, + height = self._labelheight - 4, + borderwidth = 2, + relief = 'raised') + + self._viewButton.grid(column = 0, row = 0, sticky='se') + self._viewButton.bind('', self._showbuttonpress) + self._viewButton.bind('', self._toggleview) + + # The label widget is already created by the base class, however + # we do need to make some slight modifications. + if self['label'] != None: + self._labelWidget.component('label').bind('', + self._toggleview) + self._labelWidget.grid(column=1, row=0, columnspan = 3, sticky='sw') + + # A line canvas is already created for us, we just need to make + # some slight modifications + self._lineCanvas.delete('hline') + self._lineCanvas.grid_forget() + + + # Set the minsize of column 1 to control additional branch frame indentation + self.grid_columnconfigure(1, minsize = self['indent']) + + # Create the branch frame that will contain all the branch/leaf nodes + self._branchFrame = self.createcomponent('frame', (), None, + Tkinter.Frame, (interior,), + #borderwidth=2, + #relief='ridge', + ) + self.grid_columnconfigure(2,minsize=0, weight=1) + #self.grid_rowconfigure(0,minsize=0) + + if(self['view'] == 'expanded'): + Pmw.drawarrow(self._viewButton, + self['foreground'], + 'down', 'arrow') + self._branchFrame.grid(column = 2, row = 1, sticky='nw') + if not self._last: + self._branchFrame.update() + bh = self._branchFrame.winfo_height() + self._lineCanvas.configure(height = bh) + self._lineCanvas.grid(column = 0, row = 1, sticky='news') + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + #self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag = 'vline') + self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) + else: + Pmw.drawarrow(self._viewButton, + self['foreground'], + 'right', 'arrow') + self._viewButton.configure(relief = 'raised') + + + # Check keywords and initialise options. + self.initialiseoptions() + + + + def _showbuttonpress(self, event): + self._viewButton.configure(relief = 'sunken') + + def _toggleview(self, event): + self._viewButton.configure(relief = 'sunken') + self.select() + if(self['view'] == 'expanded'): + self.collapsetree() + else: + self.expandtree() + self._viewButton.configure(relief = 'raised') + + def expandtree(self): + if(self['view'] == 'collapsed'): + cmd = self['expandcommand'] + if cmd is not None: + cmd(self) + self['view'] = 'expanded' + Pmw.drawarrow(self._viewButton, + self['foreground'], + 'down', 'arrow') + self._branchFrame.grid(column = 2, row = 1, sticky='nw') + + if not self._last: + self._branchFrame.update() + bh = self._branchFrame.winfo_height() + self._lineCanvas.configure(height = bh) + self._lineCanvas.grid(column = 0, row = 1, sticky='news') + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + #self._lineCanvas.create_line( cw/2, 1, cw/2, ch, tag = 'vline') + self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) + self._parentNode._sizechange() + + def collapsetree(self): + if(self['view'] == 'expanded'): + cmd = self['collapsecommand'] + if cmd is not None: + cmd(self) + self['view'] = 'collapsed' + Pmw.drawarrow(self._viewButton, + self['foreground'], + 'right', 'arrow') + self._branchFrame.grid_forget() + if not self._last: + #self._lineCanvas.delete('vline') + self._lineCanvas.grid_forget() + self._parentNode._sizechange() + + def _setlast(self, last): + self._last = last + if self['view'] == 'expanded': + self._branchFrame.update() + bh = self._branchFrame.winfo_height() + self._lineCanvas.configure(height = bh) + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + self._lineCanvas.delete('vline') + if not last: + self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag='vline') + + + def _sizechange(self): + if not self._last and self['view'] == 'expanded': + self._branchFrame.update() + bh = self._branchFrame.winfo_height() + self._lineCanvas.configure(height = bh) + if self._lineCanvas.coords('vline')[3] < bh: + cw = int(self._lineCanvas['width']) + ch = int(self._lineCanvas['height']) + #self._lineCanvas.delete('vline') + #self._lineCanvas.create_line(cw/2, 1, cw/2, ch, tag='vline') + self._lineCanvas.coords('vline', cw/2, 1, cw/2, ch) + self._parentNode._sizechange() + +class TreeBrowser(Pmw.MegaWidget, _Branching): + + def __init__(self, parent = None, nodeName = '0', **kw): + colors = Pmw.Color.getdefaultpalette(parent) + + # Define the megawidget options. + INITOPT = Pmw.INITOPT + optiondefs = ( + ('indent', 0, INITOPT), + ('selectbackground', colors['selectBackground'], INITOPT), + ('selectforeground', colors['selectForeground'], INITOPT), + ('background', colors['background'], INITOPT), + ('foreground', colors['foreground'], INITOPT), + #('selectrelief', 'raised', INITOPT), + ) + + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaWidget.__init__(self, parent) + _Branching.__init__(self) + + + # Create the components + interior = self._hull + + browserFrame = self.createcomponent('frame', (), None, + Pmw.ScrolledFrame, + (interior,), + ) + + browserFrame.pack(expand = 1, fill='both') + + self._branchFrame = browserFrame.interior() + + self._highlightedNode = None + self._treeRoot = self + self._nodeName = nodeName + # Check keywords and initialise options. + self.initialiseoptions() + + def _highlightnode(self, newNode): + if self._highlightedNode != newNode: + if self._highlightedNode != None: + self._highlightedNode._unhighlight() + self._highlightedNode = newNode + + def _unhighlightnode(self): + if self._highlightedNode != None: + self._highlightedNode._unhighlight() + self._highlightedNode = None + + def curselection(self): + retVal = None + if self._highlightedNode != None: + retVal = (self._highlightedNode, + self._highlightedNode._nodeName, + self._highlightedNode['label']) + return retVal + + def getname(self): + return self._nodeName + + # The top-level TreeBrowser widget only shows nodes in an expanded view + # but still provides collapsetree() and expandtree() methods so that users + # don't have to special case the top-level node + + def collapsetree(self): + return + + def expandtree(self): + return + + def _sizechange(self): + return + +if __name__ == '__main__': + + rootWin = Tkinter.Tk() + + Pmw.initialise() + + rootWin.title('TreeBrowser Demo') + + # Create the hierarchical tree browser widget + treeBrowser = TreeBrowser(rootWin, + #selectbackground = "darkgreen", + #selectforeground = 'lightgreen', + #background = 'green', + #indent = 10, + ) + + + def printselected(node): + selection = treeBrowser.curselection() + if selection != None: + print "Selected node name:", selection[1], " label:", selection[2] + + + def printdeselected(node): + selection = treeBrowser.curselection() + if selection != None: + print "Deselected node name:", selection[1], " label:", selection[2] + + def printexpanded(node): + print "Expanded node name:", node.getname(), " label:", node.getlabel() + + def printcollapsed(node): + print "Collapsed node name:", node.getname(), " label:", node.getlabel() + + + + for i in range(3): + # Add a tree node to the top level + treeNodeLevel1 = treeBrowser.addbranch(label = 'TreeNode %d'%i, + selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + ) + for j in range(3): + # Add a tree node to the second level + treeNodeLevel2 = treeNodeLevel1.addbranch(label = 'TreeNode %d.%d'%(i,j), + #selectforeground = 'yellow', + selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + ) + if i == 0 and j == 1: + dynamicTreeRootNode = treeNodeLevel1 + dynamicTreePosNode = treeNodeLevel2 + + for item in range((i+1)*(j+1)): + # Add a leaf node to the third level + leaf = treeNodeLevel2.addleaf(label = "Item %c"%(item+65), + #selectbackground = 'blue', + selectcommand = printselected, + deselectcommand = printdeselected) + for item in range(i+1): + # Add a leaf node to the top level + leaf = treeNodeLevel1.addleaf(label = "Item %c"%(item+65), + selectcommand = printselected, + deselectcommand = printdeselected) + + + treeNodeLevel1 = treeBrowser.addbranch(label = 'Check Button Label', + selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + ) + checkButton = Tkinter.Checkbutton(treeNodeLevel1.interior(), + text = 'Da Check Button', + relief = 'ridge', + command = treeNodeLevel1.select) + checkButton.pack() + + treeNodeLevel1.addleaf(label = 'Labeled Leaf', + selectcommand = printselected, + deselectcommand = printdeselected) + leaf = treeNodeLevel1.addleaf(label = 'Labeled Leaf w/ Checkbutton', + selectcommand = printselected, + deselectcommand = printdeselected) + checkButton = Tkinter.Checkbutton(leaf.interior(), + text = 'Da Check Button', + relief = 'ridge', + command = leaf.select) + checkButton.pack() + + + treeNodeLevel1 = treeBrowser.addbranch(selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + ) + checkButton = Tkinter.Checkbutton(treeNodeLevel1.interior(), + text = 'Check Button with no label', + relief = 'ridge', + command = treeNodeLevel1.select) + checkButton.pack() + + treeNodeLevel1 = treeBrowser.addbranch(label = 'Label', + selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + ) + + # setup dynamic tree node insertion and removal + class dynTree: + def __init__(self): + self.dyn = Tkinter.IntVar() + self.dtree = None + + self.dLeaf = treeBrowser.addleaf(selectcommand = self.dynSelected, + deselectcommand = self.dynDeselected) + + self.dCheckButton = Tkinter.Checkbutton(self.dLeaf.interior(), + text = 'Enable Dynamic Tree', + variable = self.dyn, + command = self.ChkBtnHandler) + self.dCheckButton.pack() + + + def dynSelected(self, node): + self.dCheckButton.configure(background = self.dLeaf.configure('selectbackground')[4]) + printselected(node) + + def dynDeselected(self, node): + self.dCheckButton.configure(background = self.dLeaf.configure('background')[4]) + printdeselected(node) + + def ChkBtnHandler(self): + self.dLeaf.select() + if self.dyn.get() == 1: + self.dtree = dynamicTreeRootNode.insertbranch(label = 'Dynamic Tree Node', + selectcommand = printselected, + deselectcommand = printdeselected, + expandcommand = printexpanded, + collapsecommand = printcollapsed, + before = dynamicTreePosNode) + self.dtree.addleaf(label = 'Dynamic Leaf 1', + selectcommand = printselected, + deselectcommand = printdeselected) + self.dtree.addleaf(label = 'Dynamic Leaf 2', + selectcommand = printselected, + deselectcommand = printdeselected) + else: + if self.dtree != None: + dynamicTreeRootNode.delete(self.dtree) + self.dtree = None + + + foo = dynTree() + + + treeBrowser.pack(expand = 1, fill='both') + + exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit) + exitButton.pack() + + rootWin.mainloop() diff --git a/Pmw/Pmw_1_2/demos/AboutDialog.py b/Pmw/Pmw_1_2/demos/AboutDialog.py new file mode 100644 index 00000000..1760befe --- /dev/null +++ b/Pmw/Pmw_1_2/demos/AboutDialog.py @@ -0,0 +1,43 @@ +title = 'Pmw.AboutDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/All.py b/Pmw/Pmw_1_2/demos/All.py new file mode 100755 index 00000000..f94955cf --- /dev/null +++ b/Pmw/Pmw_1_2/demos/All.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python + +# ------------------------------------------------------------------ +# Display a splash screen as quickly as possible (before importing +# modules and initialising Pmw). + +import Tkinter +root = Tkinter.Tk(className = 'Demo') +root.withdraw() + +splash = Tkinter.Toplevel() +splash.withdraw() +splash.title('Welcome to the Pmw demos') +text = Tkinter.Label(splash, + font=('Helvetica', 16, 'bold'), + relief = 'raised', + borderwidth = 2, + padx=50, pady=50, + text = + 'Welcome to the Pmw megawidgets demo.\n' + '\n' + 'In a moment the main window will appear.\n' + 'Please enjoy yourself while you wait.\n' + 'You may be interested to know that splash screens\n' + '(as this window is called) were first devised to draw\n' + 'attention away from the fact the certain applications\n' + 'are slow to start. They are normally flashier and more\n' + 'entertaining than this one. This is a budget model.' +) +text.pack(fill = 'both', expand = 1) +splash.update_idletasks() + +width = splash.winfo_reqwidth() +height = splash.winfo_reqheight() +x = (root.winfo_screenwidth() - width) / 2 - root.winfo_vrootx() +y = (root.winfo_screenheight() - height) / 3 - root.winfo_vrooty() +if x < 0: + x = 0 +if y < 0: + y = 0 +geometry = '%dx%d+%d+%d' % (width, height, x, y) + +splash.geometry(geometry) +splash.update_idletasks() +splash.deiconify() +root.update() + +# ------------------------------------------------------------------ + +# Now crank up the application windows. + +import imp +import os +import re +import string +import sys +import types +import Tkinter +import DemoVersion +import Args + +# Find where the other scripts are, so they can be listed. +if __name__ == '__main__': + script_name = sys.argv[0] +else: + script_name = imp.find_module('DemoVersion')[1] + +script_name = os.path.normpath(script_name) +script_name = DemoVersion.expandLinks(script_name) +script_dir = os.path.dirname(script_name) +script_dir = DemoVersion.expandLinks(script_dir) + +# Add the '../../..' directory to the path. +package_dir = os.path.dirname(script_dir) +package_dir = DemoVersion.expandLinks(package_dir) +package_dir = os.path.dirname(package_dir) +package_dir = DemoVersion.expandLinks(package_dir) +package_dir = os.path.dirname(package_dir) +package_dir = DemoVersion.expandLinks(package_dir) +sys.path[:0] = [package_dir] + +# Import Pmw after modifying sys.path (it may not be in the default path). +import Pmw +DemoVersion.setPmwVersion() + +class Demo(Pmw.MegaWidget): + + def __init__(self, parent=None, **kw): + + # Define the megawidget options. + optiondefs = () + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaWidget.__init__(self, parent) + + # Create the contents. + top = self.interior() + + panes = Pmw.PanedWidget(top, orient = 'horizontal') + panes.pack(fill = 'both', expand = 1) + + panes.add('widgetlist') + self._widgetlist = Pmw.ScrolledListBox(panes.pane('widgetlist'), + selectioncommand = Pmw.busycallback(self.startDemo), + label_text = 'Select a widget:', + labelpos = 'nw', + vscrollmode = 'dynamic', + hscrollmode = 'none', + listbox_exportselection = 0) + self._widgetlist.pack(fill = 'both', expand = 1, padx = 8) + + panes.add('info') + self._status = Tkinter.Label(panes.pane('info')) + self._status.pack(padx = 8, anchor = 'w') + + self._example = Tkinter.Frame(panes.pane('info'), + borderwidth = 2, + relief = 'sunken', + background = 'white') + self._example.pack(fill = 'both', expand = 1, padx = 8) + + self.buttonBox = Pmw.ButtonBox(top) + self.buttonBox.pack(fill = 'x') + + # Add the buttons and make them all the same width. + self._traceText = 'Trace tk calls' + self._stopTraceText = 'Stop trace' + self.buttonBox.add('Trace', text = self._traceText, + command = self.trace) + self.buttonBox.add('Code', text = 'Show code', command = self.showCode) + self.buttonBox.add('Exit', text = 'Exit', command = sys.exit) + self.buttonBox.alignbuttons() + + # Create the window to display the python code. + self.codeWindow = Pmw.TextDialog(parent, + title = 'Python source', + buttons = ('Dismiss',), + scrolledtext_labelpos = 'n', + label_text = 'Source') + self.codeWindow.withdraw() + self.codeWindow.insert('end', '') + + self.demoName = None + self._loadDemos() + + # Check keywords and initialise options. + self.initialiseoptions() + + def startDemo(self): + # Import the selected module and create and instance of the module's + # Demo class. + + sels = self._widgetlist.getcurselection() + if len(sels) == 0: + print 'No demonstrations to display' + return + demoName = sels[0] + + # Ignore if this if it is a sub title. + if demoName[0] != ' ': + self._widgetlist.bell() + return + + # Strip the leading two spaces. + demoName = demoName[2:] + + # Ignore if this demo is already being shown. + if self.demoName == demoName: + return + + self.demoName = demoName + + self.showStatus('Loading ' + demoName) + # Busy cursor + self.update_idletasks() + + for window in self._example.winfo_children(): + window.destroy() + + frame = Tkinter.Frame(self._example) + frame.pack(expand = 1) + exec 'import ' + demoName + # Need to keep a reference to the widget, so that variables, etc + # are not deleted. + self.widget = eval(demoName + '.Demo(frame)') + title = eval(demoName + '.title') + self.showStatus(title) + + if self.codeWindow.state() == 'normal': + self.insertCode() + + def showStatus(self, text): + self._status.configure(text = text) + + def showCode(self): + if self.codeWindow.state() != 'normal': + if self.demoName is None: + print 'No demonstration selected' + return + self.insertCode() + + self.codeWindow.show() + + def insertCode(self): + self.codeWindow.clear() + fileName = os.path.join(script_dir, self.demoName + '.py') + self.codeWindow.importfile(fileName) + self.codeWindow.configure(label_text = self.demoName + ' source') + + def trace(self): + text = self.buttonBox.component('Trace').cget('text') + if text == self._traceText: + self.buttonBox.configure(Trace_text = self._stopTraceText) + Pmw.tracetk(root, 1) + self.showStatus('Trace will appear on standard output') + else: + self.buttonBox.configure(Trace_text = self._traceText) + Pmw.tracetk(root, 0) + self.showStatus('Tk call tracing stopped') + + def _loadDemos(self): + files = os.listdir(script_dir) + files.sort() + megawidgets = [] + others = [] + for file in files: + if re.search('.py$', file) is not None and \ + file not in ['All.py', 'DemoVersion.py', 'Args.py']: + demoName = file[:-3] + index = string.find(demoName, '_') + if index < 0: + testattr = demoName + else: + testattr = demoName[:index] + if hasattr(Pmw, testattr): + megawidgets.append(demoName) + else: + others.append(demoName) + + self._widgetlist.insert('end', 'Megawidget demos:') + for name in megawidgets: + self._widgetlist.insert('end', ' ' + name) + self._widgetlist.insert('end', 'Other demos:') + for name in others: + self._widgetlist.insert('end', ' ' + name) + self._widgetlist.select_set(1) + +class StdOut: + def __init__(self, displayCommand): + self.displayCommand = displayCommand + self.text = '\n' + + def write(self, text): + if self.text[-1] == '\n': + self.text = text + else: + self.text = self.text + text + if self.text[-1] == '\n': + text = self.text[:-1] + else: + text = self.text + self.displayCommand(text) + +if os.name == 'nt': + defaultFontSize = 16 +else: + defaultFontSize = 12 + +commandLineArgSpecs = ( + ('fontscheme', 0, 'scheme', 'fonts to use [eg pmw2] (Tk defaults)'), + ('fontsize', 0, 'num', 'size of fonts to use with fontscheme', defaultFontSize), + ('stdout', 0, Args.Bool, 'print messages rather than display in label'), +) + +program = 'All.py' +msg = Args.parseArgs(program, sys.argv, commandLineArgSpecs, 0) +if msg is not None: + print msg + sys.exit() + +size = Args.get('fontsize') +fontScheme = Args.get('fontscheme') +Pmw.initialise(root, size = size, fontScheme = fontScheme, useTkOptionDb = 1) + +root.title('Pmw ' + Pmw.version() + ' megawidget demonstration') +if size < 18: + geometry = '800x550' +else: + geometry = '1000x700' +root.geometry(geometry) + +demo = Demo(root) +demo.pack(fill = 'both', expand = 1) +demo.focus() + +# Redirect standard output from demos to status line (unless -stdout +# option given on command line). +if not Args.get('stdout'): + sys.stdout = StdOut(demo.showStatus) + +# Start the first demo. +demo.startDemo() + +# Get rid of the splash screen +root.deiconify() +root.update() +splash.destroy() + +root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Args.py b/Pmw/Pmw_1_2/demos/Args.py new file mode 100644 index 00000000..1bbedf91 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Args.py @@ -0,0 +1,191 @@ +"""Handle command line arguments. + +This module contains functions to parse and access the arguments given +to the program on the command line. +""" + +import types +import string +import sys + +# Symbolic constants for the indexes into an argument specifier tuple. +NAME = 0 +MANDATORY = 1 +TYPE = 2 +HELP = 3 +DEFAULT = 4 +SPEC_LENGTH = 5 + +Bool = [] + +helpSpec = ( + ('help', 0, Bool, 'print help and exit'), +) + +def parseArgs(title, argv, argSpecs, filesOK): + """Parse and check command line arguments. + + Scan the command line arguments in *argv* according to the argument + specifier *argSpecs*. Return **None** if there are no errors in + the arguments, otherwise return an error string describing the error. + + This function must be called to initialise this module. + + title -- The name of the program. This is used when returning + error messages or help text. + + argv -- A sequence containing the arguments given to the program. + Normally **sys.argv**. + + argSpecs -- A sequence of argument specifiers. Each specifier describes + a valid command line argument and consists of 4 or 5 items: + + - The argument name (without a leading minus sign **-**). + + - A boolean value, true if the argument is mandatory. + + - This should be **Args.Bool** if the argument has no option. + Otherwise it should be a string describing the option + required for this argument. This is used when printing help. + + - A short string describing the argument. + + - The default value of the argument. This should only be used + for non-mandatory arguments expecting an option. + + For example: + ( + ('foreground', 0, 'colour', 'colour of text', 'black'), + ('geometry', 0, 'spec', 'geometry of initial window'), + ('server', 1, 'ompserver', 'ompserver to connect to'), + ('silent', 0, Args.Bool, 'do not sound bell'), + ) + """ + + global programName + global _fileList + + errMsg = title + ' command line error: ' + programName = argv[0]; + + argSpecs = helpSpec + argSpecs + argSpecDic = {} + for spec in argSpecs: + arg = spec[NAME] + argSpecDic[arg] = spec + if len(spec) >= SPEC_LENGTH: + set(arg, spec[DEFAULT]) + elif spec[TYPE] is Bool: + set(arg, 0) + else: + set(arg, None) + + knownKeys = argSpecDic.keys() + + i = 1 + _fileList = [] + argc = len(argv) + while i < argc: + arg = argv[i] + key = arg[1:] + if key in knownKeys: + spec = argSpecDic[key] + if spec[TYPE] is Bool: + set(key, 1) + else: + i = i + 1 + if i >= argc: + return errMsg + 'missing argument to \'' + arg + '\' option.' + value = argv[i] + if len(spec) >= SPEC_LENGTH: + try: + if type(spec[DEFAULT]) == types.IntType: + typeStr = 'integer' + value = string.atoi(value) + elif type(spec[DEFAULT]) == types.FloatType: + typeStr = 'float' + value = string.atof(value) + except: + sys.exc_traceback = None # Clean up object references + return errMsg + 'cannot convert string \'' + value + \ + '\' to ' + typeStr + ' for option \'-' + key + '\'.' + set(key, value) + else: + _fileList.append(arg) + i = i + 1 + + if get('help'): + return _helpString(title, argSpecs) + + if not filesOK and len(_fileList) > 0: + if len(_fileList) == 1: + return errMsg + 'unknown option \'' + str(_fileList[0]) + '\'.' + else: + return errMsg + 'unknown options ' + str(_fileList) + '.' + + + _missing = [] + for spec in argSpecs: + if spec[MANDATORY] and get(spec[NAME]) is None: + _missing.append(spec[NAME]) + if len(_missing) == 1: + return errMsg + 'required argument \'-' + \ + str(_missing[0]) + '\' is missing.' + elif len(_missing) > 1: + return errMsg + 'required arguments ' + \ + str(map(lambda s: '-' + s, _missing)) + ' are missing.' + + return None + +def fileList(): + return _fileList + +def _helpString(title, argSpecs): + max = 0 + for spec in argSpecs: + if spec[TYPE] is Bool: + width = len(spec[NAME]) + 1 + else: + width = len(spec[NAME]) + 4 + len(spec[TYPE]) + if width > max: + max = width + + rtn = title + ' command line arguments:' + format = '\n %-' + str(max) + 's %s' + for mandatory in (1, 0): + needHeader = 1 + for spec in argSpecs: + if mandatory and spec[MANDATORY] or not mandatory and not spec[MANDATORY]: + if needHeader: + if mandatory: + rtn = rtn + '\n Mandatory arguments:' + else: + rtn = rtn + '\n Optional arguments (defaults in parentheses):' + needHeader = 0 + if spec[TYPE] is Bool: + arg = '-%s' % spec[NAME] + else: + arg = '-%s <%s>' % (spec[NAME], spec[TYPE]) + if len(spec) >= SPEC_LENGTH: + if type(spec[DEFAULT]) == types.StringType: + definition = spec[HELP] + ' (' + spec[DEFAULT] + ')' + else: + definition = spec[HELP] + ' (' + str(spec[DEFAULT]) + ')' + else: + definition = spec[HELP] + rtn = rtn + format % (arg, definition) + + return rtn + +def exists(key): + return configDict.has_key(key) + +def get(key): + return configDict[key] + +def set(key, value): + global configDict + + configDict[key] = value + +configDict = {} diff --git a/Pmw/Pmw_1_2/demos/Balloon.py b/Pmw/Pmw_1_2/demos/Balloon.py new file mode 100644 index 00000000..71788f64 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Balloon.py @@ -0,0 +1,185 @@ +title = 'Pmw.Balloon demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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, '', 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', '', 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') + + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root, 12, fontScheme = 'default') + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/BltGraph.py b/Pmw/Pmw_1_2/demos/BltGraph.py new file mode 100644 index 00000000..a71c5c34 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/BltGraph.py @@ -0,0 +1,241 @@ +title = 'Blt Graph demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +# Simple random number generator. +rand = 12345 +def random(): + global rand + rand = (rand * 125) % 2796203 + return rand + +class GraphDemo(Pmw.MegaToplevel): + + def __init__(self, parent=None, **kw): + + # Define the megawidget options. + optiondefs = ( + ('size', 10, Pmw.INITOPT), + ) + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaToplevel.__init__(self, parent) + + # Create the graph. + self.createWidgets() + + # Check keywords and initialise options. + self.initialiseoptions() + + def createWidgets(self): + # Create vectors for use as x and y data points. + self._numElements = 7 + self._vectorSize = self['size'] + self._vector_x = Pmw.Blt.Vector() + self._vector_y = [] + for y in range(self._numElements): + self._vector_y.append(Pmw.Blt.Vector()) + for index in range(self._vectorSize): + self._vector_x.append(index) + for y in range(self._numElements): + self._vector_y[y].append(random() % 100) + + interior = self.interior() + + controlFrame = Tkinter.Frame(interior) + controlFrame.pack(side = 'bottom', fill = 'x', expand = 0) + + # Create an option menu for the kind of elements to create. + elementtype = Pmw.OptionMenu(controlFrame, + labelpos = 'nw', + label_text = 'Element type', + items = ['bars', 'lines', 'mixed', 'none'], + command = self._setelementtype, + menubutton_width = 8, + ) + elementtype.pack(side = 'left') + + # Create an option menu for the barmode option. + barmode = Pmw.OptionMenu(controlFrame, + labelpos = 'nw', + label_text = 'Bar mode', + items = ['normal', 'stacked', 'aligned', 'overlap'], + command = self._setbarmode, + menubutton_width = 8, + ) + barmode.pack(side = 'left') + + # Create an option menu for the smooth option. + self.smooth = Pmw.OptionMenu(controlFrame, + labelpos = 'nw', + label_text = 'Smooth', + items = ['linear', 'step', 'natural', 'quadratic'], + command = self._setsmooth, + menubutton_width = 9, + ) + self.smooth.pack(side = 'left') + + # Create an option menu to reverse sort the elements. + sortelements = Pmw.OptionMenu(controlFrame, + labelpos = 'nw', + label_text = 'Order', + items = ['normal', 'reverse'], + command = self._setsortelements, + menubutton_width = 8, + ) + sortelements.pack(side = 'left') + + # Create an option menu for the bufferelements option. + bufferelements = Pmw.OptionMenu(controlFrame, + labelpos = 'nw', + label_text = 'Buffering', + items = ['buffered', 'unbuffered'], + command = self._setbufferelements, + menubutton_width = 10, + ) + bufferelements.pack(side = 'left') + + # Create a button to add a point to the vector. + addpoint = Tkinter.Button(controlFrame, text = 'Add point', + command = Pmw.busycallback(self._addpoint)) + addpoint.pack(side = 'left', fill = 'x', expand = 0) + + # Create a button to close the window + close = Tkinter.Button(controlFrame, text = 'Close', + command = Pmw.busycallback(self.destroy)) + close.pack(side = 'left', fill = 'x', expand = 0) + + # Create the graph and its elements. + self._graph = Pmw.Blt.Graph(interior) + self._graph.pack(expand = 1, fill = 'both') + self._graph.yaxis_configure(command=self.yaxisCommand) + elementtype.invoke('mixed') + bufferelements.invoke('buffered') + + def yaxisCommand(self, graph, value): + try: + num = string.atoi(value) + return '%d %3d' % (num * 3, num) + except ValueError: + num = string.atof(value) + return '%g %3g' % (num * 3, num) + + def _setelementtype(self, type): + elements = self._graph.element_names() + apply(self._graph.element_delete, elements) + + if type == 'none': + return + + colorList = Pmw.Color.spectrum(self._numElements) + for elem in range(self._numElements): + if elem == 0: + hue = None + else: + hue = (elem + 1.0) / self._numElements * 6.28318 + foreground = colorList[elem] + background = Pmw.Color.changebrightness(self, foreground, 0.8) + if type == 'mixed': + if elem < self._numElements / 2: + bar = 0 + else: + bar = 1 + elif type == 'bars': + bar = 1 + else: + bar = 0 + if bar: + self._graph.bar_create( + 'var' + str(elem), + xdata=self._vector_x, + ydata=self._vector_y[elem], + foreground = foreground, + background = background) + else: + self._graph.line_create( + 'var' + str(elem), + linewidth = 4, + xdata=self._vector_x, + ydata=self._vector_y[elem], + smooth = self.smooth.getcurselection(), + color = foreground) + + def _setbarmode(self, tag): + self._graph.configure(barmode = tag) + + def _setsmooth(self, tag): + for element in self._graph.element_show(): + if self._graph.element_type(element) == 'line': + self._graph.element_configure(element, smooth = tag) + + def _setbufferelements(self, tag): + self._graph.configure(bufferelements = (tag == 'buffered')) + + def _setsortelements(self, tag): + element_list = list(self._graph.element_show()) + if len(element_list) > 1: + if (tag == 'normal') == (element_list[-1] != 'var0'): + element_list.reverse() + self._graph.element_show(element_list) + + def _addpoint(self): + self._vector_x.append(self._vectorSize) + for y in range(self._numElements): + self._vector_y[y].append(random() % 100) + self._vectorSize = self._vectorSize + 1 + +class Demo: + def __init__(self, parent): + if not Pmw.Blt.haveblt(parent): + message = 'Sorry\nThe BLT package has not been\n' + \ + 'installed on this system.\n' + \ + 'Please install it and try again.' + w = Tkinter.Label(parent, text = message) + w.pack(padx = 8, pady = 8) + return + + message = 'This is a simple demonstration of the\n' + \ + 'BLT graph widget.\n' + \ + 'Select the number of points to display and\n' + \ + 'click on the button to display the graph.' + w = Tkinter.Label(parent, text = message) + w.pack(padx = 8, pady = 8) + + # Create combobox to select number of points to display. + self.combo = Pmw.ComboBox(parent, + scrolledlist_items = ('10', '25', '50', '100', '300'), + entryfield_value = '10') + self.combo.pack(padx = 8, pady = 8) + + # Create button to start blt graph. + start = Tkinter.Button(parent, + text = 'Show BLT graph', + command = Pmw.busycallback(self.showGraphDemo)) + start.pack(padx = 8, pady = 8) + + self.parent = parent + + def showGraphDemo(self): + size = string.atoi(self.combo.get()) + demo = GraphDemo(self.parent, size = size) + demo.focus() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/BltTabset.py b/Pmw/Pmw_1_2/demos/BltTabset.py new file mode 100644 index 00000000..b6cf5894 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/BltTabset.py @@ -0,0 +1,101 @@ +title = 'Blt Tabset demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + if not Pmw.Blt.haveblt(parent): + message = 'Sorry\nThe BLT package has not been\n' + \ + 'installed on this system.\n' + \ + 'Please install it and try again.' + w = Tkinter.Label(parent, text = message) + w.pack(padx = 8, pady = 8) + return + + self.tabset = Pmw.Blt.Tabset(parent, + borderwidth = 0, + highlightthickness = 0, + selectpad = 0, + tiers = 2, + ) + background = self.tabset.cget('background') + self.tabset.configure(selectbackground = background, + tabbackground = background, activebackground = background) + + configurePanel = Tkinter.Frame(self.tabset) + sideMenu = Pmw.OptionMenu (configurePanel, + labelpos = 'w', + label_text = 'Side:', + items = ('top', 'bottom', 'left', 'right'), + menubutton_width = 10, + command = self.changeSide, + ) + sideMenu.pack(anchor = 'w', padx = 10, pady = 10) + + rotateMenu = Pmw.ComboBox(configurePanel, + labelpos = 'w', + label_text = 'Text rotation:', + entryfield_validate = 'integer', + entry_width = 8, + selectioncommand = self.rotateText, + scrolledlist_items = (0, 45, 90, 135, 180, 225, 270, 315), + ) + rotateMenu.pack(side = 'left', padx = 10, pady = 10) + + rotateMenu.selectitem(0) + self.rotateText('0') + + self.appearancePanel = Tkinter.Label(self.tabset) + helpersPanel = Tkinter.Button(self.tabset, + text = 'This is a lot\nof help!') + + self.tabset.insert('end', + 'Appearance', 'Configure', 'Helpers', 'Images') + + self.tabset.tab_configure('Appearance', + command = self.appearance_cb, fill = 'both') + self.tabset.tab_configure('Configure', window = configurePanel) + self.tabset.tab_configure('Images', + command = self.images_cb, fill = 'both') + self.tabset.tab_configure('Helpers', + window = helpersPanel, padx = 100, pady = 150) + + self.tabset.invoke(1) + self.tabset.pack(fill = 'both', expand = 1, padx = 5, pady = 5) + self.tabset.focus() + + def appearance_cb(self): + self.appearancePanel.configure( + text = 'Don\'t judge a book\nby it\'s cover.') + self.tabset.tab_configure('Appearance', window = self.appearancePanel) + + def images_cb(self): + self.appearancePanel.configure(text = 'Beauty is only\nskin deep.') + self.tabset.tab_configure('Images', window = self.appearancePanel) + + def changeSide(self, side): + self.tabset.configure(side = side) + + def rotateText(self, angle): + if Pmw.integervalidator(angle) == Pmw.OK: + self.tabset.configure(rotate = angle) + else: + self.tabset.bell() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ButtonBox.py b/Pmw/Pmw_1_2/demos/ButtonBox.py new file mode 100644 index 00000000..984ff36f --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ButtonBox.py @@ -0,0 +1,56 @@ +title = 'Pmw.ButtonBox demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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 is hit). + self.buttonBox.setdefault('OK') + parent.bind('', 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' + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Colors.py b/Pmw/Pmw_1_2/demos/Colors.py new file mode 100644 index 00000000..b6e0a5be --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Colors.py @@ -0,0 +1,50 @@ +title = 'Colorscheme demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + frame = Tkinter.Frame(parent) + frame.pack(fill = 'both', expand = 1) + + defaultPalette = Pmw.Color.getdefaultpalette(parent) + + colors = ('red', 'green', 'blue') + items = ('Testing', 'More testing', 'a test', 'foo', 'blah') + for count in range(len(colors)): + color = colors[count] + normalcolor = Pmw.Color.changebrightness(parent, color, 0.85) + Pmw.Color.setscheme(parent, normalcolor) + combo = Pmw.ComboBox(frame, + scrolledlist_items = items, + entryfield_value = items[0]) + combo.grid(sticky='nsew', row = count, column = 0) + + normalcolor = Pmw.Color.changebrightness(parent, color, 0.35) + Pmw.Color.setscheme(parent, normalcolor, foreground = 'white') + combo = Pmw.ComboBox(frame, + scrolledlist_items = items, + entryfield_value = items[0]) + combo.grid(sticky='nsew', row = count, column = 1) + + apply(Pmw.Color.setscheme, (parent,), defaultPalette) + #normalcolor = Pmw.Color.changebrightness(parent, 'red', 0.85) + #Pmw.Color.setscheme(parent, normalcolor) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ComboBox.py b/Pmw/Pmw_1_2/demos/ComboBox.py new file mode 100644 index 00000000..461fc809 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ComboBox.py @@ -0,0 +1,76 @@ +title = 'Pmw.ComboBox demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + parent.configure(background = 'white') + + # Create and pack the widget to be configured. + self.target = Tkinter.Label(parent, + relief = 'sunken', + padx = 20, + pady = 20, + ) + self.target.pack(fill = 'x', padx = 8, pady = 8) + + # Create and pack the simple ComboBox. + words = ('Monti', 'Python', 'ik', 'den', 'Holie', 'Grailen', '(Bok)') + simple = Pmw.ComboBox(parent, + label_text = 'Simple ComboBox:', + labelpos = 'nw', + selectioncommand = self.changeText, + scrolledlist_items = words, + dropdown = 0, + ) + simple.pack(side = 'left', fill = 'both', + expand = 1, padx = 8, pady = 8) + + # Display the first text. + first = words[0] + simple.selectitem(first) + self.changeText(first) + + # Create and pack the dropdown ComboBox. + colours = ('cornsilk1', 'snow1', 'seashell1', 'antiquewhite1', + 'bisque1', 'peachpuff1', 'navajowhite1', 'lemonchiffon1', + 'ivory1', 'honeydew1', 'lavenderblush1', 'mistyrose1') + dropdown = Pmw.ComboBox(parent, + label_text = 'Dropdown ComboBox:', + labelpos = 'nw', + selectioncommand = self.changeColour, + scrolledlist_items = colours, + ) + dropdown.pack(side = 'left', anchor = 'n', + fill = 'x', expand = 1, padx = 8, pady = 8) + + # Display the first colour. + first = colours[0] + dropdown.selectitem(first) + self.changeColour(first) + + def changeColour(self, colour): + print 'Colour: ' + colour + self.target.configure(background = colour) + + def changeText(self, text): + print 'Text: ' + text + self.target.configure(text = text) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ComboBoxDialog.py b/Pmw/Pmw_1_2/demos/ComboBoxDialog.py new file mode 100644 index 00000000..c0e3deda --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ComboBoxDialog.py @@ -0,0 +1,44 @@ +title = 'Pmw.ComboBoxDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create the dialog. + self.dialog = Pmw.ComboBoxDialog(parent, + title = 'My ComboBoxDialog', + buttons = ('OK', 'Cancel'), + defaultbutton = 'OK', + combobox_labelpos = 'n', + label_text = 'What do you think of Pmw?', + scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross')) + self.dialog.withdraw() + + # Create button to launch the dialog. + w = Tkinter.Button(parent, + text = 'Show combo box dialog', + command = self.doit) + w.pack(padx = 8, pady = 8) + + def doit(self): + result = self.dialog.activate() + print 'You clicked on', result, self.dialog.get() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() + diff --git a/Pmw/Pmw_1_2/demos/ConfigClass.py b/Pmw/Pmw_1_2/demos/ConfigClass.py new file mode 100644 index 00000000..b4d2b7fd --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ConfigClass.py @@ -0,0 +1,76 @@ +title = 'Component python class configuration demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class MyButton(Tkinter.Button): + # This is just an ordinary button with special colors. + + def __init__(self, master=None, cnf={}, **kw): + self.__toggle = 0 + kw['background'] = 'green' + kw['activebackground'] = 'red' + apply(Tkinter.Button.__init__, (self, master, cnf), kw) + +class Demo: + def __init__(self, parent): + + # Create a title label: + label = Tkinter.Label(parent, + text = 'EntryFields with label components of specified type:') + label.pack(fill='x', expand=1, padx=10, pady=5) + + # Create and pack some EntryFields. + entries = [] + entry = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Label' + ) + entry.pack(fill='x', expand=1, padx=10, pady=5) + entries.append(entry) + + entry = Pmw.EntryField(parent, + labelpos = 'w', + label_pyclass = Tkinter.Button, + label_text = 'Button' + ) + entry.pack(fill='x', expand=1, padx=10, pady=5) + entries.append(entry) + + entry = Pmw.EntryField(parent, + labelpos = 'w', + label_pyclass = MyButton, + label_text = 'Special button' + ) + entry.pack(fill='x', expand=1, padx=10, pady=5) + entries.append(entry) + + Pmw.alignlabels(entries) + + # Create and pack a ButtonBox. + buttonBox = Pmw.ButtonBox(parent, + labelpos = 'nw', + label_text = 'ButtonBox:') + buttonBox.pack(fill = 'both', expand = 1, padx=10, pady=5) + + # Add some buttons to the ButtonBox. + buttonBox.add('with a') + buttonBox.add('special', pyclass = MyButton) + buttonBox.add('button') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Counter.py b/Pmw/Pmw_1_2/demos/Counter.py new file mode 100644 index 00000000..856b4dfa --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Counter.py @@ -0,0 +1,121 @@ +title = 'Pmw.Counter demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import time +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Need to use long ints here because on the Macintosh the maximum size + # of an integer is smaller than the value returned by time.time(). + now = (long(time.time()) / 300) * 300 + + # Create the Counters. + self._date = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'Date (4-digit year):', + entryfield_value = + time.strftime('%d/%m/%Y', time.localtime(now)), + entryfield_command = self.execute, + entryfield_validate = {'validator' : 'date', 'format' : 'dmy'}, + datatype = {'counter' : 'date', 'format' : 'dmy', 'yyyy' : 1}) + + self._isodate = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'ISO-Date (4-digit year):', + entryfield_value = + time.strftime('%Y-%m-%d', time.localtime(now)), + entryfield_command = self.execute, + entryfield_validate = {'validator' : 'date', 'format' : 'ymd', + 'separator' : '-' }, + datatype = {'counter' : 'date', 'format' : 'ymd', 'yyyy' : 1, + 'separator' : '-' }) + + self._time = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'Time:', + entryfield_value = + time.strftime('%H:%M:%S', time.localtime(now)), + entryfield_validate = {'validator' : 'time', + 'min' : '00:00:00', 'max' : '23:59:59', + 'minstrict' : 0, 'maxstrict' : 0}, + datatype = {'counter' : 'time', 'time24' : 1}, + increment=5*60) + self._real = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'Real (with comma)\nand extra\nlabel lines:', + label_justify = 'left', + entryfield_value = '1,5', + datatype = {'counter' : 'real', 'separator' : ','}, + entryfield_validate = {'validator' : 'real', + 'min' : '-2,0', 'max' : '5,0', + 'separator' : ','}, + increment = 0.1) + self._custom = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'Custom:', + entryfield_value = specialword[:4], + datatype = _custom_counter, + entryfield_validate = _custom_validate) + self._int = Pmw.Counter(parent, + labelpos = 'w', + label_text = 'Vertical integer:', + orient = 'vertical', + entry_width = 2, + entryfield_value = 50, + entryfield_validate = {'validator' : 'integer', + 'min' : 0, 'max' : 99} + ) + + counters = (self._date, self._isodate, self._time, self._real, + self._custom) + Pmw.alignlabels(counters) + + # Pack them all. + for counter in counters: + counter.pack(fill='both', expand=1, padx=10, pady=5) + self._int.pack(padx=10, pady=5) + + def execute(self): + print 'Return pressed, value is', self._date.get() + +specialword = 'Monti Python ik den Holie Grailen (Bok)' + +def _custom_validate(text): + if string.find(specialword, text) == 0: + return 1 + else: + return -1 + +def _custom_counter(text, factor, increment): + # increment is ignored here. + if string.find(specialword, text) == 0: + length = len(text) + if factor == 1: + if length >= len(specialword): + raise ValueError, 'maximum length reached' + return specialword[:length + 1] + else: + if length == 0: + raise ValueError, 'empty string' + return specialword[:length - 1] + else: + raise ValueError, 'bad string ' + text + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/CounterDialog.py b/Pmw/Pmw_1_2/demos/CounterDialog.py new file mode 100644 index 00000000..808c3bf3 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/CounterDialog.py @@ -0,0 +1,60 @@ +title = 'Pmw.CounterDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +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() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/DemoVersion.py b/Pmw/Pmw_1_2/demos/DemoVersion.py new file mode 100644 index 00000000..477a9f95 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/DemoVersion.py @@ -0,0 +1,36 @@ +# Set the version of Pmw to use for the demonstrations based on the +# directory name. + +import imp +import os +import string + +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 setPmwVersion(): + file = imp.find_module(__name__)[1] + file = os.path.normpath(file) + file = expandLinks(file) + + dir = os.path.dirname(file) + dir = expandLinks(dir) + dir = os.path.dirname(dir) + dir = expandLinks(dir) + dir = os.path.basename(dir) + + version = string.replace(dir[4:], '_', '.') + import Pmw + if version in Pmw.installedversions(): + Pmw.setversion(version) + else: + print 'No such Pmw version', `version` + '.', + print 'Using default version', `Pmw.version()` diff --git a/Pmw/Pmw_1_2/demos/Dialog.py b/Pmw/Pmw_1_2/demos/Dialog.py new file mode 100644 index 00000000..3be3fdb0 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Dialog.py @@ -0,0 +1,89 @@ +title = 'Pmw.Dialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/EntryField.py b/Pmw/Pmw_1_2/demos/EntryField.py new file mode 100644 index 00000000..69163816 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/EntryField.py @@ -0,0 +1,98 @@ +title = 'Pmw.EntryField demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import time +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create and pack the EntryFields. + self._any = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Any:', + validate = None, + command = self.execute) + self._real = Pmw.EntryField(parent, + labelpos = 'w', + value = '55.5', + label_text = 'Real (10.0 to 99.0):', + validate = {'validator' : 'real', + 'min' : 10, 'max' : 99, 'minstrict' : 0}, + modifiedcommand = self.changed) + self._odd = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Odd length:', + validate = self.custom_validate, + value = 'ABC') + self._date = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Date (in 2000):', + value = '2000/2/29', + validate = {'validator' : 'date', + 'min' : '2000/1/1', 'max' : '2000/12/31', + 'minstrict' : 0, 'maxstrict' : 0, + 'format' : 'ymd'}, + ) + now = time.localtime(time.time()) + self._date2 = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Date (d.m.y):', + value = '%d.%d.%d' % (now[2], now[1], now[0]), + validate = {'validator' : 'date', + 'format' : 'dmy', 'separator' : '.'}, + ) + self._time = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Time (24hr clock):', + value = '8:00:00', + validate = {'validator' : 'time', + 'min' : '00:00:00', 'max' : '23:59:59', + 'minstrict' : 0, 'maxstrict' : 0}, + ) + self._comma = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Real (with comma):', + value = '123,456', + validate = {'validator' : 'real', 'separator' : ','}, + ) + + entries = (self._any, self._real, self._odd, self._date, self._date2, + self._time, self._comma) + + for entry in entries: + entry.pack(fill='x', expand=1, padx=10, pady=5) + Pmw.alignlabels(entries) + + self._any.component('entry').focus_set() + + def changed(self): + print 'Text changed, value is', self._real.getvalue() + + def execute(self): + print 'Return pressed, value is', self._any.getvalue() + + # This implements a custom validation routine. It simply checks + # if the string is of odd length. + def custom_validate(self, text): + print 'text:', text + if len(text) % 2 == 0: + return -1 + else: + return 1 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ErrorHandling.py b/Pmw/Pmw_1_2/demos/ErrorHandling.py new file mode 100644 index 00000000..41fd10fc --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ErrorHandling.py @@ -0,0 +1,42 @@ +title = 'Pmw error handling demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create two buttons to generate errors. + w = Tkinter.Button(parent, text = 'Click here to generate\n' + + 'an error in a command callback.', command = self.execute) + w.pack(padx = 8, pady = 8) + + w = Tkinter.Button(parent, text = 'Click here to generate\n' + + 'an error in a callback called\nfrom an event binding.') + w.pack(padx = 8, pady = 8) + w.bind('', self.execute) + w.bind('', self.execute) + + def execute(self, event = None): + self._error() + + def _error(self): + # Divide by zero + 1/0 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ExampleDemo.py b/Pmw/Pmw_1_2/demos/ExampleDemo.py new file mode 100644 index 00000000..f7ec1e71 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ExampleDemo.py @@ -0,0 +1,33 @@ +title = 'Pmw.EXAMPLE demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + # Create and pack the EXAMPLEs. + self.widget1 = Pmw.Counter(parent) + self.widget1.setentry('1') + self.widget1.pack() + + self.widget2 = Pmw.Counter(parent, increment = 10) + self.widget2.setentry('100') + self.widget2.pack() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Grid.py b/Pmw/Pmw_1_2/demos/Grid.py new file mode 100644 index 00000000..051863e5 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Grid.py @@ -0,0 +1,44 @@ +title = 'Grid geometry manager demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + frame = Tkinter.Frame(parent) + frame.pack(fill = 'both', expand = 1) + + button = {} + for num in range(0, 10): + button[num] = Tkinter.Button(frame, text = 'Button ' + str(num)) + + button[0].grid(column=0, row=0, rowspan=2, sticky='nsew') + button[1].grid(column=1, row=0, columnspan=3, sticky='nsew') + button[2].grid(column=1, row=1, rowspan=2, sticky='nsew') + button[3].grid(column=2, row=1) + button[4].grid(column=3, row=1) + button[5].grid(column=0, row=2) + button[6].grid(column=0, row=3, columnspan=2, sticky='nsew') + button[7].grid(column=2, row=2, columnspan=2, rowspan=2, sticky='nsew') + button[8].grid(column=0, row=4) + button[9].grid(column=3, row=4, sticky='e') + + frame.grid_rowconfigure(3, weight=1) + frame.grid_columnconfigure(3, weight=1) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Group.py b/Pmw/Pmw_1_2/demos/Group.py new file mode 100644 index 00000000..b1c4ed5c --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Group.py @@ -0,0 +1,93 @@ +title = 'Pmw.Group demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + # Create and pack the Groups. + w = Pmw.Group(parent, tag_text='label') + w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) + cw = Tkinter.Label(w.interior(), + text = 'A group with the\ndefault Label tag') + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + + w = Pmw.Group(parent, tag_pyclass = None) + w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) + cw = Tkinter.Label(w.interior(), text = 'A group\nwithout a tag') + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + + radiogroups = [] + self.var = Tkinter.IntVar() + self.var.set(0) + radioframe = Tkinter.Frame(parent) + w = Pmw.Group(radioframe, + tag_pyclass = Tkinter.Radiobutton, + tag_text='radiobutton 1', + tag_value = 0, + tag_variable = self.var) + w.pack(fill = 'both', expand = 1, side='left') + cw = Tkinter.Frame(w.interior(),width=200,height=20) + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + radiogroups.append(w) + + w = Pmw.Group(radioframe, + tag_pyclass = Tkinter.Radiobutton, + tag_text='radiobutton 2', + tag_font = Pmw.logicalfont('Helvetica', 4), + tag_value = 1, + tag_variable = self.var) + w.pack(fill = 'both', expand = 1, side='left') + cw = Tkinter.Frame(w.interior(),width=200,height=20) + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + radiogroups.append(w) + radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both') + Pmw.aligngrouptags(radiogroups) + + w = Pmw.Group(parent, + tag_pyclass = Tkinter.Checkbutton, + tag_text='checkbutton', + tag_foreground='blue') + w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) + cw = Tkinter.Frame(w.interior(),width=150,height=20) + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + + w = Pmw.Group(parent, + tag_pyclass = Tkinter.Button, + tag_text='Tkinter.Button') + w.configure(tag_command = w.toggle) + w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) + cw = Tkinter.Label(w.interior(), + background = 'aliceblue', + text = 'A group with\na Button tag!?' + ) + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + + w = Pmw.Group(parent, + tag_pyclass = Tkinter.Button, + tag_text='Show/Hide') + w.configure(tag_command = w.toggle) + w.pack(fill = 'both', expand = 1, padx = 6, pady = 6) + cw = Tkinter.Label(w.interior(), + background = 'aliceblue', + text = 'Now you see me.\nNow you don\'t.' + ) + cw.pack(padx = 2, pady = 2, expand='yes', fill='both') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/HistoryText.py b/Pmw/Pmw_1_2/demos/HistoryText.py new file mode 100644 index 00000000..5a7b2eb4 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/HistoryText.py @@ -0,0 +1,102 @@ +title = 'Pmw.HistoryText demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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') + + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/LabeledWidget.py b/Pmw/Pmw_1_2/demos/LabeledWidget.py new file mode 100644 index 00000000..8a98c59e --- /dev/null +++ b/Pmw/Pmw_1_2/demos/LabeledWidget.py @@ -0,0 +1,46 @@ +title = 'Pmw.LabeledWidget demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + widget = Demo(root) + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack() + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/LogicalFont.py b/Pmw/Pmw_1_2/demos/LogicalFont.py new file mode 100644 index 00000000..61854690 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/LogicalFont.py @@ -0,0 +1,84 @@ +title = 'Pmw LogicalFont demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +class Demo: + + # The fonts to demonstrate. + fontList = ( + (('Times', 0), {}), + (('Helvetica', 0), {}), + (('Typewriter', 0), {}), + (('Fixed', 0), {}), + (('Courier', 0), {}), + (('Helvetica', 2), {'slant' : 'italic'}), + (('Helvetica', 0), {'size' : 18}), + (('Helvetica', 0), {'weight' : 'bold'}), + (('Helvetica', 12), {'weight' : 'bold', 'slant' : 'italic'}), + (('Typewriter', 0), {'size' : 8, 'weight' : 'bold'}), + (('Fixed', 0), {'size' : 8, 'weight' : 'bold'}), + (('Times', 0), {'size' : 24, 'weight' : 'bold', 'slant' : 'italic'}), + (('Typewriter', 0), {'width' : 'condensed'}), + (('Typewriter', -1), {'width' : 'condensed'}), + (('Fixed', 0), {'width' : 'condensed'}), + (('Fixed', -1), {'width' : 'condensed'}), + (('Helvetica', 0), {'weight' : 'bogus'}), + ) + + fontText = [] + + def __init__(self, parent): + + self.parent = parent + + # Create the text to display to the user to represent each font. + if Demo.fontText == []: + for args, dict in Demo.fontList: + text = args[0] + if args[1] != 0: + text = text + ' ' + str(args[1]) + for name, value in dict.items(): + text = text + ' ' + name + ': ' + str(value) + Demo.fontText.append(text) + + # Create a listbox to contain the font selections. + self.box = Pmw.ScrolledListBox(parent, listbox_selectmode='single', + listbox_width = 35, + listbox_height = 10, + items=Demo.fontText, + label_text='Font', labelpos='nw', + selectioncommand=self.selectionCommand) + self.box.pack(fill = 'both', expand = 1, padx = 10, pady = 10) + + # Create a label to display the selected font. + self.target = Tkinter.Label(parent, + text = 'The quick brown fox jumps\nover the lazy dog', + relief = 'sunken', padx = 10, pady = 10) + self.target.pack(fill = 'both', expand = 1, padx = 10, pady = 10) + + def selectionCommand(self): + sel = self.box.curselection() + if len(sel) > 0: + args, dict = Demo.fontList[string.atoi(sel[0])] + font = apply(Pmw.logicalfont, args, dict) + self.target.configure(font = font) + print font + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MainMenuBar.py b/Pmw/Pmw_1_2/demos/MainMenuBar.py new file mode 100644 index 00000000..682d36ee --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MainMenuBar.py @@ -0,0 +1,176 @@ +title = 'Pmw.MainMenuBar demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MenuBar.py b/Pmw/Pmw_1_2/demos/MenuBar.py new file mode 100644 index 00000000..8e22e53b --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MenuBar.py @@ -0,0 +1,166 @@ +title = 'Pmw.MenuBar demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MessageBar.py b/Pmw/Pmw_1_2/demos/MessageBar.py new file mode 100644 index 00000000..8cec7ddc --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MessageBar.py @@ -0,0 +1,85 @@ +title = 'Pmw.MessageBar demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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', +} + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MessageDialog.py b/Pmw/Pmw_1_2/demos/MessageDialog.py new file mode 100644 index 00000000..09c8c98b --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MessageDialog.py @@ -0,0 +1,102 @@ +title = 'Pmw.MessageDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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 + + + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MessageInfo.py b/Pmw/Pmw_1_2/demos/MessageInfo.py new file mode 100644 index 00000000..1c2fac40 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MessageInfo.py @@ -0,0 +1,108 @@ +title = 'Pmw toplevel megawidget demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class MessageInfo(Pmw.MegaToplevel): + + # Demo Pmw toplevel megawidget. + + def __init__(self, parent=None, **kw): + + # Define the megawidget options. + optiondefs = () + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaToplevel.__init__(self, parent) + + # Create the components. + interior = self.interior() + + self._dismiss = self.createcomponent('dismiss', + (), None, + Tkinter.Button, (interior,), + text = 'Dismiss', + command = self.goodbye) + self._dismiss.pack(side = 'bottom', pady = 4) + + self._separator = self.createcomponent('separator', + (), None, + Tkinter.Frame, (interior,), + height = 2, + borderwidth = 1, + relief = 'sunken') + self._separator.pack(side = 'bottom', fill = 'x', pady = 4) + + self._icon = self.createcomponent('icon', + (), None, + Tkinter.Label, (interior,)) + self._icon.pack(side = 'left', padx = 8, pady = 8) + + self._infoFrame = self.createcomponent('infoframe', + (), None, + Tkinter.Frame, (interior,)) + self._infoFrame.pack( + side = 'left', + fill = 'both', + expand = 1, + padx = 4, + pady = 4) + + self._message = self.createcomponent('message', + (), None, + Tkinter.Label, (interior,)) + self._message.pack(expand = 1, fill = 'both', padx = 10, pady = 10) + + self.bind('', self.goodbye) + + # Check keywords and initialise options. + self.initialiseoptions() + + def goodbye(self, event = None): + self.destroy() + +class Demo: + def __init__(self, parent): + # Create button to launch the megawidget. + self.button = Tkinter.Button(parent, + command = self.showMessageInfo, + text = 'Show toplevel megawidget') + self.button.pack(padx = 8, pady = 8) + + self.count = 0 + self.parent = parent + + def showMessageInfo(self): + bitmaps = ('warning', 'hourglass', 'error', 'info', + 'gray25', 'gray50', 'question', 'questhead') + bitmap = bitmaps[self.count % len(bitmaps)] + + message = 'This is a demonstration of\na megawidget.\n' + \ + 'It contains a configurable\nmessage area and bitmap.\n' + \ + 'This instance is displaying\nthe "' + bitmap + '" bitmap.' + + # Make the toplevel window a child of this window, so that it + # is destroyed when the demo is destroyed. + MessageInfo(self.parent, message_text = message, icon_bitmap = bitmap) + + self.count = self.count + 1 + if self.count == 1: + self.button.configure(text = 'Show another\ntoplevel megawidget') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/MultiLineLabel.py b/Pmw/Pmw_1_2/demos/MultiLineLabel.py new file mode 100644 index 00000000..b08b4c15 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/MultiLineLabel.py @@ -0,0 +1,73 @@ +title = 'Multi-line label demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + frame = Tkinter.Frame(parent, background = '#eeeeee') + frame.pack(fill = 'both', expand = 1, padx = 5, pady = 5) + + stickys = ('n', 's', 'e', 'w', 'ns', 'ew', 'ne', 'nw', 'se', 'sw', + 'nsw', 'nse', 'new', 'sew', 'nsew',) + + widgets = [] + row = 0 + column = 0 + + # Choose one megawidget class to demonstrate: + cls = Pmw.EntryField + # cls = Pmw.Counter + # cls = Pmw.ComboBox + # cls = Pmw.LabeledWidget + # cls = Pmw.MessageBar + + for sticky in stickys: + dict = {} + dict['sticky'] = sticky + dict['labelpos'] = 'w' + dict['label_text'] = '1\n' + sticky + ':\n3' + if cls == Pmw.EntryField: + dict['value'] = sticky + dict['entry_width'] = 6 + if cls == Pmw.Counter or cls == Pmw.ComboBox: + dict['entryfield_value'] = sticky + dict['entry_width'] = 6 + widget = apply(cls, (frame,), dict) + if cls == Pmw.LabeledWidget: + f = Tkinter.Button(widget.interior(), text = sticky) + f.pack(fill = 'both', expand = 1) + if cls == Pmw.MessageBar: + widget.message('state', sticky) + widget.grid(column=column, row=row, sticky='ew', padx = 10, pady = 5) + frame.grid_columnconfigure(column, weight=1) + frame.grid_rowconfigure(row, weight=1) + + widgets.append(widget) + + if row < 4: + row = row + 1 + else: + row = 0 + column = column + 1 + + Pmw.alignlabels(widgets, sticky = 'e') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/NestedDialogs.py b/Pmw/Pmw_1_2/demos/NestedDialogs.py new file mode 100644 index 00000000..e8199a33 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/NestedDialogs.py @@ -0,0 +1,71 @@ +title = 'Modal dialog nesting demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create button to launch the dialog. + w = Tkinter.Button(parent, text = 'Show first dialog', + command = self.showFirstDialog) + w.pack(padx = 8, pady = 8) + + self.timerId = None + + self.dialog1 = Pmw.MessageDialog(parent, + message_text = 'This is the first modal dialog.\n' + + 'You can see how dialogs nest by\n' + + 'clicking on the "Next" button.', + title = 'Dialog 1', + buttons = ('Next', 'Cancel'), + defaultbutton = 'Next', + command = self.next_dialog) + self.dialog1.withdraw() + + self.dialog2 = Pmw.Dialog(self.dialog1.interior(), + title = 'Dialog 2', + buttons = ('Cancel',), + deactivatecommand = self.cancelTimer, + defaultbutton = 'Cancel') + self.dialog2.withdraw() + w = Tkinter.Label(self.dialog2.interior(), + text = 'This is the second modal dialog.\n' + + 'It will automatically disappear shortly') + w.pack(padx = 10, pady = 10) + + def showFirstDialog(self): + self.dialog1.activate() + + def cancelTimer(self): + if self.timerId is not None: + self.dialog2.after_cancel(self.timerId) + self.timerId = None + + def deactivateSecond(self): + self.timerId = None + self.dialog2.deactivate() + + def next_dialog(self, result): + if result != 'Next': + self.dialog1.deactivate() + return + + self.timerId = self.dialog2.after(3000, self.deactivateSecond) + self.dialog2.activate() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/NoteBook.py b/Pmw/Pmw_1_2/demos/NoteBook.py new file mode 100644 index 00000000..20815a51 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/NoteBook.py @@ -0,0 +1,52 @@ +title = 'Pmw.NoteBook demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + widget = Demo(root) + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack() + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/NoteBook_2.py b/Pmw/Pmw_1_2/demos/NoteBook_2.py new file mode 100644 index 00000000..f42037a7 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/NoteBook_2.py @@ -0,0 +1,224 @@ +title = 'Pmw.NoteBook demonstration (more complex)' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent, withTabs = 1): + + # Repeat random number sequence for each run. + self.rand = 12345 + + # Default demo is to display a tabbed notebook. + self.withTabs = withTabs + + # Create a frame to put everything in + self.mainframe = Tkinter.Frame(parent) + self.mainframe.pack(fill = 'both', expand = 1) + + # Find current default colors + button = Tkinter.Button() + defaultbg = button.cget('background') + defaultfg = button.cget('foreground') + button.destroy() + + # Create the list of colors to cycle through + self.colorList = [] + self.colorList.append((defaultbg, defaultfg)) + self.colorIndex = 0 + for color in Pmw.Color.spectrum(6, 1.5, 1.0, 1.0, 1): + bg = Pmw.Color.changebrightness(self.mainframe, color, 0.85) + self.colorList.append((bg, 'black')) + bg = Pmw.Color.changebrightness(self.mainframe, color, 0.55) + self.colorList.append((bg, 'white')) + + # Set the color to the current default + Pmw.Color.changecolor(self.mainframe, defaultbg, foreground = defaultfg) + defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) + Pmw.Color.setscheme(self.mainframe, defaultbg, foreground = defaultfg) + + # Create the notebook, but don't pack it yet. + if self.withTabs: + tabpos = 'n' + else: + tabpos = None + self.notebook = Pmw.NoteBook(self.mainframe, + tabpos = tabpos, + createcommand = PrintOne('Create'), + lowercommand = PrintOne('Lower'), + raisecommand = PrintOne('Raise'), + hull_width = 300, + hull_height = 200, + ) + + # Create a buttonbox to configure the notebook and pack it first. + buttonbox = Pmw.ButtonBox(self.mainframe) + buttonbox.pack(side = 'bottom', fill = 'x') + + # Add some buttons to the buttonbox to configure the notebook. + buttonbox.add('Insert\npage', command = self.insertpage) + buttonbox.add('Delete\npage', command = self.deletepage) + buttonbox.add('Add\nbutton', command = self.addbutton) + buttonbox.add('Change\ncolor', command = self.changecolor) + buttonbox.add('Natural\nsize', command = + self.notebook.setnaturalsize) + + if not self.withTabs: + # Create the selection widget to select the page in the notebook. + self.optionmenu = Pmw.OptionMenu(self.mainframe, + menubutton_width = 10, + command = self.notebook.selectpage + ) + self.optionmenu.pack(side = 'left', padx = 10) + + # Pack the notebook last so that the buttonbox does not disappear + # when the window is made smaller. + self.notebook.pack(fill = 'both', expand = 1, padx = 5, pady = 5) + + # Populate some pages of the notebook. + page = self.notebook.add('tmp') + self.notebook.delete('tmp') + page = self.notebook.add('Appearance') + if self.withTabs: + self.notebook.tab('Appearance').focus_set() + button = Tkinter.Button(page, + text = 'Welcome\nto\nthe\nAppearance\npage') + button.pack(expand = 1) + page = self.notebook.add('Fonts') + button = Tkinter.Button(page, + text = 'This is a very very very very wide Fonts page') + button.pack(expand = 1) + page = self.notebook.insert('Applications', before = 'Fonts') + button = Tkinter.Button(page, text = 'This is the Applications page') + button.pack(expand = 1) + + # Initialise the first page and the initial colour. + if not self.withTabs: + self.optionmenu.setitems(self.notebook.pagenames()) + apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) + self.pageCounter = 0 + + def insertpage(self): + # Create a page at a random position + + defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) + bg, fg = self.colorList[self.colorIndex] + Pmw.Color.setscheme(self.mainframe, bg, foreground = fg) + + self.pageCounter = self.pageCounter + 1 + before = self.randomchoice(self.notebook.pagenames() + [Pmw.END]) + pageName = 'page%d' % self.pageCounter + if self.pageCounter % 5 == 0: + tab_text = pageName + '\nline two' + else: + tab_text = pageName + classes = (None, Tkinter.Button, Tkinter.Label, Tkinter.Checkbutton) + cls = self.randomchoice((None,) + classes) + if cls is None: + print 'Adding', pageName, 'as a frame with a button' + if self.withTabs: + page = self.notebook.insert(pageName, before, tab_text = tab_text) + else: + page = self.notebook.insert(pageName, before) + button = Tkinter.Button(page, + text = 'This is button %d' % self.pageCounter) + button.pack(expand = 1) + else: + print 'Adding', pageName, 'using', cls + if self.withTabs: + page = self.notebook.insert(pageName, before, + tab_text = tab_text, + page_pyclass = cls, + page_text = 'This is a page using\na %s' % str(cls) + ) + else: + page = self.notebook.insert(pageName, before, + page_pyclass = cls, + page_text = 'This is a page using\na %s' % str(cls) + ) + if not self.withTabs: + self.optionmenu.setitems( + self.notebook.pagenames(), self.notebook.getcurselection()) + + apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) + + def addbutton(self): + # Add a button to a random page. + + defaultPalette = Pmw.Color.getdefaultpalette(self.mainframe) + bg, fg = self.colorList[self.colorIndex] + Pmw.Color.setscheme(self.mainframe, bg, foreground = fg) + + framePages = [] + for pageName in self.notebook.pagenames(): + page = self.notebook.page(pageName) + if page.__class__ == Tkinter.Frame: + framePages.append(pageName) + + if len(framePages) == 0: + self.notebook.bell() + return + + pageName = self.randomchoice(framePages) + print 'Adding extra button to', pageName + page = self.notebook.page(pageName) + button = Tkinter.Button(page, text = 'This is an extra button') + button.pack(expand = 1) + + apply(Pmw.Color.setscheme, (self.mainframe,), defaultPalette) + + def deletepage(self): + # Delete a random page + + pageNames = self.notebook.pagenames() + if len(pageNames) == 0: + self.notebook.bell() + return + + pageName = self.randomchoice(pageNames) + print 'Deleting', pageName + self.notebook.delete(pageName) + if not self.withTabs: + self.optionmenu.setitems( + self.notebook.pagenames(), self.notebook.getcurselection()) + + def changecolor(self): + self.colorIndex = self.colorIndex + 1 + if self.colorIndex == len(self.colorList): + self.colorIndex = 0 + + bg, fg = self.colorList[self.colorIndex] + print 'Changing color to', bg + Pmw.Color.changecolor(self.mainframe, bg, foreground = fg) + self.notebook.recolorborders() + + # Simple random number generator. + def randomchoice(self, selection): + num = len(selection) + self.rand = (self.rand * 125) % 2796203 + index = self.rand % num + return selection[index] + +class PrintOne: + def __init__(self, text): + self.text = text + + def __call__(self, text): + print self.text, text + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + widget = Demo(root) + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack() + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/NoteBook_3.py b/Pmw/Pmw_1_2/demos/NoteBook_3.py new file mode 100644 index 00000000..8106c5af --- /dev/null +++ b/Pmw/Pmw_1_2/demos/NoteBook_3.py @@ -0,0 +1,26 @@ +title = 'Pmw.NoteBook demonstration (with no tabs)' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +# Reuse the NoteBook with tabs demo. +import NoteBook_2 + +class Demo(NoteBook_2.Demo): + def __init__(self, parent): + NoteBook_2.Demo.__init__(self, parent, withTabs = 0) + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + widget = Demo(root) + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack() + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/OptionMenu.py b/Pmw/Pmw_1_2/demos/OptionMenu.py new file mode 100644 index 00000000..11d7a88a --- /dev/null +++ b/Pmw/Pmw_1_2/demos/OptionMenu.py @@ -0,0 +1,66 @@ +title = 'Pmw.OptionMenu demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create and pack the OptionMenu megawidgets. + # The first one has a textvariable. + self.var = Tkinter.StringVar() + self.var.set('steamed') + self.method_menu = Pmw.OptionMenu(parent, + labelpos = 'w', + label_text = 'Choose method:', + menubutton_textvariable = self.var, + items = ['baked', 'steamed', 'stir fried', 'boiled', 'raw'], + menubutton_width = 10, + ) + self.method_menu.pack(anchor = 'w', padx = 10, pady = 10) + + self.vege_menu = Pmw.OptionMenu (parent, + labelpos = 'w', + label_text = 'Choose vegetable:', + items = ('broccoli', 'peas', 'carrots', 'pumpkin'), + menubutton_width = 10, + command = self._printOrder, + ) + self.vege_menu.pack(anchor = 'w', padx = 10, pady = 10) + + self.direction_menu = Pmw.OptionMenu (parent, + labelpos = 'w', + label_text = 'Menu direction:', + items = ('flush', 'above', 'below', 'left', 'right'), + menubutton_width = 10, + command = self._changeDirection, + ) + self.direction_menu.pack(anchor = 'w', padx = 10, pady = 10) + + menus = (self.method_menu, self.vege_menu, self.direction_menu) + Pmw.alignlabels(menus) + + def _printOrder(self, vege): + # Can use 'self.var.get()' instead of 'getcurselection()'. + print 'You have chosen %s %s.' % \ + (self.method_menu.getcurselection(), vege) + + def _changeDirection(self, direction): + for menu in (self.method_menu, self.vege_menu, self.direction_menu): + menu.configure(menubutton_direction = direction) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/PanedWidget.py b/Pmw/Pmw_1_2/demos/PanedWidget.py new file mode 100644 index 00000000..e8bdb22d --- /dev/null +++ b/Pmw/Pmw_1_2/demos/PanedWidget.py @@ -0,0 +1,103 @@ +title = 'Pmw.PanedWidget demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + # Create a main PanedWidget with a few panes. + self.pw = Pmw.PanedWidget(parent, + orient='vertical', + hull_borderwidth = 1, + hull_relief = 'sunken', + hull_width=300, + hull_height=400) + for self.numPanes in range(4): + if self.numPanes == 1: + name = 'Fixed size' + pane = self.pw.add(name, min = .1, max = .1) + else: + name = 'Pane ' + str(self.numPanes) + pane = self.pw.add(name, min = .1, size = .25) + label = Tkinter.Label(pane, text = name) + label.pack(side = 'left', expand = 1) + button = Tkinter.Button(pane, text = 'Delete', + command = lambda s=self, n=name: s.deletePane(n)) + button.pack(side = 'left', expand = 1) + # TODO: add buttons to invoke self.moveOneUp and self.moveOneUp. + + self.pw.pack(expand = 1, fill='both') + + buttonBox = Pmw.ButtonBox(parent) + buttonBox.pack(fill = 'x') + buttonBox.add('Add pane', command = self.addPane) + buttonBox.add('Move pane', command = self.move) + self.moveSrc = 0 + self.moveNewPos = 1 + self.moveBack = 0 + + def move(self): + numPanes = len(self.pw.panes()) + if numPanes == 0: + print 'No panes to move!' + return + + if self.moveSrc >= numPanes: + self.moveSrc = numPanes - 1 + if self.moveNewPos >= numPanes: + self.moveNewPos = numPanes - 1 + print 'Moving pane', self.moveSrc, 'to new position', self.moveNewPos + self.pw.move(self.moveSrc, self.moveNewPos) + + self.moveSrc, self.moveNewPos = self.moveNewPos, self.moveSrc + if self.moveBack: + if self.moveNewPos == numPanes - 1: + self.moveNewPos = 0 + if self.moveSrc == numPanes - 1: + self.moveSrc = 0 + else: + self.moveSrc = self.moveSrc + 1 + else: + self.moveNewPos = self.moveNewPos + 1 + self.moveBack = not self.moveBack + + def addPane(self): + self.numPanes = self.numPanes + 1 + name = 'Pane ' + str(self.numPanes) + print 'Adding', name + pane = self.pw.add(name, min = .1, size = .25) + label = Tkinter.Label(pane, text = name) + label.pack(side = 'left', expand = 1) + button = Tkinter.Button(pane, text = 'Delete', + command = lambda s=self, n=name: s.deletePane(n)) + button.pack(side = 'left', expand = 1) + self.pw.updatelayout() + + def deletePane(self, name): + print 'Deleting', name + self.pw.delete(name) + self.pw.updatelayout() + + def moveOneUp(self, name): + self.pw.move(name, name, -1) + + def moveOneDown(self, name): + self.pw.move(name, name, 1) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/PanedWidget_2.py b/Pmw/Pmw_1_2/demos/PanedWidget_2.py new file mode 100644 index 00000000..334bced0 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/PanedWidget_2.py @@ -0,0 +1,65 @@ +title = 'Pmw.PanedWidget demonstration (pane factory)' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + self.paneCount = 0 + + # Create a "pane factory". + label = Tkinter.Label(parent, + pady = 10, + text = 'Below is a simple "pane factory".\n' + + 'Drag the handle on the left\nto create new panes.') + label.pack() + self.factory = Pmw.PanedWidget(parent, + orient='horizontal', + command = self.resize, + hull_borderwidth = 1, + hull_relief = 'raised', + hull_width=300, hull_height=200 + ) + self.factory.add('starter', size = 0.0) + self.factory.add('main') + button = Tkinter.Button(self.factory.pane('main'), + text = 'Pane\n0') + button.pack(expand = 1) + self.factory.pack(expand = 1, fill = 'both') + + def resize(self, list): + # Remove any panes less than 2 pixel wide. + for i in range(len(list) - 1, 0, -1): + if list[i] < 2: + self.factory.delete(i) + + # If the user has dragged the left hand handle, create a new pane. + if list[0] > 1: + self.paneCount = self.paneCount + 1 + + # Add a button to the new pane. + name = self.factory.panes()[0] + text = 'Pane\n' + str(self.paneCount) + button = Tkinter.Button(self.factory.pane(name), text = text) + button.pack(expand = 1) + + # Create a new starter pane. + name = 'Pane ' + str(self.paneCount) + self.factory.insert(name, size=0.0) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/PromptDialog.py b/Pmw/Pmw_1_2/demos/PromptDialog.py new file mode 100644 index 00000000..40f50f7d --- /dev/null +++ b/Pmw/Pmw_1_2/demos/PromptDialog.py @@ -0,0 +1,62 @@ +title = 'Pmw.PromptDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +# This may demonstrate a bug in Tk. Click on Cancel in the confirm +# dialog and then click on OK in the password dialog. Under Solaris +# 2.5 and python 1.5, the Cancel button in the confirm dialog is still +# displayed active, that is, it has a lighter background. + +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() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/RadioSelect.py b/Pmw/Pmw_1_2/demos/RadioSelect.py new file mode 100644 index 00000000..fb549b72 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/RadioSelect.py @@ -0,0 +1,116 @@ +title = 'Pmw.RadioSelect demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Resources.py b/Pmw/Pmw_1_2/demos/Resources.py new file mode 100644 index 00000000..2168b4ac --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Resources.py @@ -0,0 +1,74 @@ +title = 'Using Tk option database to configure Tk widgets' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +info = """ + The Tk widgets contained in this + simple megawidget have been + configured using the Tk option + database. + *DemoClass*Listbox.cursor is 'heart' + *DemoClass*Entry.cursor is 'hand1' + *DemoClass*background is 'pink' + *DemoClass*highlightBackground is 'green' + *DemoClass*foreground is 'blue' +""" + +class DemoClass(Pmw.MegaWidget): + + # Demo Pmw megawidget. + + def __init__(self, parent = None, **kw): + + # Define the megawidget options. + optiondefs = () + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaWidget.__init__(self, parent) + + interior = self.interior() + listbox = Tkinter.Listbox(interior, height = 12, width = 40) + listbox.pack(fill='both', expand='yes') + for line in string.split(info, '\n'): + listbox.insert('end', line) + + entry = Tkinter.Entry(interior) + entry.pack(fill='y') + entry.insert(0, 'Hello, World!') + + # Check keywords and initialise options. + self.initialiseoptions() + +class Demo: + def __init__(self, parent): + + # Test Tk option database settings. + parent.option_add('*DemoClass*Listbox.cursor', 'heart') + parent.option_add('*DemoClass*Entry.cursor', 'hand1') + parent.option_add('*DemoClass*background', 'pink') + parent.option_add('*DemoClass*highlightBackground', 'green') + parent.option_add('*DemoClass*foreground', 'blue') + + # Create and pack the megawidget. + demo = DemoClass(parent) + demo.pack(fill = 'both', expand = 1) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Resources_Pmw.py b/Pmw/Pmw_1_2/demos/Resources_Pmw.py new file mode 100644 index 00000000..a1f2f992 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Resources_Pmw.py @@ -0,0 +1,110 @@ +title = 'Using Tk option database to configure Pmw megawidgets' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + self.parent = parent + + header = Tkinter.Label(parent, text = 'Select some Tk option ' + + 'database values from\nthe lists, then click ' + + '\'Create dialog\' to create\na MessageDialog with ' + + 'these values as defaults.') + header.pack(padx = 10, pady = 10) + + # Create and pack the ComboBoxes to select options. + buttons = ( + "('OK',)", + "('Read', 'Write')", + "('OK', 'Cancel')", + "('OK', 'Apply', 'Cancel', 'Help')", + ) + + if Tkinter.TkVersion >= 8.4: + disabledState = 'readonly' + else: + disabledState = 'disabled' + + self._buttons = Pmw.ComboBox(parent, label_text = 'buttons:', + labelpos = 'w', + entry_state = disabledState, + scrolledlist_items = buttons) + self._buttons.pack(fill = 'x', expand = 1, padx = 8, pady = 8) + self._buttons.selectitem(3) + + buttonboxpos = ('n', 's', 'e', 'w',) + self._buttonboxpos = Pmw.ComboBox(parent, label_text = 'buttonboxpos:', + labelpos = 'w', + entry_state = disabledState, + scrolledlist_items = buttonboxpos) + self._buttonboxpos.pack(fill = 'x', expand = 1, padx = 8, pady = 8) + self._buttonboxpos.selectitem(2) + + pad = ('0', '8', '20', '50',) + self._pad = Pmw.ComboBox(parent, label_text = 'padx, pady:', + labelpos = 'w', + entry_state = disabledState, + scrolledlist_items = pad) + self._pad.pack(fill = 'x', expand = 1, padx = 8, pady = 8) + self._pad.selectitem(1) + + Pmw.alignlabels((self._buttons, self._buttonboxpos, self._pad)) + + # Create button to launch the dialog. + w = Tkinter.Button(parent, text = 'Create dialog', + command = self._createDialog) + w.pack(padx = 8, pady = 8) + + self.dialog = None + + def _createDialog(self): + + # Set the option database. + buttons = self._buttons.get() + buttonboxpos = self._buttonboxpos.get() + pad = self._pad.get() + self.parent.option_add('*MessageDialog.buttons', buttons) + self.parent.option_add('*MessageDialog.buttonboxpos', buttonboxpos) + self.parent.option_add('*ButtonBox.padx', pad) + self.parent.option_add('*ButtonBox.pady', pad) + + # Create the dialog. + if self.dialog is not None: + self.dialog.destroy() + + text = ('This dialog was created by setting the Tk ' + + 'option database:\n\n *MessageDialog.buttons: ' + buttons + + '\n *MessageDialog.buttonboxpos: ' + buttonboxpos + + '\n *ButtonBox.padx: ' + pad + + '\n *ButtonBox.pady: ' + pad) + self.dialog = Pmw.MessageDialog(self.parent, + defaultbutton = 0, + title = 'Pmw option database demonstration', + message_justify = 'left', + message_text = text) + self.dialog.iconname('Test dialog') + + # Return the defaults to normal, otherwise all other demos + # will be affected. + self.parent.option_add('*MessageDialog.buttons', "('OK',)") + self.parent.option_add('*MessageDialog.buttonboxpos', 's') + self.parent.option_add('*ButtonBox.padx', 8) + self.parent.option_add('*ButtonBox.pady', 8) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root, useTkOptionDb = 1) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledCanvas.py b/Pmw/Pmw_1_2/demos/ScrolledCanvas.py new file mode 100644 index 00000000..28933ec5 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledCanvas.py @@ -0,0 +1,124 @@ +title = 'Pmw.ScrolledCanvas demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledField.py b/Pmw/Pmw_1_2/demos/ScrolledField.py new file mode 100644 index 00000000..b3a268df --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledField.py @@ -0,0 +1,51 @@ +title = 'Pmw.ScrolledField demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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', +) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledFrame.py b/Pmw/Pmw_1_2/demos/ScrolledFrame.py new file mode 100644 index 00000000..06880df1 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledFrame.py @@ -0,0 +1,157 @@ +title = 'Pmw.ScrolledFrame demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create the ScrolledFrame. + self.sf = Pmw.ScrolledFrame(parent, + labelpos = 'n', label_text = 'ScrolledFrame', + usehullsize = 1, + hull_width = 400, + hull_height = 220, + ) + + # Create a group widget to contain the flex options. + w = Pmw.Group(parent, tag_text='Flex') + w.pack(side = 'bottom', padx = 5, pady = 3) + + hflex = Pmw.OptionMenu(w.interior(), + labelpos = 'w', + label_text = 'Horizontal:', + items = ['fixed', 'expand', 'shrink', 'elastic'], + command = self.sethflex, + menubutton_width = 8, + ) + hflex.pack(side = 'left', padx = 5, pady = 3) + hflex.invoke('fixed') + + vflex = Pmw.OptionMenu(w.interior(), + labelpos = 'w', + label_text = 'Vertical:', + items = ['fixed', 'expand', 'shrink', 'elastic'], + command = self.setvflex, + menubutton_width = 8, + ) + vflex.pack(side = 'left', padx = 5, pady = 3) + vflex.invoke('fixed') + + # Create a group widget to contain the scrollmode options. + w = Pmw.Group(parent, tag_text='Scroll mode') + w.pack(side = 'bottom', padx = 5, pady = 0) + + 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 = 3) + 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 = 3) + vmode.invoke('dynamic') + + self.radio = Pmw.RadioSelect(parent, selectmode = 'multiple', + command = self.radioSelected) + self.radio.add('center', text = 'Keep centered vertically') + self.radio.pack(side = 'bottom') + + buttonBox = Pmw.ButtonBox(parent) + buttonBox.pack(side = 'bottom') + buttonBox.add('add', text = 'Add a button', command = self.addButton) + buttonBox.add('yview', text = 'Show yview', command = self.showYView) + buttonBox.add('scroll', text = 'Page down', command = self.pageDown) + + # Pack this last so that the buttons do not get shrunk when + # the window is resized. + self.sf.pack(padx = 5, pady = 3, fill = 'both', expand = 1) + + self.frame = self.sf.interior() + + self.row = 0 + self.col = 0 + + for count in range(15): + self.addButton() + + def sethscrollmode(self, tag): + self.sf.configure(hscrollmode = tag) + + def setvscrollmode(self, tag): + self.sf.configure(vscrollmode = tag) + + def sethflex(self, tag): + self.sf.configure(horizflex = tag) + + def setvflex(self, tag): + self.sf.configure(vertflex = tag) + + def addButton(self): + button = Tkinter.Button(self.frame, + text = '(%d,%d)' % (self.col, self.row)) + button.grid(row = self.row, column = self.col, sticky = 'nsew') + + self.frame.grid_rowconfigure(self.row, weight = 1) + self.frame.grid_columnconfigure(self.col, weight = 1) + if self.sf.cget('horizflex') == 'expand' or \ + self.sf.cget('vertflex') == 'expand': + self.sf.reposition() + + if 'center' in self.radio.getcurselection(): + self.sf.update_idletasks() + self.centerPage() + + if self.col == self.row: + self.col = 0 + self.row = self.row + 1 + else: + self.col = self.col + 1 + + def showYView(self): + print self.sf.yview() + + def pageDown(self): + self.sf.yview('scroll', 1, 'page') + + def radioSelected(self, name, state): + if state: + self.centerPage() + + def centerPage(self): + # Example of how to use the yview() method of Pmw.ScrolledFrame. + top, bottom = self.sf.yview() + size = bottom - top + middle = 0.5 - size / 2 + self.sf.yview('moveto', middle) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + import os + if os.name == 'nt': + size = 16 + else: + size = 12 + root = Tkinter.Tk() + Pmw.initialise(root, size = size, fontScheme = 'pmw2') + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledListBox.py b/Pmw/Pmw_1_2/demos/ScrolledListBox.py new file mode 100644 index 00000000..f2f7d9d6 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledListBox.py @@ -0,0 +1,118 @@ +title = 'Pmw.ScrolledListBox demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledText.py b/Pmw/Pmw_1_2/demos/ScrolledText.py new file mode 100644 index 00000000..aae02ea2 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledText.py @@ -0,0 +1,99 @@ +title = 'Pmw.ScrolledText demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import os +import math +import string +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + # Create the ScrolledText with headers. + fixedFont = Pmw.logicalfont('Fixed') + self.st = Pmw.ScrolledText(parent, + # borderframe = 1, + labelpos = 'n', + label_text='ScrolledText with headers', + columnheader = 1, + rowheader = 1, + rowcolumnheader = 1, + usehullsize = 1, + hull_width = 400, + hull_height = 300, + text_wrap='none', + text_font = fixedFont, + Header_font = fixedFont, + Header_foreground = 'blue', + rowheader_width = 3, + rowcolumnheader_width = 3, + text_padx = 4, + text_pady = 4, + Header_padx = 4, + rowheader_pady = 4, + ) + + self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1) + + funcs = 'atan cos cosh exp log log10 sin sinh sqrt tan tanh' + funcs = string.split(funcs) + + # Create the header for the row headers + self.st.component('rowcolumnheader').insert('end', 'x') + + # Create the column headers + headerLine = '' + for column in range(len(funcs)): + headerLine = headerLine + ('%-7s ' % (funcs[column],)) + headerLine = headerLine[:-3] + self.st.component('columnheader').insert('0.0', headerLine) + + self.st.tag_configure('yellow', background = 'yellow') + + # Create the data rows and the row headers + numRows = 50 + tagList = [] + for row in range(1, numRows): + dataLine = '' + x = row / 5.0 + for column in range(len(funcs)): + value = eval('math.' + funcs[column] + '(' + str(x) + ')') + data = str(value)[:7] + if value < 0: + tag1 = '%d.%d' % (row, len(dataLine)) + tag2 = '%d.%d' % (row, len(dataLine) + len(data)) + tagList.append(tag1) + tagList.append(tag2) + data = '%-7s' % (data,) + dataLine = dataLine + data + ' ' + dataLine = dataLine[:-3] + header = '%.1f' % (x,) + if row < numRows - 1: + dataLine = dataLine + '\n' + header = header + '\n' + self.st.insert('end', dataLine) + self.st.component('rowheader').insert('end', header) + apply(self.st.tag_add, ('yellow',) + tuple(tagList)) + + # Prevent users' modifying text and headers + self.st.configure( + text_state = 'disabled', + Header_state = 'disabled', + ) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ScrolledText_2.py b/Pmw/Pmw_1_2/demos/ScrolledText_2.py new file mode 100644 index 00000000..cffb733a --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ScrolledText_2.py @@ -0,0 +1,99 @@ +title = 'Pmw.ScrolledText demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import os +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create the ScrolledText. + self.st = Pmw.ScrolledText(parent, + borderframe = 1, + labelpos = 'n', + label_text='ScrolledText.py', + usehullsize = 1, + hull_width = 400, + hull_height = 300, + text_padx = 10, + text_pady = 10, + text_wrap='none' + ) + + # 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.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1) + + # Read this file into the text widget. + head, tail = os.path.split(sys.argv[0]) + self.st.importfile(os.path.join(head,'ScrolledText.py')) + + self.st.insert('end', '\nThis demonstrates how to\n' + + 'add a window to a text widget: ') + counter = Pmw.Counter(self.st.component('text'), + entryfield_value = 9999) + self.st.window_create('end', window = counter) + + def sethscrollmode(self, tag): + self.st.configure(hscrollmode = tag) + + def setvscrollmode(self, tag): + self.st.configure(vscrollmode = tag) + + def showYView(self): + print self.st.yview() + + def pageDown(self): + self.st.yview('scroll', 1, 'page') + + def centerPage(self): + top, bottom = self.st.yview() + size = bottom - top + middle = 0.5 - size / 2 + self.st.yview('moveto', middle) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/SelectionDialog.py b/Pmw/Pmw_1_2/demos/SelectionDialog.py new file mode 100644 index 00000000..12fea94d --- /dev/null +++ b/Pmw/Pmw_1_2/demos/SelectionDialog.py @@ -0,0 +1,47 @@ +title = 'Pmw.SelectionDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create the dialog. + self.dialog = Pmw.SelectionDialog(parent, + title = 'My SelectionDialog', + buttons = ('OK', 'Cancel'), + defaultbutton = 'OK', + scrolledlist_labelpos = 'n', + label_text = 'What do you think of Pmw?', + scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'), + command = self.execute) + self.dialog.withdraw() + + # Create button to launch the dialog. + w = Tkinter.Button(parent, text = 'Show selection dialog', + command = self.dialog.activate) + w.pack(padx = 8, pady = 8) + + def execute(self, result): + sels = self.dialog.getcurselection() + if len(sels) == 0: + print 'You clicked on', result, '(no selection)' + else: + print 'You clicked on', result, sels[0] + self.dialog.deactivate(result) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/ShowBusy.py b/Pmw/Pmw_1_2/demos/ShowBusy.py new file mode 100644 index 00000000..831b7a56 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/ShowBusy.py @@ -0,0 +1,48 @@ +title = 'Blt busy cursor demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + self.parent = parent + + if Pmw.Blt.havebltbusy(parent): + text = 'Click here to show the\nbusy cursor for one second.' + else: + text = 'Sorry\n' \ + 'Either the BLT package has not\n' \ + 'been installed on this system or\n' \ + 'it does not support the busy command.\n' \ + 'Clicking on this button will pause\n' \ + 'for one second but will not display\n' \ + 'the busy cursor.' + + button = Tkinter.Button(parent, + text = text, + command = Pmw.busycallback(self.sleep, parent.update)) + button.pack(padx = 10, pady = 10) + + entry = Tkinter.Entry(parent, width = 30) + entry.insert('end', 'Try to enter some text while busy.') + entry.pack(padx = 10, pady = 10) + + def sleep(self): + self.parent.after(1000) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/SpecialCounter.py b/Pmw/Pmw_1_2/demos/SpecialCounter.py new file mode 100644 index 00000000..a76645a1 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/SpecialCounter.py @@ -0,0 +1,68 @@ +title = 'Subclassing Pmw.Counter' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import time +import types +import Tkinter +import Pmw + +class LabeledDateCounter(Pmw.Counter): + + def __init__(self, parent=None , **kw): + + # Need to use long ints here because on the Macintosh the maximum size + # of an integer is smaller than the value returned by time.time(). + now = (long(time.time()) / 300) * 300 + text = time.strftime('%y/%m/%d', time.localtime(now)) + + kw['datatype'] = 'date' + kw['entryfield_validate'] = 'date' + kw['entryfield_value'] = text + kw['labelpos'] = 'w' + + apply(Pmw.Counter.__init__, (self, parent), kw) + +class LabeledRealCounter(Pmw.Counter): + + def __init__(self, parent=None , **kw): + + # Define the validate option dictionary. + validate = {'validator' : 'real', 'min' : 0.0, 'max' : 100.0} + + kw['datatype'] = 'real' + kw['entryfield_validate'] = validate + kw['entryfield_value'] = 50.0 + kw['labelpos'] = 'w' + + apply(Pmw.Counter.__init__, (self, parent), kw) + +class Demo: + def __init__(self, parent): + # Create and pack some LabeledDateCounters and LabeledRealCounter. + self._date1 = LabeledDateCounter(parent, label_text = 'Date:') + self._date2 = LabeledDateCounter(parent, label_text = 'Another Date:') + self._real1 = LabeledRealCounter(parent, label_text = 'Real:') + self._real2 = LabeledRealCounter(parent, label_text = 'Another Real:') + + counters = (self._date1, self._date2, self._real1, self._real2) + + for counter in counters: + counter.pack(fill='x', expand=1, padx=10, pady=5) + Pmw.alignlabels(counters) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/SpecialEntry.py b/Pmw/Pmw_1_2/demos/SpecialEntry.py new file mode 100644 index 00000000..270780b5 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/SpecialEntry.py @@ -0,0 +1,170 @@ +title = 'Subclassing Pmw.EntryField' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import time +import types +import Tkinter +import Pmw + +class SpecialEntry(Pmw.EntryField): + + def __init__(self, parent=None , **kw): + + kw['extravalidators'] = _myValidators + apply(Pmw.EntryField.__init__, (self, parent), kw) + self._converter = None + + def setentry(self, text): + # Override Pmw.EntryField.setentry to pass string through + # the appropriate converter. + + val = self['validate'] + if type(val) == types.DictionaryType: + val = val['validator'] + if _converters.has_key(val): + text = _converters[val](text, output = 0) + Pmw.EntryField.setentry(self, text) + + def getentry(self): + text = self.get() + val = self['validate'] + if type(val) == types.DictionaryType: + val = val['validator'] + if _converters.has_key(val): + return _converters[val](text, output = 1) + else: + return text + +def _date(text): + return Pmw.datevalidator(text, 'dmy', '.') + +def _real(text): + return Pmw.realvalidator(text, ',') + +def _dateconv(text, output = 0): + # On output, convert from dd.mm.yy to mm-dd-yy. On input, convert + # mm-dd-yy to dd.mm.yy and also from +NN+ or -NN- to date NN days + # before or after today. + + if len(text) == 0: + return '' + if output: + try: + d = string.split(text, '.') + return d[1] + '-' + d[0] + '-' + d[2] + except: + return text + else: + if text[-1] == '+' or text[-1] == '-': + text = text[:-1] + if text[0] == '+' or text[0] == '-': + secondsAhead = string.atoi(text) * 3600 * 24 + return time.strftime('%d.%m.%Y', + time.localtime(time.time() + secondsAhead)) + try: + d = string.split(text,'-') + return d[1] + '.' + d[0] + '.' + d[2] + except: + return text + +def _realconv(text, output = 0): + # Convert between DD.DD and DD,DD. + + if output: + index = string.find(text, ',') + if index >= 0: + return text[:index] + '.' + text[index + 1:] + else: + return text + else: + index = string.find(text, '.') + if index >= 0: + return text[:index] + ',' + text[index + 1:] + else: + return text + + +_converters = { + 'real' : _realconv, + 'float8' : _realconv, + 'date' : _dateconv +} + +_myValidators = { + 'date' : (_date, lambda s: Pmw.datestringtojdn(s, 'dmy', '.')), + 'real' : (_real, lambda s: string.atof(_realconv(s, 1))), + 'int4' : ('numeric', 'numeric'), + 'oid' : ('int4', 'int4'), + 'float8' : ('real', 'real'), + 'varchar' : ('alphanumeric', 'alphanumeric'), + 'text' : ('alphanumeric', 'alphanumeric'), +} + +class Demo: + def __init__(self, parent): + # Create and pack the SpecialEntry megawidgets. + self._any = SpecialEntry(parent, + labelpos = 'w', + label_text = 'Text (max 10 chars):', + validate = {'validator' : 'text', 'max' : 10}, + command = self.execute) + self._any.setentry('abc') + self._int = SpecialEntry(parent, + labelpos = 'w', + label_text = 'Int4:', + validate = 'int4') + self._int.setentry(1) + self._real = SpecialEntry(parent, + labelpos = 'w', + label_text = 'Real (max 2,5e+9):', + validate = {'validator' : 'real', 'max' : +2.5e+9}, + ) + self._real.setentry('+2.5e+6') + self._date = SpecialEntry(parent, + labelpos = 'w', + label_text = 'Date (dd.mm.yy):', + validate = 'date', + modifiedcommand = self.changed + ) + # Set entry to one week from now, using special intput format. + self._date.setentry('+7+') + + entries = (self._any, self._int, self._real, self._date) + + for entry in entries: + entry.pack(fill='x', expand=1, padx=10, pady=5) + Pmw.alignlabels(entries) + + self._any.component('entry').focus_set() + + def changed(self): + print 'Text changed, converted value is', self._date.getentry() + + def execute(self): + print 'Return pressed, value is', self._any.get() + + # This implements a custom validation routine. It simply checks + # if the string is of odd length. + def custom_validate(self, text): + print 'text:', text + if len(text) % 2 == 0: + return -1 + else: + return 1 + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/Spectrum.py b/Pmw/Pmw_1_2/demos/Spectrum.py new file mode 100644 index 00000000..cfef9791 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/Spectrum.py @@ -0,0 +1,166 @@ +title = 'Color spectrum demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + parent = Tkinter.Frame(parent) + parent.pack(padx=10, pady=10, fill='both', expand=1) + self.width = 350 + self.height = 250 + self.canvas = Tkinter.Canvas(parent, + width = self.width, height = self.height) + self.canvas.grid(row = 0, column = 0, columnspan = 2, sticky = 'news') + + self.numColors = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Number of colors:', + entry_width = 5, + validate = 'numeric', + command = Pmw.busycallback(self.execute)) + self.numColors.grid(row = 1, column = 0, sticky = 'ew') + + self.correction = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Correction:', + validate = 'real', + entry_width = 5, + command = Pmw.busycallback(self.execute)) + self.correction.grid(row = 1, column = 1, sticky = 'ew') + + self.saturation = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Saturation:', + validate = 'real', + entry_width = 5, + command = Pmw.busycallback(self.execute)) + self.saturation.grid(row = 2, column = 0, sticky = 'ew') + + self.intensity = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Intensity:', + validate = 'real', + entry_width = 5, + command = Pmw.busycallback(self.execute)) + self.intensity.grid(row = 2, column = 1, sticky = 'ew') + + self.extraOrange = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Emphasize orange (0 or 1):', + validate = {'validator' : 'numeric', 'min' : 0, 'max' : 1}, + entry_width = 5, + command = Pmw.busycallback(self.execute)) + self.extraOrange.grid(row = 3, column = 0, sticky = 'ew') + + self.text = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Text:', + entry_width = 20, + command = Pmw.busycallback(self.execute)) + self.text.grid(row = 4, column = 0, sticky = 'ew') + + self.brightness = Pmw.EntryField(parent, + labelpos = 'w', + label_text = 'Brightness:', + validate = 'real', + entry_width = 5, + command = Pmw.busycallback(self.execute)) + self.brightness.grid(row = 3, column = 1, sticky = 'ew') + + self.radiobuttons = Pmw.RadioSelect(parent, + command = Pmw.busycallback(self.radio_cb), + ) + self.radiobuttons.grid(row = 4, column = 1) + self.radiobuttons.add('Use saturation\nand intensity') + self.radiobuttons.add('Use\nbrightness') + + parent.grid_columnconfigure(0, weight = 1) + parent.grid_columnconfigure(1, weight = 1) + parent.grid_rowconfigure(0, weight = 1) + + Pmw.alignlabels((self.numColors, self.saturation, self.extraOrange)) + Pmw.alignlabels((self.correction, self.intensity, self.brightness)) + + # Set initial values for all entries. + self.numColors.setentry('64') + self.correction.setentry('1.0') + self.saturation.setentry('1.0') + self.intensity.setentry('1.0') + self.extraOrange.setentry('1') + self.brightness.setentry('0.7') + self.text.setentry('This is a test') + self.radiobuttons.invoke('Use saturation\nand intensity') + + self.execute() + + def radio_cb(self, value): + self.execute() + + def execute(self): + try: + numColors = string.atoi(self.numColors.get()) + correction = string.atof(self.correction.get()) + saturation = string.atof(self.saturation.get()) + intensity = string.atof(self.intensity.get()) + extraOrange = string.atof(self.extraOrange.get()) + brightness = string.atof(self.brightness.get()) + except ValueError: + self.numColors.bell() + return + + if numColors <= 0: + self.numColors.bell() + return + + self.canvas.delete('all') + + colorList = Pmw.Color.spectrum( + numColors, correction, saturation, intensity, extraOrange) + extent = 360.0 / numColors + + useBrightness = \ + (self.radiobuttons.getcurselection() == 'Use\nbrightness') + + if numColors == 1: + # Special case circle, since create_arc does not work when + # extent is 360. + background = colorList[0] + if useBrightness: + background = Pmw.Color.changebrightness( + self.canvas, background, brightness) + self.canvas.create_oval(10, 10, self.width - 10, self.height - 10, + fill = background, outline = background) + + for index in range(numColors): + start = index * extent - extent / 2 + background = colorList[index] + if useBrightness: + background = Pmw.Color.changebrightness( + self.canvas, background, brightness) + self.canvas.create_arc(10, 10, self.width - 10, self.height - 10, + start = start, extent = extent, + fill = background, outline = background) + + text = self.text.get() + self.canvas.create_text(self.width / 2, self.height / 3, text = text) + self.canvas.create_text(self.width / 2, self.height / 2, text = text) + self.canvas.create_text(self.width / 2, 2 * self.height / 3, text = text) + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/SpeedTest.py b/Pmw/Pmw_1_2/demos/SpeedTest.py new file mode 100644 index 00000000..589486bb --- /dev/null +++ b/Pmw/Pmw_1_2/demos/SpeedTest.py @@ -0,0 +1,60 @@ +title = 'Test of the speed of creating Pmw megawidgets' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import time +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + self.parent = parent + + message = 'This is a test of the time\n' + \ + 'it takes to create 20 Pmw\nEntryField megawidgets.\n' + \ + 'Click on the button to create them.' + w = Tkinter.Label(parent, text = message) + w.pack(padx = 8, pady = 8) + + # Create button to run speed test. + w = Tkinter.Button(parent, + text = 'Create 20 EntryFields', + command = self.createEntries) + w.pack(padx = 8, pady = 8) + + def createEntries(self): + entryTop = Tkinter.Toplevel(self.parent) + + startClock = time.clock() + fields = [] + for num in range(20): + field = Pmw.EntryField(entryTop, + labelpos = 'w', + label_text='*' + ('*' * num), + hull_background = 'lightsteelblue', + label_background = 'lightsteelblue', + hull_highlightbackground = 'lightsteelblue', + label_highlightbackground = 'lightsteelblue', + entry_highlightbackground = 'lightsteelblue', + entry_background = 'aliceblue') + field.pack() + fields.append(field) + + Pmw.alignlabels(fields) + print 'Time to create 20 EntryFields:', \ + time.clock() - startClock, 'seconds' + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/SubClassing.py b/Pmw/Pmw_1_2/demos/SubClassing.py new file mode 100644 index 00000000..f538b59e --- /dev/null +++ b/Pmw/Pmw_1_2/demos/SubClassing.py @@ -0,0 +1,128 @@ +title = 'More examples of subclassing' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class ExtraMethods(Pmw.EntryField): + + # How to subclass a Pmw megawidget when you only want to add or + # override methods. + + def doubletext(self): + self.setvalue(self.getvalue() + ' ' + self.getvalue()) + +class OverrideInit(Pmw.EntryField): + + # How to subclass a Pmw megawidget when you want to define + # a new __init__ method. + + def __init__(self, textToAdd, parent = None, **kw): + self._textToAdd = textToAdd + apply(Pmw.EntryField.__init__, (self, parent), kw) + + def addtext(self): + self.setvalue(self.getvalue() + ' ' + self._textToAdd) + +class DefaultOptions(Pmw.EntryField): + + # How to subclass a Pmw megawidget when you only want to set + # existing options to new default values. + + def __init__(self, parent = None, **kw): + kw['label_foreground'] = 'blue' + kw['entry_background'] = 'white' + apply(Pmw.EntryField.__init__, (self, parent), kw) + +class NewOptions(Pmw.EntryField): + + # How to subclass a Pmw megawidget when you want to add new options. + + def __init__(self, parent=None , **kw): + + # Define the megawidget options. + optiondefs = ( + ('backgrounds', None, self._backgrounds), + ) + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.EntryField.__init__(self, parent) + + # Check keywords and initialise options. + self.initialiseoptions() + + def _backgrounds(self): + background = self['backgrounds'] + Pmw.Color.changecolor(self.component('hull'), background) + +class Demo: + def __init__(self, parent): + # Create and pack the megawidgets. + self._extraMethod = ExtraMethods(parent, + labelpos = 'w', + label_text = 'Sub class with extra method:', + value = 'Hello' + ) + self._overrideInit = OverrideInit('Again', parent, + labelpos = 'w', + label_text = 'Sub class with new __init__ method:', + value = 'Hello' + ) + self._defaultOptions = DefaultOptions(parent, + labelpos = 'w', + label_text = 'Sub class with new default options:', + value = 'Hello' + ) + + self._newOptions = NewOptions(parent, + labelpos = 'w', + label_text = 'Sub class with new option:', + value = 'Hello', + backgrounds = 'white', + ) + + entries = (self._extraMethod, self._overrideInit, + self._defaultOptions, self._newOptions) + + for entry in entries: + entry.pack(fill='x', expand=1, padx=10, pady=5) + Pmw.alignlabels(entries) + + bb = Pmw.ButtonBox(parent) + bb.add('Double text', command = self._doubleText) + bb.pack() + bb.add('Add text', command = self._addText) + bb.pack() + bb.add('White', command = self._changeColorWhite) + bb.pack() + bb.add('Green', command = self._changeColorGreen) + bb.pack() + + def _doubleText(self): + self._extraMethod.doubletext() + + def _addText(self): + self._overrideInit.addtext() + + def _changeColorWhite(self): + self._newOptions.configure(backgrounds = 'white') + + def _changeColorGreen(self): + self._newOptions.configure(backgrounds = 'green') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/TextDialog.py b/Pmw/Pmw_1_2/demos/TextDialog.py new file mode 100644 index 00000000..adec8214 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/TextDialog.py @@ -0,0 +1,75 @@ +title = 'Pmw.TextDialog demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +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. + +""" +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/TextDisplay.py b/Pmw/Pmw_1_2/demos/TextDisplay.py new file mode 100644 index 00000000..0eadf525 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/TextDisplay.py @@ -0,0 +1,78 @@ +title = 'Demonstration of how to create a megawidget' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class TextDisplay(Pmw.MegaWidget): + + # Demo Pmw megawidget. + + def __init__(self, parent = None, **kw): + + # Define the megawidget options. + optiondefs = () + self.defineoptions(kw, optiondefs) + + # Initialise the base class (after defining the options). + Pmw.MegaWidget.__init__(self, parent) + + # Create the components. + interior = self.interior() + + self._text = self.createcomponent('text', + (), None, + Tkinter.Text, (interior,), state = 'disabled') + self._text.pack(side='left', fill='both', expand='yes') + + self._scrollbar = self.createcomponent('scrollbar', + (), None, + Tkinter.Scrollbar, (interior,), command = self._text.yview) + self._scrollbar.pack(side='right', fill='y') + self._text.configure(yscrollcommand = self._scrollbar.set) + + # Check keywords and initialise options. + self.initialiseoptions() + + def display(self, info): + self._text.configure(state = 'normal') + self._text.delete('1.0', 'end') + self._text.insert('1.0', info) + self._text.configure(state = 'disabled') + + def append(self, info): + self._text.configure(state = 'normal') + self._text.insert('end', info) + self._text.configure(state = 'disabled') + +class Demo: + def __init__(self, parent): + # Create and pack the megawidget. + text = TextDisplay(parent, + text_background = 'aliceblue', + text_width = 40, + text_height = 10, + text_wrap = 'none', + ) + text.pack(fill = 'both', expand = 1) + text.display('This is an example of a simple Pmw megawidget.\n\n' + + 'Public attributes of the Tkinter module:\n\n') + for name in dir(Tkinter): + if name[0] != '_': + text.append(' ' + name + '\n') + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/TimeCounter.py b/Pmw/Pmw_1_2/demos/TimeCounter.py new file mode 100644 index 00000000..7be1eb36 --- /dev/null +++ b/Pmw/Pmw_1_2/demos/TimeCounter.py @@ -0,0 +1,40 @@ +title = 'Pmw.TimeCounter demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import string +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + self._time = Pmw.TimeCounter(parent, + labelpos = 'w', + label_text = 'HH:MM:SS', + min = '00:00:00', + max = '23:59:59') + self._time.pack(padx=10, pady=5) + + button = Tkinter.Button(parent, text = 'Show', command = self.show) + button.pack() + + def show(self): + stringVal = self._time.getstring() + intVal = self._time.getint() + print stringVal + ' (' + str(intVal) + ')' + + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/demos/WidgetDestroy.py b/Pmw/Pmw_1_2/demos/WidgetDestroy.py new file mode 100644 index 00000000..a62fa28c --- /dev/null +++ b/Pmw/Pmw_1_2/demos/WidgetDestroy.py @@ -0,0 +1,36 @@ +title = 'Demonstration of Pmw megawidget destruction' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + # Create and pack an EntryField. + self.entryfield = Pmw.EntryField(parent, + command = self.execute, + value = 'Press to destroy me', + entry_width = 30) + self.entryfield.pack(fill='x', expand=1, padx=10, pady=5) + + self.entryfield.component('entry').focus_set() + + def execute(self): + print 'Return pressed, destroying EntryField.' + self.entryfield.destroy() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/doc/AboutDialog.gif b/Pmw/Pmw_1_2/doc/AboutDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..2d60dc59f458da079d1f6904951a8caa2a13143b GIT binary patch literal 4081 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/AboutDialog.html b/Pmw/Pmw_1_2/doc/AboutDialog.html new file mode 100644 index 00000000..8f487d5b --- /dev/null +++ b/Pmw/Pmw_1_2/doc/AboutDialog.html @@ -0,0 +1,286 @@ + + + + + + Pmw.AboutDialog reference manual + + + + +

Pmw.AboutDialog

+ +
+
+

Name

+

Pmw.AboutDialog() - + window to display version and contact information +

+ + +
+

Inherits

+Pmw.MessageDialog
+
+

Description

+

+ An about dialog is a dialog window which displays information + about the application, such as name, version, copyright and + contact details.

+ +

The text of the message is constructed from the application name + (given by the applicationname option) followed by the values + supplied in the most recent calls to Pmw.aboutversion(), + Pmw.aboutcopyright() and Pmw.aboutcontact() functions.

+ +

The icon of the message defaults to 'info', but may be changed + using the icon_bitmap component option.

+ +

+ + +
+

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.

+ + +
+ +
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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/Balloon.gif b/Pmw/Pmw_1_2/doc/Balloon.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8bc9b81b311bd76bfc2f71652988e1735741b72 GIT binary patch literal 4660 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 H0G + + + + Pmw.Balloon reference manual + + + + +

Pmw.Balloon

+ +
+
+

Name

+

Pmw.Balloon() - + display "tool tips" for a number of widgets +

+ + +
+

Inherits

+Pmw.MegaToplevel
+
+

Description

+

+ 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.

+ + +
+ +
tagbind(widget, tagOrItem, balloonHelp, statusHelp = None)
+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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/Blt.html b/Pmw/Pmw_1_2/doc/Blt.html new file mode 100644 index 00000000..99869840 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/Blt.html @@ -0,0 +1,135 @@ + + + + + + Pmw.Blt reference manual + + + + +

Pmw.Blt

+ +
+

Name

+

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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ButtonBox.gif b/Pmw/Pmw_1_2/doc/ButtonBox.gif new file mode 100644 index 0000000000000000000000000000000000000000..402b6b0e22ae9cb51601c6ed8c82bae50a8441a6 GIT binary patch literal 964 zcmV;#13UajNk%v~VJQJY0Pz3-|Ns90007z9*@A+CEC2ui04V`M00091l#i*)?GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDSW83>2OqVb4KDwoWr^9hYgr_`$T zI=~D7+^+Wv4vWX+viXcotJmzd`wfq40l>Qb{@Kp){J#I8cMuH z*eE&a5*cAhnW;H~2}qZK6)H-!S(^80@t8G}FAntk$5rY`dBaUG_W?T^&YCZLQ6P4Jv%;-1}W8)SFFMUcrUljlj&nE3p2TKCUqD zmrjA-r?2q7ARa$H_0G|22VvkLgtP4J3MbE@kAe~u-tkvaVh{d|?lcC3XweSE2qDQa zbWjoq#{&TWf%LdzWI~uaRz67i!=`|i-u{VWXD%a9bu=BFgLCwO8~z9H|yYlGNUeOtso`LIiwu^m<;Fn)#DRwa2 zYvsvEV2;a)w~t2wrU;~tEJg^ATmo_S)LtK|m_dzr6{X*G%1zl;hAfeY0A;FGM^3n^kV+R^)E8R7j9w9Dbmmf`VXq zz?wC=*czFEibfSv7b=M6EQkWSkc9VbHk6u3IyflV=EEo? zj%K=HtFXS>PprAjx+G-ZIhNx8fo(Y@=q4i*6Cz;+1Z@m&)UAy5-8MR4usNORu$mvVw2Fo}jwLHUfL$ zZ^5VPYjDD@Y*&`T4lg|B!xC@8@J^pjjIkpTXUwr76<6GG$TWNmK)fcOjB?5>*D mF24+O%rZwKa?Lj1jC0O9@62=0KK~4K&_WMQbkTSe0029c7wV}1 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/ButtonBox.html b/Pmw/Pmw_1_2/doc/ButtonBox.html new file mode 100644 index 00000000..2075f42f --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ButtonBox.html @@ -0,0 +1,306 @@ + + + + + + Pmw.ButtonBox reference manual + + + + +

Pmw.ButtonBox

+ +
+
+

Name

+

Pmw.ButtonBox() - + manager megawidget for buttons +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/Color.html b/Pmw/Pmw_1_2/doc/Color.html new file mode 100644 index 00000000..e004f85e --- /dev/null +++ b/Pmw/Pmw_1_2/doc/Color.html @@ -0,0 +1,326 @@ + + + + + + Pmw.Color reference manual + + + + +

Pmw.Color

+ +
+

Name

+

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.

+ +

+ + +
+
Pmw.Color.bhi2saturation(brightness, hue, intensity)
+ + 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.

+ +

+ + +
+
Pmw.Color.changebrightness(root, colorName, brightness)
+ + 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.

+ +

+ + +
+
Pmw.Color.changecolor(widget, background = None, **kw)
+ + 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:

+ +
 Pmw.Color.changecolor(widget,
+     background = 'red3', foreground = 'white')
+ +

The colors of widgets created after this call will not be + affected.

+ +

Note that widget must be a Tk widget or toplevel. To change the + color of a Pmw megawidget, use it's hull component. For example:

+ +
 widget = megawidget.component('hull')
+ Pmw.Color.changecolor(widget, background = 'red3')
+ +

+ + +
+
Pmw.Color.correct(rgb, correction)
+ + 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:

+ +
 root = megawidget.component('hull')
+ Pmw.Color.getdefaultpalette(root)
+ +

+ + +
+
Pmw.Color.hsi2rgb(hue, saturation, intensity)
+ + 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.

+ +

+ + +
+
Pmw.Color.setscheme(root, background = None, **kw)
+ + 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:

+ +
 Pmw.Color.setscheme(root,
+     background = 'red3', foreground = 'white')
+ +

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:

+ +
 root = megawidget.component('hull')
+ Pmw.Color.setscheme(root, background = 'red3')
+ +

+ + +
+
Pmw.Color.spectrum(numColors, correction = 1.0, saturation = 1.0, intensity = 1.0, extraOrange = 1, returnHues = 0)
+ + 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ComboBox.gif b/Pmw/Pmw_1_2/doc/ComboBox.gif new file mode 100644 index 0000000000000000000000000000000000000000..31fee77ce66cbde5ec9204d9aa8cc656affa3d77 GIT binary patch literal 4556 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/ComboBox.html b/Pmw/Pmw_1_2/doc/ComboBox.html new file mode 100644 index 00000000..0be8d68c --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ComboBox.html @@ -0,0 +1,363 @@ + + + + + + Pmw.ComboBox reference manual + + + + +

Pmw.ComboBox

+ +
+
+

Name

+

Pmw.ComboBox() - + dropdown or simple combination box +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        parent.configure(background = 'white')
+
+        # Create and pack the widget to be configured.
+        self.target = Tkinter.Label(parent,
+                relief = 'sunken',
+                padx = 20,
+                pady = 20,
+        )
+        self.target.pack(fill = 'x', padx = 8, pady = 8)
+
+        # Create and pack the simple ComboBox.
+        words = ('Monti', 'Python', 'ik', 'den', 'Holie', 'Grailen', '(Bok)')
+        simple = Pmw.ComboBox(parent,
+                label_text = 'Simple ComboBox:',
+                labelpos = 'nw',
+                selectioncommand = self.changeText,
+                scrolledlist_items = words,
+                dropdown = 0,
+        )
+        simple.pack(side = 'left', fill = 'both',
+                expand = 1, padx = 8, pady = 8)
+
+        # Display the first text.
+        first = words[0]
+        simple.selectitem(first)
+        self.changeText(first)
+
+        # Create and pack the dropdown ComboBox.
+        colours = ('cornsilk1', 'snow1', 'seashell1', 'antiquewhite1',
+                'bisque1', 'peachpuff1', 'navajowhite1', 'lemonchiffon1',
+                'ivory1', 'honeydew1', 'lavenderblush1', 'mistyrose1')
+        dropdown = Pmw.ComboBox(parent,
+                label_text = 'Dropdown ComboBox:',
+                labelpos = 'nw',
+                selectioncommand = self.changeColour,
+                scrolledlist_items = colours,
+        )
+        dropdown.pack(side = 'left', anchor = 'n',
+                fill = 'x', expand = 1, padx = 8, pady = 8)
+
+        # Display the first colour.
+        first = colours[0]
+        dropdown.selectitem(first)
+        self.changeColour(first)
+
+    def changeColour(self, colour):
+        print 'Colour: ' + colour
+        self.target.configure(background = colour)
+
+    def changeText(self, text):
+        print 'Text: ' + text
+        self.target.configure(text = text)
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 1 November 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ComboBoxDialog.gif b/Pmw/Pmw_1_2/doc/ComboBoxDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..011fde577b4abeabf72ef62d21e9ac014ad054e7 GIT binary patch literal 3484 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 KDOv;(002A0O%uHU literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/ComboBoxDialog.html b/Pmw/Pmw_1_2/doc/ComboBoxDialog.html new file mode 100644 index 00000000..e139f11c --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ComboBoxDialog.html @@ -0,0 +1,286 @@ + + + + + + Pmw.ComboBoxDialog reference manual + + + + +

Pmw.ComboBoxDialog

+ +
+
+

Name

+

Pmw.ComboBoxDialog() - + selection dialog displaying a list and an entry field +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        # Create the dialog.
+        self.dialog = Pmw.ComboBoxDialog(parent,
+            title = 'My ComboBoxDialog',
+            buttons = ('OK', 'Cancel'),
+            defaultbutton = 'OK',
+            combobox_labelpos = 'n',
+            label_text = 'What do you think of Pmw?',
+            scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'))
+        self.dialog.withdraw()
+
+        # Create button to launch the dialog.
+        w = Tkinter.Button(parent,
+                text = 'Show combo box dialog',
+                command = self.doit)
+        w.pack(padx = 8, pady = 8)
+
+    def doit(self):
+        result = self.dialog.activate()
+        print 'You clicked on', result, self.dialog.get()
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 18 May 2002 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/Counter.gif b/Pmw/Pmw_1_2/doc/Counter.gif new file mode 100644 index 0000000000000000000000000000000000000000..20c33222fcea9225f4a5b5512068c59e6ae36946 GIT binary patch literal 2212 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/Counter.html b/Pmw/Pmw_1_2/doc/Counter.html new file mode 100644 index 00000000..a52595e8 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/Counter.html @@ -0,0 +1,455 @@ + + + + + + Pmw.Counter reference manual + + + + +

Pmw.Counter

+ +
+
+

Name

+

Pmw.Counter() - + entry field with up and down arrow buttons +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        # Need to use long ints here because on the Macintosh the maximum size
+        # of an integer is smaller than the value returned by time.time().
+        now = (long(time.time()) / 300) * 300
+
+        # Create the Counters.
+        self._date = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'Date (4-digit year):',
+                entryfield_value =
+                        time.strftime('%d/%m/%Y', time.localtime(now)),
+                entryfield_command = self.execute,
+                entryfield_validate = {'validator' : 'date', 'format' : 'dmy'},
+                datatype = {'counter' : 'date', 'format' : 'dmy', 'yyyy' : 1})
+
+        self._isodate = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'ISO-Date (4-digit year):',
+                entryfield_value =
+                        time.strftime('%Y-%m-%d', time.localtime(now)),
+                entryfield_command = self.execute,
+                entryfield_validate = {'validator' : 'date', 'format' : 'ymd',
+                        'separator' : '-' },
+                datatype = {'counter' : 'date', 'format' : 'ymd', 'yyyy' : 1,
+                        'separator' : '-' })
+
+        self._time = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'Time:',
+                entryfield_value =
+                        time.strftime('%H:%M:%S', time.localtime(now)),
+                entryfield_validate = {'validator' : 'time',
+                        'min' : '00:00:00', 'max' : '23:59:59',
+                        'minstrict' : 0, 'maxstrict' : 0},
+                datatype = {'counter' : 'time', 'time24' : 1},
+                increment=5*60)
+        self._real = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'Real (with comma)\nand extra\nlabel lines:',
+                label_justify = 'left',
+                entryfield_value = '1,5',
+                datatype = {'counter' : 'real', 'separator' : ','},
+                entryfield_validate = {'validator' : 'real',
+                        'min' : '-2,0', 'max' : '5,0',
+                        'separator' : ','},
+                increment = 0.1)
+        self._custom = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'Custom:',
+                entryfield_value = specialword[:4],
+                datatype = _custom_counter,
+                entryfield_validate = _custom_validate)
+        self._int = Pmw.Counter(parent,
+                labelpos = 'w',
+                label_text = 'Vertical integer:',
+                orient = 'vertical',
+                entry_width = 2,
+                entryfield_value = 50,
+                entryfield_validate = {'validator' : 'integer',
+                        'min' : 0, 'max' : 99}
+        )
+
+        counters = (self._date, self._isodate, self._time, self._real,
+                self._custom)
+        Pmw.alignlabels(counters)
+
+        # Pack them all.
+        for counter in counters:
+            counter.pack(fill='both', expand=1, padx=10, pady=5)
+        self._int.pack(padx=10, pady=5)
+
+    def execute(self):
+        print 'Return pressed, value is', self._date.get()
+
+specialword = 'Monti Python ik den Holie Grailen (Bok)'
+
+def _custom_validate(text):
+    if string.find(specialword, text) == 0:
+        return 1
+    else:
+        return -1
+
+def _custom_counter(text, factor, increment):
+    # increment is ignored here.
+    if string.find(specialword, text) == 0:
+        length = len(text)
+        if factor == 1:
+            if length >= len(specialword):
+                raise ValueError, 'maximum length reached'
+            return specialword[:length + 1]
+        else:
+            if length == 0:
+                raise ValueError, 'empty string'
+            return specialword[:length - 1]
+    else:
+        raise ValueError, 'bad string ' + text
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 24 May 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/CounterDialog.gif b/Pmw/Pmw_1_2/doc/CounterDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd833420b4fe117f0be2f42498499599840aa5af GIT binary patch literal 2769 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 + + + + Pmw.CounterDialog reference manual + + + + +

Pmw.CounterDialog

+ +
+
+

Name

+

Pmw.CounterDialog() - + selection dialog displaying a counter +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/Dialog.gif b/Pmw/Pmw_1_2/doc/Dialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..34834576d1489beafada8eb081422b810f6a25c7 GIT binary patch literal 2855 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 F06UbN^OXPq literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/Dialog.html b/Pmw/Pmw_1_2/doc/Dialog.html new file mode 100644 index 00000000..1e3c8886 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/Dialog.html @@ -0,0 +1,286 @@ + + + + + + Pmw.Dialog reference manual + + + + +

Pmw.Dialog

+ +
+
+

Name

+

Pmw.Dialog() - + toplevel window with button box +

+ + +
+

Inherits

+Pmw.MegaToplevel
+
+

Description

+

+ 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.ButtonBox 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 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/EntryField.gif b/Pmw/Pmw_1_2/doc/EntryField.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9eeb8b24c4a2b860b430a9464f38b6a44914915 GIT binary patch literal 2228 zcmV;l2ut@zNk%v~VL1V@0P+9;|Ns90007z9*@A+C|G>+cb9w*(00000EC2ui0677% z000C2D7xJKFv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4u9SyG7tai)odcWYXcuX#v#Z~8d&2GEj@G~IYywdLrz#N~n^XYnjNPdD; zfgk~iiW>nCjZ=>hgoRRvACUry8kh^5nGK4bnTrmh5upsIrKAd`0)C;IqpF>;lsT3j zoUW%2n5>_jpsA%7zpcc{$jc9~z7o8*Gr1kRwX&_Oo}$OX%E8x)qDc6`czO5pwX>NS2)E0Rh-#+Cu?R+=d@)>&XHMvselo73AOG_#)+}HMXa|eUmwwyxSCYi$XFbim27_8`N(I` zRCsYNJ>)cN7OP(aaV)y?~x9{J;g9{%{ytwh;wQCGG&b+zv=g^}cPfoqM z_3PNPYv0bjyZ7(l!;2qJzP$PK=+moT&%V9;_wbRBoKL^L{rmXy>)+46zy5#x@lg;! z0R$Fk;DHDxsNjMOHt67k5Jo8Bgb#)W-+&ZmsNsejcIe@R09g1Qh6I#o;)y7xsN#w& zw&>!EFvck3j5M;ShluWxSmTZ*Cc@*7Kn5vfi#G;1fsRAM=wp&hHtD2|A&vlyU_aq# zft4{JX<`5=lGNprJ%+L+mrs^yW|BoB;+9Q7=MK zs^X-QvTEt8eqtIAM6%TS){uieP-{sA z?GC^?I;NPa()lQ#$#(1HvN|;@ZCi}hI<8!Em0Ezc><;T{wqd^O?YuvN`xLF`o)ncg z&Q7cDwb&BdsKBd!DKEVU&uH(xBjqb@QFpOK)D1`uOR%c$o_cV?9J{zMS!?bp@=m$p ziWXIFo}ic!T2xvj7P&s_7;D&EXQ z$~DO8r_xMUU82)Q^m>HUeNt^T(^zLcWf5GT>Gjt&hdtuZXtxck+Bp&^-Q0B7ZMWS} zqc`B)eE045-@4^}-hYG_ZusGdC$687j5qH1EC4=A;@E-h;-TD5e zJqJ}Vl=Gna^Oy805HkHQ(U*nTVc1i~l=4aWI&t$?Ivg!O#7kfov_XRtFTqsyf(cgf3M`tp~+45l!LNz7sz^O(p?rZShw%x1CHbG}j=@Xy3>UyLhAz2k9w1 zhTw-(A|Dc?_JQ@e#4r+!j04SA#(!#%6#n<~V@JYxP-|#yRBPO)U*;JBgGw=>ZlvQK z1>sJToveWo=_49Prcw}YZ;KeHU_kw43KYUrl%B~W!w4m@A5$C=p8u6DP}-R^q# zyWkD4c*jfL@|yR&=uNMBnUc-+y7zU}e6M`x>xSVnj-8cbE_d)tIsI;jzmpSUeX>fH zaP?)UMdgZaLH9|(o>8`|;HdKqd|Z2qmY)+j zkgX$!>+B30a>d4ubFItlW&>xs&W^UUb+g`TTl?DB&bGF<&FyY```h3Sx41iy0028z CHi3!& literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/EntryField.html b/Pmw/Pmw_1_2/doc/EntryField.html new file mode 100644 index 00000000..5417f144 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/EntryField.html @@ -0,0 +1,545 @@ + + + + + + Pmw.EntryField reference manual + + + + +

Pmw.EntryField

+ +
+
+

Name

+

Pmw.EntryField() - + entry widget with validation +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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:

+
 Pmw.numericvalidator
+ Pmw.integervalidator
+ Pmw.hexadecimalvalidator
+ Pmw.realvalidator
+ Pmw.alphabeticvalidator
+ Pmw.alphanumericvalidator
+ Pmw.timevalidator
+ Pmw.datevalidator
+ + +

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.

+
+class Demo:
+    def __init__(self, parent):
+        # Create and pack the EntryFields.
+        self._any = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Any:',
+                validate = None,
+                command = self.execute)
+        self._real = Pmw.EntryField(parent,
+                labelpos = 'w',
+                value = '55.5',
+                label_text = 'Real (10.0 to 99.0):',
+                validate = {'validator' : 'real',
+                        'min' : 10, 'max' : 99, 'minstrict' : 0},
+                modifiedcommand = self.changed)
+        self._odd = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Odd length:',
+                validate = self.custom_validate,
+                value = 'ABC')
+        self._date = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Date (in 2000):',
+                value = '2000/2/29',
+                validate = {'validator' : 'date',
+                        'min' : '2000/1/1', 'max' : '2000/12/31',
+                        'minstrict' : 0, 'maxstrict' : 0,
+                        'format' : 'ymd'},
+                )
+        now = time.localtime(time.time())
+        self._date2 = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Date (d.m.y):',
+                value = '%d.%d.%d' % (now[2], now[1], now[0]),
+                validate = {'validator' : 'date',
+                        'format' : 'dmy', 'separator' : '.'},
+                )
+        self._time = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Time (24hr clock):',
+                value = '8:00:00',
+                validate = {'validator' : 'time',
+                        'min' : '00:00:00', 'max' : '23:59:59',
+                        'minstrict' : 0, 'maxstrict' : 0},
+                )
+        self._comma = Pmw.EntryField(parent,
+                labelpos = 'w',
+                label_text = 'Real (with comma):',
+                value = '123,456',
+                validate = {'validator' : 'real', 'separator' : ','},
+                )
+
+        entries = (self._any, self._real, self._odd, self._date, self._date2,
+                self._time, self._comma)
+
+        for entry in entries:
+            entry.pack(fill='x', expand=1, padx=10, pady=5)
+        Pmw.alignlabels(entries)
+
+        self._any.component('entry').focus_set()
+
+    def changed(self):
+        print 'Text changed, value is', self._real.getvalue()
+
+    def execute(self):
+        print 'Return pressed, value is', self._any.getvalue()
+
+    # This implements a custom validation routine.  It simply checks
+    # if the string is of odd length.
+    def custom_validate(self, text):
+        print 'text:', text
+        if len(text) % 2 == 0:
+          return -1
+        else:
+          return 1
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 22 May 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ExampleDemo.py b/Pmw/Pmw_1_2/doc/ExampleDemo.py new file mode 100644 index 00000000..f7ec1e71 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ExampleDemo.py @@ -0,0 +1,33 @@ +title = 'Pmw.EXAMPLE demonstration' + +# Import Pmw from this directory tree. +import sys +sys.path[:0] = ['../../..'] + +import Tkinter +import Pmw + +class Demo: + def __init__(self, parent): + + # Create and pack the EXAMPLEs. + self.widget1 = Pmw.Counter(parent) + self.widget1.setentry('1') + self.widget1.pack() + + self.widget2 = Pmw.Counter(parent, increment = 10) + self.widget2.setentry('100') + self.widget2.pack() + +###################################################################### + +# Create demo in root window for testing. +if __name__ == '__main__': + root = Tkinter.Tk() + Pmw.initialise(root) + root.title(title) + + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy) + exitButton.pack(side = 'bottom') + widget = Demo(root) + root.mainloop() diff --git a/Pmw/Pmw_1_2/doc/Group.gif b/Pmw/Pmw_1_2/doc/Group.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c4d8d5e9e41c5b63bf26877c83980f3f5f9fba8 GIT binary patch literal 2155 zcmV-x2$c6nNk%v~VXOhs0P+9;|Ns90008j#{{R60+1c5Gf`YIxU;qFBEC2ui0IUJg z000C2NV?qqFv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4uty-_xtai)odcWYXcuX#v&uD2tvbMC-@VK1ue$*%Txqctc(=UE}f`e9X z0f&YJh;)kzfrOBeOl^mbl$Vy7ijth2I|ZPjqM&~cl%;j23!|*9uCK7Mva__cwzs&s zy1Tr+zQ4f16a@gq#>W7qiioO?mdwrz$kWu-*4NnC+S}aS-rwNi;^XAy=I7|c$rYH< zsnHFOp7Zn@#OiMFoBQr|_5T3vt&?z%ou*354z`mQu%W|(1P9_-u&C0SM$ZyC+{pfM zl|%>-JBl2sA|%LV25q7@sM;zC0UQMHTA?=Wah z$`*f4yE$y<#;_y5Q+wyGY0_%p&7NJhb=TVdWV>y)kGJsRy4@z1&1~*c-&&g^jE8D? zY~%fqmsY<0xM1j6ft#w1o4EP$eO3KsTVCH=@KpV<4eeQ>{eVV4PS2Z{xsVEl359EC4TD41#=T!>){8gBTQg&%$b;9e!B_(X^* zw%7!V@!{d2JQvpJVq6iR$QK(L5Qp1D`7C&2VR`{r6^%W*rzB#4RCptdMJ1NeGgDqS znRu2>caegb)z-*?Qc8HDkx{OOpP9QYDIc0>^2gzs9{vR7PicBbUUmZlS!Z_K@tIp! zbNaMfbGk8BXP#LuCYqrY658K?IR190Xm+X>Ts#`>$=zvw#_3a_J!x90m4BA1sgFwT z_o$eWM#rW*uWBbGBlo?jsF1df78afr{zA%xRcmb#5oSB)w%{(IZMfvhFmAc%g7|H^?D}wSyYP}ARWS6{Ywx}I=Bw|% z{Pyc_FJq!3@W2EYZ1BMdC#>+o43`t{!w^R-@x&BYZ1KeyXRPtY9Cz&T#~_C+^2j8Y zZ1Txt{HyZHEVu0P%P_}WuR0CaZ1c@H=dAP2Jf{OK$|JuEG`m6%jc(CKlZ$lH;4aOy zwN5`hWYlI&dotAmO8s+Q@j9!u16aFOs%N(~tLm0ke;Br;OTvkot(4+N^t$lA_NZ~^ zt(xxI;mz8f-g!HyG~Mh`pIsgNVS_;-ZN^Nz7DbQg8o>0 z2C!4!DuuRf0!`^;@7L}1Ut;EKipX~qeOL0MNs@Oe8-!mwAzPcFv|aHErr|f;-^zFciJ+z^YcL(p+lF z$2|llkU`r6O|qQDIRwpzS;88d^R@=O4m7VQ{ma;!%;&)tA_jl4o1hI%SHm6dt%p7= zR}6zllpzxFQ)7~u5|_xtCOYwnP?So~rbxvqTJiphSj=KEj>yF>dhv^345JvwNX9an z@r-CpqZ-%9#x}a~jc|;k9Op>KI@GbTTaAm z_XD7^Dgzs4R!MriRACx?$pCUH@>tY6X7;M5EKd>(oy-(gGmja}a7JO4)U0M96^X%v z^z%%2;#97f#0PVh6PP#Tl-!Ip8e@@7nf|eSCo1+u8gH1kPKYqsyBhiYKr z=ogzy1uu&GYJfpiickUpCXoZp9OnXAQHo+pq84>Y%xGqfg93n~99^k_^f$jzjnsnc z`zTAbI1XZ5S0zR=1j0R^ku`b0TX{TRN)%Ce^SNe4kRa09P{UgsxzNEL9|||9(S|Ctos`vV zL^rEUPP!|!qBQ_%MOREIi7*k`{v+XMv}8bWPQkUWl`L%QYQp0h%DN176g?UG&|>X% zP0}%uSR-)AAL=N!QAIBXFuSGuwYRg*jF45mI?UdB)}1-1)*t6~UiAV+wo?P{SRLCU z=-Oixof~h)418b!N6Uzs0YHB>IyVJljKLs-@P8(3I{{M+!ynVIm^geq5A#mK1pcsz zB?e-TiFj8iCfSR87fh}@RV(wW076?DOm>cmU&p^c76FdT@Klql@ex)tr>=C&hVJ69On?v z+01oz@tygb;uHVa&3P6;@}AAxXBHQbBf)TmCis#neGR)Z`706PO=NN@lE literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/Group.html b/Pmw/Pmw_1_2/doc/Group.html new file mode 100644 index 00000000..b961a1f2 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/Group.html @@ -0,0 +1,226 @@ + + + + + + Pmw.Group reference manual + + + + +

Pmw.Group

+ +
+
+

Name

+

Pmw.Group() - + frame with ring border and tag +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+
+        # Create and pack the Groups.
+        w = Pmw.Group(parent, tag_text='label')
+        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
+        cw = Tkinter.Label(w.interior(),
+                text = 'A group with the\ndefault Label tag')
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+
+        w = Pmw.Group(parent, tag_pyclass = None)
+        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
+        cw = Tkinter.Label(w.interior(), text = 'A group\nwithout a tag')
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+
+        radiogroups = []
+        self.var = Tkinter.IntVar()
+        self.var.set(0)
+        radioframe = Tkinter.Frame(parent)
+        w = Pmw.Group(radioframe,
+                tag_pyclass = Tkinter.Radiobutton,
+                tag_text='radiobutton 1',
+                tag_value = 0,
+                tag_variable = self.var)
+        w.pack(fill = 'both', expand = 1, side='left')
+        cw = Tkinter.Frame(w.interior(),width=200,height=20)
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+        radiogroups.append(w)
+
+        w = Pmw.Group(radioframe,
+                tag_pyclass = Tkinter.Radiobutton,
+                tag_text='radiobutton 2',
+                tag_font = Pmw.logicalfont('Helvetica', 4),
+                tag_value = 1,
+                tag_variable = self.var)
+        w.pack(fill = 'both', expand = 1, side='left')
+        cw = Tkinter.Frame(w.interior(),width=200,height=20)
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+        radiogroups.append(w)
+        radioframe.pack(padx = 6, pady = 6, expand='yes', fill='both')
+        Pmw.aligngrouptags(radiogroups)
+
+        w = Pmw.Group(parent,
+                tag_pyclass = Tkinter.Checkbutton,
+                tag_text='checkbutton',
+                tag_foreground='blue')
+        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
+        cw = Tkinter.Frame(w.interior(),width=150,height=20)
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+
+        w = Pmw.Group(parent,
+                tag_pyclass = Tkinter.Button,
+                tag_text='Tkinter.Button')
+        w.configure(tag_command = w.toggle)
+        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
+        cw = Tkinter.Label(w.interior(),
+                background = 'aliceblue',
+                text = 'A group with\na Button tag!?'
+        )
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+
+        w = Pmw.Group(parent,
+                tag_pyclass = Tkinter.Button,
+                tag_text='Show/Hide')
+        w.configure(tag_command = w.toggle)
+        w.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
+        cw = Tkinter.Label(w.interior(),
+                background = 'aliceblue',
+                text = 'Now you see me.\nNow you don\'t.'
+        )
+        cw.pack(padx = 2, pady = 2, expand='yes', fill='both')
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 15 November 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/HistoryText.gif b/Pmw/Pmw_1_2/doc/HistoryText.gif new file mode 100644 index 0000000000000000000000000000000000000000..5ee3ae37eac8763f5b62714975f4a717fa14c19a GIT binary patch literal 2298 zcmc&z`9IW+8hyq#-xt}LDN-^FN~A=Zx>J`d#fy^E$WlIJi8N_!nNnGj22s|Su?`Aj zsfi|(eYB{A^hzpOu355F^O~zq_x&60`SJNYpL5Q0&gZeU-)CvzgO^B!Mfe3OmHPJW z+a=Kww-wkMQBsmXBm#v(rO}+^_QC5fgS zz|x}0au^J8#pt{Ee^{kOQX)Rgi9yT(jzz2X@Wym$Ni;%4>?v3Y8X4p;(nJKX@$f$l zX%Y4apL|J-!Eg{{G>CL07$ju?+oeQ~gbjy|O7KCN0|ZbJ{5B1+e|C&AbQ{q`8(UJ> zr#i{wRKZITxBw~u@^ApO1i&)}eF|ht0h$O1z+(V9fW`!%5Q-L$#>2^piA0VM1~uf9 zEiHq_O0EKDDnvN}Ms+3h7!pAs!DESBtGrXtGH9SY1{xjYG=PYpya~Wv02MJlg&^@y zcBwzAU^E3Z(O^l0)Iz{%fH$C4{2(w!0s$W;R38h1FNVHsbmza+{^)r3kXU;tO*<#AjR-dJy}prlk-+?`=? zkV)#UE9t#udZH)Ko>j`twLClZuA5c%><%$rc5T$b$98nP3?t8;`ig-vXNE)m6nWwW z=&%Audm1VS?|HW;uic+D4VAdsEYIG?>XD|fk3IP#^HneEl~9uyBuoaq26Vbx_0Ur`62d zSo?C^&FU;G-t6SFN{f5PeZu2!#Oj95?eYcj zHPoY-JJ}a!9?U8C%LphPT9Y!cXR<|c-t1VcZ{NwB`M!a;S0XtRR!X8rj!4j zlv*-mSXRVFF+VeCMjfRThkb!xOK!JqKUJC+G4-|VWQgokd2v?Ylr_D8ImN6>&tZBm zXR^zEt6CZYr>lKhl7|?}v-g#&@5_uZ@5b#J-guHDTRBr_LN_1rirc_0r(Ydz^3P4o zu{9t+dgKw(@NkC_zQM&T=yc7Ky2gT3e^-y<8}8}ZCyNyHj!q}+z0mEM`DNkST~?ra z?x(mbSlJbZB63zvVy`hRgYB( zY9P+qx98J>fk~gJr|L!fQe)*@|Heg z!|yj6NnuTgPapqGYxBP&S_u7g`med|ns#UVC+-9*_c<4=-n}?e89T^occ%p8qK<2a zJWAJ`F?%UIHfS*UI_M6xj_-PM`7{-I;)YT@`&h~<%uOz@cUs%7^{h?JC2ZgNfUL4s zg{UxHjHnRViEUHPpO*v&O~GhCo*_?rPPuN;_j8Lstt?e`p}jM+W7iLt$T_*U>(Jd5yHy0VGh1*QFx?t9 zW`eZhUR@mi4{cjlLApmRPTyik*)d#@f#u^2Y?F-a(*-w^w&@wU581iZ2{O~13_{nN0|C$;W&hX`ku@u1t!Oqkvu^BKo5%q>NR{_L1!@!d*TnXruwVH%?pnIZL|v&kyV#7Ulrh3d33PnO(T20 zI_!ES>5Ic4dwBjXg@mi$< TtoJrmG%fo*Qm1ZG0e1cuHO1Nk literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/HistoryText.html b/Pmw/Pmw_1_2/doc/HistoryText.html new file mode 100644 index 00000000..c42dad64 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/HistoryText.html @@ -0,0 +1,427 @@ + + + + + + Pmw.HistoryText reference manual + + + + +

Pmw.HistoryText

+ +
+
+

Name

+

Pmw.HistoryText() - + text widget with a course-grained form of history +

+ + +
+

Inherits

+Pmw.ScrolledText
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/LabeledWidget.gif b/Pmw/Pmw_1_2/doc/LabeledWidget.gif new file mode 100644 index 0000000000000000000000000000000000000000..dfa61540861a06dc2c6edff357d0f11890fdea23 GIT binary patch literal 887 zcmV--1Bm=bNk%v~VWR+a0P+9;|Ns90007z9+2!Tsf`Wno0000000000EC2ui0HXkO z000C2IJ(^aFv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhHyg+MGCkI1BQ z$!t22!p?I_ty-0UD2FKMdcWYXcuX#v&s{)PtKp*G@VNY|X159Ryndfv+lP33f`ess ze}IIEihYNOi(Ua`k#Cc8hK&?%j{=oqoo1hKmzWZokD*_vW2$GPq!6ZYkpZ-xkhGPv zwYR&Rdakbyv2eS+kX^--$;isezkb0F!<4CEsLsc}*{o*3(F@aPouRq7*vQQ0=y~4X z1L0@m*38@0+F;y;(C*-YbMpAstpj-N89!nEdl+#=)HVK2 zqr^BAqgmWUl1#{8BTK5Jv+rQal`BuadI__nOj0y!Zn}vnr_Mz@8~Oa1DCnV~LkNU~Zk1E~B(v*gM8ID7H@`5j~d zg+&V>{aLf>)u%B>ajlxQWZI%_SH=C$);)}6bi0hbSx>>=*~|#vN_-Eu^Y0TGUIoRg$9!4CGtzmS-(|MDDuB|+9GTzlzzc{a6`}bqwznw41_x`~D$pt4} zY3i-Q(1G^_2;YFMfd`6s1PvtKdHSU1;DfzHc+Yld=tmcSm3f#Kh<1sH7>RM2*wcj} zGI$${CAzp9jJ++QqEIv{^wAzS9+hJr+`Z8wQ$MbfokPhOBczPOp|~D`M{a0NkexBf+?Njmh@2c$mStss39cDOo0+`{oO=){c?O-c*_le1 zKX@t@s6J?R#i^&F zM__EIwpxX%4Ze1lg|ZSNTcW4cipH&(=Bg{KFaG*empBT$2d|y_M{2AX$cC!yvS2h@ z>a)-)My!w3PIN7i*?MK6W8j7>F1YE9Ywo$|Zadw&?6&LfyYR*<@4WQZYwx}I=Bw|% N{PyebzY` + + + + Pmw.LabeledWidget reference manual + + + + +

Pmw.LabeledWidget

+ +
+
+

Name

+

Pmw.LabeledWidget() - + frame with label +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MainMenuBar.gif b/Pmw/Pmw_1_2/doc/MainMenuBar.gif new file mode 100644 index 0000000000000000000000000000000000000000..aa7a7bf88eafed57d468ac3bee0d5a5a2542b097 GIT binary patch literal 518 zcmV+h0{Q(%Nk%v~VcG#50Pz3-|Ns90007z9*@A+CEC2ui0NMc^00091gpR4p?GK}z zwAzca-n{z{hT_N!28pKX%C_zc$8u`U_KoNI&i8xm3krwCqVWg5x|ln5oGlSh?oeaEO2j=|MUQdfG6kTDtiP+tX8d+{sYv{7k@yXcjjd};&I`T1DSbZfns8kQzO9aW z%$#0}d-s-X?;kaC=J>HY7>i!9fdv^V5G77qFk${sNenkEo-*KM@fKRdhcM(bcN4dj zLjW=3MuQL{el!_PCC73eFKWCgGN+$e-3VH{)hp;q4K6RVA;D%A<~49`?P zK^=1Wu0qdUHZgLYR`BIMu{fie^+M9-9#U6j4m>&yV9lq(SP9hEQSQfOEYJF-B8@NE zWDBlog8MhI;))T}DC~RTF=RfHn=QT!wQ_`eh5;eQ4Eii*prK2fzTEk=>ecH~vwjU5 zkn7mAYk!$-JGbsAxOe;hUBtwI;lzs@KaM=P^5x8%JAV#6y7cMPt6RU0J-hbp+`D`K Ip1c46I~k4xXaE2J literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/MainMenuBar.html b/Pmw/Pmw_1_2/doc/MainMenuBar.html new file mode 100644 index 00000000..4f0fea88 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MainMenuBar.html @@ -0,0 +1,421 @@ + + + + + + Pmw.MainMenuBar reference manual + + + + +

Pmw.MainMenuBar

+ +
+
+

Name

+

Pmw.MainMenuBar() - + manager for toplevel native menus +

+ + +
+

Inherits

+Pmw.MegaArchetype
+
+

Description

+

+ 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. +

+ +
addcascademenu(parentMenuName, menuName, statusHelp = '', traverseSpec = None, **kw)
+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.

+ + + +
+ +
addmenu(menuName, balloonHelp, statusHelp = None, traverseSpec = None, **kw)
+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.

+ + + +
+ +
addmenuitem(menuName, itemType, statusHelp = '', traverseSpec = None, **kw)
+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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MegaArchetype.html b/Pmw/Pmw_1_2/doc/MegaArchetype.html new file mode 100644 index 00000000..03f62660 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MegaArchetype.html @@ -0,0 +1,459 @@ + + + + + + Pmw.MegaArchetype reference manual + + + + +

Pmw.MegaArchetype

+ +
+

Name

+

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

+
 combobox.configure(entryfield_entry_state = 'normal')
+ + +

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

+
 dialog = Pmw.TextDialog(text_pyclass = 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.

+ + + +
+ +
createcomponent(componentName, componentAliases, componentGroup, widgetClass, *widgetArgs, **kw)
+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.

+ + +
+ +
defineoptions(keywords, optionDefs, dynamicGroups = ())
+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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MegaToplevel.html b/Pmw/Pmw_1_2/doc/MegaToplevel.html new file mode 100644 index 00000000..53c1fe03 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MegaToplevel.html @@ -0,0 +1,267 @@ + + + + + + Pmw.MegaToplevel reference manual + + + + +

Pmw.MegaToplevel

+ +
+

Name

+

Pmw.MegaToplevel() - + base class for megawidgets within a toplevel +

+ + +
+

Inherits

+Pmw.MegaArchetype
+
+

Description

+

+ 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. +

+ +
activate(globalMode = 0, geometry = 'centerscreenfirst')
+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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MegaWidget.html b/Pmw/Pmw_1_2/doc/MegaWidget.html new file mode 100644 index 00000000..d18698bb --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MegaWidget.html @@ -0,0 +1,83 @@ + + + + + + Pmw.MegaWidget reference manual + + + + +

Pmw.MegaWidget

+ +
+

Name

+

Pmw.MegaWidget() - + base class for megawidgets within a frame +

+ + +
+

Inherits

+Pmw.MegaArchetype
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MenuBar.gif b/Pmw/Pmw_1_2/doc/MenuBar.gif new file mode 100644 index 0000000000000000000000000000000000000000..aa7a7bf88eafed57d468ac3bee0d5a5a2542b097 GIT binary patch literal 518 zcmV+h0{Q(%Nk%v~VcG#50Pz3-|Ns90007z9*@A+CEC2ui0NMc^00091gpR4p?GK}z zwAzca-n{z{hT_N!28pKX%C_zc$8u`U_KoNI&i8xm3krwCqVWg5x|ln5oGlSh?oeaEO2j=|MUQdfG6kTDtiP+tX8d+{sYv{7k@yXcjjd};&I`T1DSbZfns8kQzO9aW z%$#0}d-s-X?;kaC=J>HY7>i!9fdv^V5G77qFk${sNenkEo-*KM@fKRdhcM(bcN4dj zLjW=3MuQL{el!_PCC73eFKWCgGN+$e-3VH{)hp;q4K6RVA;D%A<~49`?P zK^=1Wu0qdUHZgLYR`BIMu{fie^+M9-9#U6j4m>&yV9lq(SP9hEQSQfOEYJF-B8@NE zWDBlog8MhI;))T}DC~RTF=RfHn=QT!wQ_`eh5;eQ4Eii*prK2fzTEk=>ecH~vwjU5 zkn7mAYk!$-JGbsAxOe;hUBtwI;lzs@KaM=P^5x8%JAV#6y7cMPt6RU0J-hbp+`D`K Ip1c46I~k4xXaE2J literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/MenuBar.html b/Pmw/Pmw_1_2/doc/MenuBar.html new file mode 100644 index 00000000..e2c04a6c --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MenuBar.html @@ -0,0 +1,399 @@ + + + + + + Pmw.MenuBar reference manual + + + + +

Pmw.MenuBar

+ +
+
+

Name

+

Pmw.MenuBar() - + manager megawidget for menu buttons and menus +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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. +

+ +
addcascademenu(parentMenuName, menuName, statusHelp = '', traverseSpec = None, **kw)
+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.

+ + + +
+ +
addmenu(menuName, balloonHelp, statusHelp = None, side = 'left', traverseSpec = None, **kw)
+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.

+ + + +
+ +
addmenuitem(menuName, itemType, statusHelp = '', traverseSpec = None, **kw)
+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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MessageBar.gif b/Pmw/Pmw_1_2/doc/MessageBar.gif new file mode 100644 index 0000000000000000000000000000000000000000..0dc444658814786e25a8be6dbe9f9b13cff5234c GIT binary patch literal 435 zcmV;k0Zjf!Nk%v~VU7VT0Pz3-|Ns90007z9*@A+CEC2ui0FD7H00091l#i*)?GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4KDwoWr^9hYgr_`$T zip^@b+^+Wv4kHKTviXcotJmzd`wfrF=k&V$j?e4&1Lgn#7$`VMSZH{Nn5ekO*y#8O z87VnQS!sFc2Oze|nevy}87d0$xl}renp$zn5#Z{=swz9H5R36@fE)0z%VA3ktom!w zd(d0VfSfTL+}z1bp`7b_Og;UITuiN<0PXz!uH*;}MOF3Y0+<_>m$)gaSBf zJQ>7fIdcWiP1F@qpF2$`YeG?(z}m`d11%2RWsclTn?xJZRD!dpQW;5UG+hdn#Z#t7 zqgwSbHAdE}TtjSq@rRGtv1H4dJ&QK2S~^w7TzU&PuH3nF>)O3Lx2xX0eEa(S3plXg d!GsGNK8!fA;>C;`JAMo~vgFB>D|adY06W$N+F1Yq literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/MessageBar.html b/Pmw/Pmw_1_2/doc/MessageBar.html new file mode 100644 index 00000000..69be04e7 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MessageBar.html @@ -0,0 +1,302 @@ + + + + + + Pmw.MessageBar reference manual + + + + +

Pmw.MessageBar

+ +
+
+

Name

+

Pmw.MessageBar() - + information line for displaying short messages +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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

+
 {
+     'systemerror'  : (5, 10, 2, 1),
+     'usererror'    : (4, 5, 1, 0),
+     'busy'         : (3, 0, 0, 0),
+     'systemevent'  : (2, 5, 0, 0),
+     'userevent'    : (2, 5, 0, 0),
+     'help'         : (1, 5, 0, 0),
+     'state'        : (0, 0, 0, 0),
+ }
+ + + +
+ +
silent +
+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',
+}
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/MessageDialog.gif b/Pmw/Pmw_1_2/doc/MessageDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6ac164348bf965727373d187d747a252628fd14 GIT binary patch literal 3374 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 EJ0Y9oMF0Q* literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/MessageDialog.html b/Pmw/Pmw_1_2/doc/MessageDialog.html new file mode 100644 index 00000000..f3e35884 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/MessageDialog.html @@ -0,0 +1,326 @@ + + + + + + Pmw.MessageDialog reference manual + + + + +

Pmw.MessageDialog

+ +
+
+

Name

+

Pmw.MessageDialog() - + a dialog displaying a text message and an icon +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/NoteBook.gif b/Pmw/Pmw_1_2/doc/NoteBook.gif new file mode 100644 index 0000000000000000000000000000000000000000..206a88d396dccfdec3f2dbb9edc3e6a721ac6811 GIT binary patch literal 2585 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/NoteBook.html b/Pmw/Pmw_1_2/doc/NoteBook.html new file mode 100644 index 00000000..38601f7e --- /dev/null +++ b/Pmw/Pmw_1_2/doc/NoteBook.html @@ -0,0 +1,344 @@ + + + + + + Pmw.NoteBook reference manual + + + + +

Pmw.NoteBook

+ +
+
+

Name

+

Pmw.NoteBook() - + a set of tabbed pages +

+ + +
+

Inherits

+Pmw.MegaArchetype
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/OptionMenu.gif b/Pmw/Pmw_1_2/doc/OptionMenu.gif new file mode 100644 index 0000000000000000000000000000000000000000..a36b151ebdc8c4d383287e33885000326de69ab5 GIT binary patch literal 2354 zcmV-23C;FLNk%v~VJZQt0P+9;|Ns90007z9+3f7>f`WpMj*b8T00000EC2ui04f2h z000C2D7xJKFv>}*y*TU5yU#!%OZg&m(N#c&_g$?Vr4$a7Zk2en^pV z$!t1t$>eiNty(2f6)6ZVd+!)_Si!0ee}2i5dJab$TDEdhA+ddq&U-?#+W!OZm7rZrpuf)KSl(q@n5MKoEVr~ zfbxM#We=h1bmvs6)p%2*YSjueD+-ZM*t6!@gz=q96m~TLgJ{dYZt9EUKwn=;0!sbuvU%h2@R^3W9FWt^u0goJaF=vCI zIK_qx3}BP%*RCD76#&<>-pipeTV{tD^wr(BMOy@ClX2YQKUb>Gd<3?0$VUksL+&?m zV#_{%?|rG;I#AXbP@7HeoqWv3t0EVhY+<9kBz8Ki7>hVB8)3aSK|#KJm=$&Kn5w~kVF<~WNfWixZ?}09qHtgP(~@GjQr5J zBiH<*;-V{<|i!ZYYZ;vu8Ma zCbVFLC(tbl^=S`!FpNbFu8GQe8g+fBl`RIrGB<>`J5Za&F{jaGhq;?wkZwz1+Ny69 z?NxT)zw!ZiE@uGSr&v+(bR@8DZyAeCM8zFEUwjmYyYIy^fGb>D0-C`8eOp{?V{#@37EG;)K#{n3<2GVlnW_HrsP}WzyIzxRH)B8!LwP`~iXZK5D ztAVs;R_A1Kl;zU{jZO8ha~VUB@5(ll3*n1Fnp@=9y=0ZFwSx z9uQdh;FDbkdlRU1(-XJ8a7yhI?DT4fxdd@<3ZHCk?I6SFI_s~G?y%+NoX$b&cyP<( z@Od~~x(?4DuW|Cm=gS69LNyNj_Pz(tuJo@wy~N|z!=5r)EQ=of1;|UvJSxWC6*S|E zYhQow;A=`ghOlo*RC}`iD_V=L|C60k;Y2f`b zr#uQ7kWW3Dk_ev^4a9&feHGw8cA! zag1gtqaDtO#yVlKjagEo9M}j)Xvi@RbgbiO-l)evIB$mBvmpV|0mVMr0DCAzp%L?B<2KC+EQ)~?1L|NgfU12Q<$}UQ!yWLOdlo_Q+MrLYuV}<)u4$Xgn`WfIdB|m&vq{oQ!#S5(0J2r)263~8Ctskl4q|RbAsB!@_sP$G z`tzRv4X8i|O3;25pq(EqTeoTk4u(~bp8gCZPN4u$(2830q8J6}LCK~NduqU=DS1LQ zCHb&GQ8c3{O{q%xxzU93EoyVgUCmS$8eReqBHrU&()P##yo{wVL;J=ER!Y>ORKs4ezRm%Hy2U)^)9RaOb9;}t52>vHUI;dD`PX# z*n!Y>0AE!bKmf}&tC^K)eC^Fx9eT?aEbyL$MJ;Va@K4D?HnOjEtz{|e+RE;;wsFlY zZ=%9k+YC-7!0Fj%_bObfssNI0{{5*?S=-OK!Zxw7eXVV$``qeU_p-VTi&?L8o9a20 zcAQ&ka)8r=Xnry%vQ+JA;ksDqw%4-Pb*^t3zmcTwd0B6DvmUHU%Qy%Of|d^=oWqh1(M8D`Rk zKg{Czf_TCsZt#8Wsz3AckinIOFnx7gUmoYU#1^LUrBX~r9AEax7(MZ!h};6iBKgS{ zRr0KCEX5T=`N{&7GNY*6B_m_`%PbW#HC+h9GXKcQU{13>wG1dSoB7SK8Nos4Oy@e= z`ObLGv!3_NXFO-~msJA(K%WOq=t3KM&wmDVqQt4_aCWoNPJA?^bHL;#B)ZX+X2PWv zo#{`icNpHBv?;lq0#U9|)ZARcAR`!RRM)~EfIMyX7H3uEtoi|)1~ei;rh+khxWGH~HQ9}O*8Ki7zz5Fo zhV!eL9ym7)w(anWTRad7FO8)MaPf|J9OB#RCC5EZ@`gXL + + + + Pmw.OptionMenu reference manual + + + + +

Pmw.OptionMenu

+ +
+
+

Name

+

Pmw.OptionMenu() - + single item selection megawidget +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        # Create and pack the OptionMenu megawidgets.
+        # The first one has a textvariable.
+        self.var = Tkinter.StringVar()
+        self.var.set('steamed')
+        self.method_menu = Pmw.OptionMenu(parent,
+                labelpos = 'w',
+                label_text = 'Choose method:',
+                menubutton_textvariable = self.var,
+                items = ['baked', 'steamed', 'stir fried', 'boiled', 'raw'],
+                menubutton_width = 10,
+        )
+        self.method_menu.pack(anchor = 'w', padx = 10, pady = 10)
+
+        self.vege_menu = Pmw.OptionMenu (parent,
+                labelpos = 'w',
+                label_text = 'Choose vegetable:',
+                items = ('broccoli', 'peas', 'carrots', 'pumpkin'),
+                menubutton_width = 10,
+                command = self._printOrder,
+        )
+        self.vege_menu.pack(anchor = 'w', padx = 10, pady = 10)
+
+        self.direction_menu = Pmw.OptionMenu (parent,
+                labelpos = 'w',
+                label_text = 'Menu direction:',
+                items = ('flush', 'above', 'below', 'left', 'right'),
+                menubutton_width = 10,
+                command = self._changeDirection,
+        )
+        self.direction_menu.pack(anchor = 'w', padx = 10, pady = 10)
+
+        menus = (self.method_menu, self.vege_menu, self.direction_menu)
+        Pmw.alignlabels(menus)
+
+    def _printOrder(self, vege):
+        # Can use 'self.var.get()' instead of 'getcurselection()'.
+        print 'You have chosen %s %s.' % \
+            (self.method_menu.getcurselection(), vege)
+
+    def _changeDirection(self, direction):
+        for menu in (self.method_menu, self.vege_menu, self.direction_menu):
+            menu.configure(menubutton_direction = direction)
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 23 October 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/PanedWidget.gif b/Pmw/Pmw_1_2/doc/PanedWidget.gif new file mode 100644 index 0000000000000000000000000000000000000000..eecbbf201834091ec69748438206fbdb9424ebd4 GIT binary patch literal 1917 zcmV-@2ZH!VNk%v~VUPiU0Pz3-|Ns90007z9*@A+CEC2ui0FVKI00091l#i*)?GK}z zwAzca-n{z{hT=$;=82~2iUIBm$MQ_q_KoNI&iDQg3<`(DqVYH!3|JZ^^9hYMmr$ql zDgX=s*vYmF4okmPu9&GcpBdz}`weO{hAV(v+^nI@Yy#~}N)|0PO|5N_jncjSYTc`F4Q{^hElqwNZdMMK&MyDDK3so( zJf1hte-Kadk6OMr0sCz$7y@CjG)mre(bBM?L4FV;I!tKM3O@c@bCgY-$FYe=aIoNn z{Fv$_29=mfzF~>76U+)T8@Y5-GiIZl5_k%_xyGl?LL*TKLT{K$`h56Rv&>cTFi#(4r7SE;?ml-XH zb?eNeMZzXJ`xk0?s;|h-ZTq$4+ADqoUr8J}Y$VKi87I}eIb<%;Z!G&;ojHX&*^MlD zj;?!=izcaykMSM*`6S!FxG-Y+ ziGG2YqKp#I$d!o>@+V>fJW^s~VK^?LA_POC<)eEn){-PrPeMuHk`PAefR(E?2_pjm zd>iVr(dy`Q?>5t{4HE0c5D3lMu{#K$|&^=}(ym=!s;NYT#)ApqXK5 zjGuWDYC@V1{P+N)0!T{Vn|)|mXabamRb*#tYFeSCk1Cocnp_^~C8&j-Iq9T^n%NVg zbzs`+pNj%IC#$X+>PM%meQN8fxbFI=uFJ?8{$8A_?n-E`uNvEcqgmP+X|bzb>ngT- z^2!FX1d*C;xZC16F18Oyy9thrmMbo~?wWh7s9A!`ZoTh@d+w>2%9(1dnfeQGwB9CD zCY$}P`)|U%3VJKF{~`=9qY-Wxr@;%58!W{6_J``l4Ok2@zXuMy2CbV4yKTl6Z@d$* z7sDDc%7#v?AGn&r9P-Kw*V(1VFP9o~z?6}EhRI$wt1!ki`Rbd?Hv=8A!15-l?9UHp zYyrB}^sK~3o;2cWy=}DBDMLN@&N~|Z{_)3cUcNTWBTqf+-@<0AvF3yyV))6#VqUiB z@h0f`>A7a^@B&(+LwSvy_cCQ!Opn1er?-!o`xG40TE*M&1fRj|<-zSc>#^7kB=R5- zUwqnos`vcx(ue&!!P&RWd?<`>&pprKZ`pmxoDc3;zS4>B?6)`c;m5{NsS?gy%ovXzYD`JKqE*2*Cte@MZ_(8}=Nyw)aI4 zgk_^3{x(p+xE;zetzo!4Oap^ zBL)zOL<|EDVR$GYRxO4f+`#@3S!hEL2yt^2e4^Y!)xN}R5dk#YQF5+`z!z<>0%KfQ z7w6N)p-J&hSd?J~(8#{|t+84q6y6(+=({jlAdai6;tWHWK{a|YaZ&su3Ed<}HrCOQ zcSK|jN9e%VO;SEed>|7eNdZEZ5l)>XWVf=ope7zqex!S0hnl#^MkO(ojvNpu_eV+F zVUm_7d`2(jcuQHr@|T<2WsGW>%3!Kue5_Pb?Ruoj`!y3cv5eI)r#UTG#zluxsAi>< zSt&c}QjgvgUo;6w%+aZ7k5m#TG>vIHWX1@b&CBIG$yt$%=yRX^?595?a?Ty*^PdDQ zs6ku!8W$XNq52#qL;fEMQRNBAJrS+wK?B-Ni)xghRodu96Xem5Hq?B$IgTrK!;aqY z&ZH;pWd)}Vcf9 zRGJ*Mr%-)LR42hybEwpXS0xZndE?WrYVfNm4Xap_`UIJJV5?+3t0|@m)~ZHJu5QH& zSCLxMx~8kGS~aU)V*%H)(v_xv-D_G0I}E=T7AJviDq0uI*t=5ov5-}YWaCQN%HD{t zBvGtpjl|i5c=ofux~yO`OWLNH*0Fg_t*2JoSH$K)wuQ}VXKAYz-0Ib~qSY-%T??Vc z#ul}}JuGZ*T}#~J=0&*3ZLM-cy9nO~W3 + + + + Pmw.PanedWidget reference manual + + + + +

Pmw.PanedWidget

+ +
+
+

Name

+

Pmw.PanedWidget() - + frame subdivided into several resizable panes +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+
+        # Create a main PanedWidget with a few panes.
+        self.pw = Pmw.PanedWidget(parent,
+                orient='vertical',
+                hull_borderwidth = 1,
+                hull_relief = 'sunken',
+                hull_width=300,
+                hull_height=400)
+        for self.numPanes in range(4):
+            if self.numPanes == 1:
+                name = 'Fixed size'
+                pane = self.pw.add(name, min = .1, max = .1)
+            else:
+                name = 'Pane ' + str(self.numPanes)
+                pane = self.pw.add(name, min = .1, size = .25)
+            label = Tkinter.Label(pane, text = name)
+            label.pack(side = 'left', expand = 1)
+            button = Tkinter.Button(pane, text = 'Delete',
+                    command = lambda s=self, n=name: s.deletePane(n))
+            button.pack(side = 'left', expand = 1)
+            # TODO: add buttons to invoke self.moveOneUp and self.moveOneUp.
+
+        self.pw.pack(expand = 1, fill='both')
+
+        buttonBox = Pmw.ButtonBox(parent)
+        buttonBox.pack(fill = 'x')
+        buttonBox.add('Add pane', command = self.addPane)   
+        buttonBox.add('Move pane', command = self.move)   
+        self.moveSrc = 0
+        self.moveNewPos = 1
+        self.moveBack = 0
+
+    def move(self):
+        numPanes = len(self.pw.panes())
+        if numPanes == 0:
+            print 'No panes to move!'
+            return
+
+        if self.moveSrc >= numPanes:
+            self.moveSrc = numPanes - 1
+        if self.moveNewPos >= numPanes:
+            self.moveNewPos = numPanes - 1
+        print 'Moving pane', self.moveSrc, 'to new position', self.moveNewPos
+        self.pw.move(self.moveSrc, self.moveNewPos)
+
+        self.moveSrc, self.moveNewPos = self.moveNewPos, self.moveSrc
+        if self.moveBack:
+            if self.moveNewPos == numPanes - 1:
+                self.moveNewPos = 0
+                if self.moveSrc == numPanes - 1:
+                    self.moveSrc = 0
+                else:
+                    self.moveSrc = self.moveSrc + 1
+            else:
+                self.moveNewPos = self.moveNewPos + 1
+        self.moveBack = not self.moveBack
+
+    def addPane(self):
+        self.numPanes = self.numPanes + 1
+        name = 'Pane ' + str(self.numPanes)
+        print 'Adding', name
+        pane = self.pw.add(name, min = .1, size = .25)
+        label = Tkinter.Label(pane, text = name)
+        label.pack(side = 'left', expand = 1)
+        button = Tkinter.Button(pane, text = 'Delete',
+                command = lambda s=self, n=name: s.deletePane(n))
+        button.pack(side = 'left', expand = 1)
+        self.pw.updatelayout()
+
+    def deletePane(self, name):
+        print 'Deleting', name
+        self.pw.delete(name)
+        self.pw.updatelayout()
+
+    def moveOneUp(self, name):
+        self.pw.move(name, name, -1)
+
+    def moveOneDown(self, name):
+        self.pw.move(name, name, 1)
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 14 April 2001 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/PmwFunctions.html b/Pmw/Pmw_1_2/doc/PmwFunctions.html new file mode 100644 index 00000000..af22de8f --- /dev/null +++ b/Pmw/Pmw_1_2/doc/PmwFunctions.html @@ -0,0 +1,766 @@ + + + + + + Pmw functions reference manual + + + + +

Pmw functions

+ +
+
Pmw.aboutcontact(value)
+

+ 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.EntryField alphabetic standard validator.

+ +

+ + +
+
Pmw.alphanumericvalidator(text)
+

+ Validator function for Pmw.EntryField alphanumeric 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:

+
 'dmy':  31/01/99  31/1/1999  31/1/99
+ 'mdy':  01/31/99  1/31/1999  1/31/99
+ 'ymd':  99/01/31  1999/1/31  99/1/31
+ + +

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.EntryField date 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.

+ +

+ + +
+
Pmw.drawarrow(canvas, color, direction, tag, baseOffset = 0.25, edgeOffset = 0.15)
+

+ 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.

+ +

+ + +
+
Pmw.forwardmethods(fromClass, toClass, toPart, exclude = ())
+

+ Forward methods from one class to another.

+ +

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.

+ +

For example:

+ +
class MyClass:
+    def __init__(self):
+        ...
+        self.__target = TargetClass()
+        ...
+
+    def foo(self):
+        pass
+
+    def findtarget(self):
+        return self.__target
+
+Pmw.forwardmethods(MyClass, TargetClass, '__target',
+    ['dangerous1', 'dangerous2'])
+
+# ...or...
+
+Pmw.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 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.EntryField hexadecimal 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().

+ +

+ + +
+
Pmw.initialise(root = None, size = None, fontScheme = None, useTkOptionDb = 0, noBltBusy = 0, disableKeyboardWhileBusy = None)
+

+ 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.EntryField integer 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).

+ +

+ + +
+
Pmw.logicalfont(name = 'Helvetica', sizeIncr = 0, **kw)
+

+ 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.EntryField numeric 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().

+ +

+ + +
+
Pmw.pushgrab(grabWindow, globalMode, deactivateFunction)
+

+ 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.EntryField real 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.EntryField time standard validator.

+ +

+ + +
+
Pmw.tracetk(root = None, on = 1, withStackTrace = 0, file = None)
+

+ 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:

+ +
python executed:
+  button = Tkinter.Button()
+  button.configure(text = 'Hi')
+
+tracetk output:
+  CALL  TK> 1:  ('button', '.3662448') -> '.3662448'
+  CALL  TK> 1:  ('.3662448', 'configure', '-text', 'Hi')
+ +

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:

+ +
python executed:
+  def callback():
+      button.configure(text = 'Bye')
+      return 'Got me!'
+  button = Tkinter.Button()
+  button.configure(command = callback)
+  button.invoke()
+ +
tracetk output:
+  CALL  TK> 1:  ('button', '.3587144') -> '.3587144'
+  CALL  TK> 1:  ('.3587144', 'configure', '-command', '3638368callback')
+  CALL  TK> 1:  ('.3587144', 'invoke')
+  CALLBACK> 2:    callback()
+  CALL  TK> 2:    ('.3587144', 'configure', '-text', 'Bye')
+  CALL RTN> 1:  -> 'Got me!'
+ +

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.

+ +

+ + +
+
Pmw.ymdtojdn(year, month, day, julian = -1, papal = 1)
+

+ Return the Julian Day Number corresponding to year, month and + day. See jdntoymd() for description of other arguments)

+ +

+ + +
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/PromptDialog.gif b/Pmw/Pmw_1_2/doc/PromptDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..b82205c921b71042bd7e117cb410afe2b843c4cb GIT binary patch literal 1959 zcmV;Y2Uz$=Nk%v~VcGzs0P+9;|Ns90007z9*}!0TU@$v^f`b2srvLx|EC2ui0NMbg z000C2Xu8}^F3L%(y*TU5IqaZ8d|_#xXsRwF_>FKZ&*E&~c&_h!@BhFcu=W!vgvg|F z$!t2GG-GW;T3N5yEQ`vOwlZI>cuWRYE#b@e^%=O|aQHV)uiNkVynfH``~P@zdxCmv zM{R?MfQxqlj*pCyc8-#jZ-jZ6fiH&&e43Vvly0M;k)@`KpmwWuhEoQgim8C5l#c;# zxVn%7qrbVny|=lu#|=Dy`QmirMGv2`efqv(gjoJa zpu=?L;KXuwNg*PJmmEUlIEkLNim0e%>)y?~x9{J;g9{%{{LBad0+K6V&b+zv=g^}|pH98H z_3PNPYtLT5B=YUx!;2qJzPx$u-TfXv&%V9;_wdQ5Py9W;{rmXym!Hq3zW)CI00t-^ ze~0)d;DHDxxSw|lHt67k)e%^Ofe=<`p@I^wcj1N{2AClM6m}@$i06G6B8e!b$Q^?! zw&d51dBKipAkQNF_;iR6+4vdH97brB+DW3G zbmFp{pm9EuXPk%%K&YaM!fB|ZJNh{yo^m#tC!~o|%IKkoR_bY>j$+#9mouvAoT!5~ z7bv2dZp!Jak&-GSpM@HFX{EQWx+$u>ruw6#BGPIpte2{a>9M}H{z~kqW9}%dvc570 zDVx;7+H0b9%KGB7p<3(htDqL^>ad>1+ANO3HcD-%xT>oxrM8Z%?ylz2XXd@&0gLax z$?3~4zW)AeX21f6NpQhk9z4&&3^(lX!w^R-@x&BYY%#>!DO|wD9Cz&T#~_C+^2j8Y zZ1Tw{r>wHc=}M>Z$}q<)^UO5YtTF&CNB1(qD9V;IbUT~ZF3;upoUyjl1+ejXLlZro z(dZ#PozewFi|y5%HtlqHP_KAyc2svtZ?%k)U2VKuKaKOzUt<^ct%J6U_M<nXNx`U*z?-0cHK4V9o^f@@~ODEf^)rg)NNmfIC)zBH+~)7*9Bc(<(A+5xYzb- zH~Dy+cRn5FFd7cs=;D=bdUU8qsQPoPhv)k1&&5ui=9CkT`*ONZ$2;l1|DIg%F3*1I z(n1$+Jn}j#uPXDKJO4ZMKua$z^~MW`{c|r9C;s^4mv8?0vsvG-_JbCH{`>I9FF$eW z3!w1D_~)A2pvz3@~fHv)<_*Z=8=vCvg024*dgW-QaZAEpdK@) zJUu2dM~+mRA^|xeK|WGOhLj{EDXAgh-Eoq8)FdVsnK~LW$B~CTVI;+KNgI+zvx*;Tmbd=61MQPug{hT>cOJl(@hN&FBr(eg)mmLE)BAbuLq%N&D7D zGZj!qUX+@xYbdJZqfqTIR8{-5RjUr#jb&vMo`*y!Jz?r9Y~IwDAKhCwNlH{{HPmGl z&E82fs!^kUi=`gj<{{fT(_~qdr%1)AC4o6q#QilRcPIx`%+yE-Pq=K(Aopc#fQxsOIg3_cj$mw8FRM>@b6+&wrre}_z zShtQcs*XKuDH#x0a$44vn04u69~9YWjuU8$B~fEVt66c@QJ$a0WoYR-S_hTZqNfF4 zYDqX(?9^4Yel1*Ef6Lq1`nI-7dkU^vi76W~I(N0SeXeu03R?h3ce+5`=5@tLT~Df! zjKl;IatGE(KPnNt7xf}!wW!|vbg{khc`tn5Bj5RIiM{r9kBPR+-~Rgdza2BlYX(f< t0vk9A>d?R$%D~_TI~WWuaKVBfOyLSYI1LI8O%V>v;SRq>!#zj<06TMv^cw&G literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/PromptDialog.html b/Pmw/Pmw_1_2/doc/PromptDialog.html new file mode 100644 index 00000000..f04b350b --- /dev/null +++ b/Pmw/Pmw_1_2/doc/PromptDialog.html @@ -0,0 +1,293 @@ + + + + + + Pmw.PromptDialog reference manual + + + + +

Pmw.PromptDialog

+ +
+
+

Name

+

Pmw.PromptDialog() - + selection dialog displaying an entry field +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/RadioSelect.gif b/Pmw/Pmw_1_2/doc/RadioSelect.gif new file mode 100644 index 0000000000000000000000000000000000000000..026a1397ed5214a2e2e046edd401667efbaa0c5d GIT binary patch literal 4476 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 + + + + Pmw.RadioSelect reference manual + + + + +

Pmw.RadioSelect

+ +
+
+

Name

+

Pmw.RadioSelect() - + a set of buttons, some of which may be selected +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledCanvas.gif b/Pmw/Pmw_1_2/doc/ScrolledCanvas.gif new file mode 100644 index 0000000000000000000000000000000000000000..da7941aed1a6c2f26c66648a973b8abf3c35f1b4 GIT binary patch literal 2931 zcmV-(3ykzfNk%v~VSWMd0P+9;|Ns900093000930+1c5{!^2=OJA#6OEC2ui0Db}R z000C2NV?qqFv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ zxj8tW(5Q4uty-_xtai)odcWYXcuX#nQ|7dK&2GEj@VI;mSbQhWNPyYcKm33W0e*rC zgoF!+iH3uNg@TQSi;{?qhlqTc6##V#UY!wndYS~7lYxDuf0C>WimaxtkE*n_d#|;v zq`MECb_WH)!Ue#?!M+lrqneelt*EA`xzDGQvd-AK&DgQLyvPJj#svVy#^4aj%bAwd zjJTN6(ejCofA;UHxYLn<-QK&vi90uN7`g}Q)&X3|u%QNl=8lz%C=t&A3;!Hy+{peA z;<-8nD<->$k)z3z3q1-$7LpvObRd<*dGv?M zFfJ#q#1`5tMXc>z`kWV(6HZwAjs$_)g=)^2-@Y9jS8zPqQEeZXh^2JS5WQLaF08nE ztbN-SYezow=D2ar&uWOSV(nd5!((sn##Sz2;q|yXR{p(yc&w-8>)$`Yd;a~ZevLpL ze*~K3-+#J=f*)@MHmKi$|J`T8fDTp|5Pb+5B-&&XTIgYIzi=Yrh$M;_V22;37?yG+ zwpfmYC{U>4j6pzjAB-{5sAEbjZa5l_IqoQ=CN}z*6Ocg;sbmsGT7+bhOGY_FlOsI| zrIc9qK&66KUYX^WL-pvSk>Z^oBbaD*uq8}grf_DOa9*$`Ld%i4pmcHO*}|MxwOO8? zfTF-BQgxmf!<&HyI;dHN?iN_0kb7^S?`eUV*V(RH8Vphp%r=OPEOQ>9q zN~)=>5}@gks;=7Vr?1`?tE{tLT5F>U@_=ZrD(>p%48H>Fp|H2&{!py34kByl4$Cr2 zptFwp5UsQiqRM8nTVb0gwY>&$t+$_n3)2wek_(!)bPk(Cy6OgHE}ccd8!t`sUS)*6 z_nwq5p-1rB??(SJy41iz7R+J52!33!NGBa8 zr9W2-P}5G+u=FleR~^IESZnPs(S*92q9tUP?X?J8dr0;GY`5+9+hm{3LD~&A^7h?$ z;={1>-`s;bCo;2$-xeoj7aA&P3*o=zZI_|)S&NuBG*&h7yY|9Qa z@fsPAJo3t;%zQ)6KM%d`X->aT_10fswf5cw(Ea$aI}JY8;*+nw;n?q3_8{jolm7bj zM-Qwe0_3lM{_!6@KmGMjDtO91hV|MRdp!k(k6wF|q!MPMqMjqDVa|)-Y06#3BrJ*fB5m zFi}7h;{(YkE;D`+P-#@70onM2DY{X8N^G7Svv|T(adB#Qd}Ex#xW^J|v0X+3WFQ5J zCPEfch=(lNA9-QNMUF3z+k4~~pUA6onWU1IWFed!smVEV(s%3#B_p#$%2Mu+j=oam z2Qi5?SCSBx(30f^X~{HO8nTaDL?J^!smtf_(to~$Brp**Lz zBiPWALQIMv6{SW;YEfdPG^8utXiF{gQs{}4r5&YU7i${4genxLCMBXr!^hK}vT~%< z%&8|)T2$QmG+;=b>7knHR95O!lTu9$Rd4rHsLE8S^fKaBQP)+kQZ%bt9V_U{YSw_F z^##OK>)qJ8udh-n3#d$>Tt7$Gx-Qg4TFC1-_lmi`*6XYo$`DSL+C0KK&ai&nCWP$s zP=h*Fc!P9nVihac!Cn@#qr9pZC;OewdiJw(g`;SjNLuhz*0QK|8)PFk&DMUzov@8< z2m`fRKJrDe31X~Rb-P1;J zxY=a~bUFHq=?1sD){Sj=U{yQ?|Je2JGmCPXAzFjf{8lT4}-WR5*{&$ zn`+_{QzXUS-JX80Y2kQjc*5x8X^m~1U>L(Ug)>&=j(J?(>Ef8dDQ)q(iVWN%_cx+L zzSoUaOuZnRG0IZzv4~@AL@Of^%UNc!a=F}PaDq9^(ls)bhpS5^BWKEF{-l=!h&VX^ z7%VF6p_{p5XPxRN&*9wubIi0%**NES&cHkK$NDT>0s-24l4}5?(L2CENBUG^RJP1V<6TGJDZDk&FfzK`qwU! z7okhLW`qIz*vL+{i$ul|T%T0eMgjuI9O7(?jV{_hn07;|t?lJu+Xvm|QKo(D=hc0? z2jKOjNp8E89`-p+T7 z%UmX1X-75$|MiAW$EPVn4p}*gj6dC(w1NXT3W;y11y6P5j~;|MRbQ%*w4Q9x6l3L+xq+955M@we}Xxf|NQ7rzxvnD{xPhe z{qT>!{Ql=p|N2`2^cX;~eO%K0{`>#`02qM9XI^U7WcYUh`u7o}A%G0nfDZV8*!N-t zNNk*-X)2I_5>a}wM}A6xffHC2BeG=|D1rP35(~(I9N~cWM5y1cjbYg{9mvw~3tC zONpL%1%60bD#(aE2VA7_iKv*0swjV + + + + Pmw.ScrolledCanvas reference manual + + + + +

Pmw.ScrolledCanvas

+ +
+
+

Name

+

Pmw.ScrolledCanvas() - + canvas with optional scrollbars +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledField.gif b/Pmw/Pmw_1_2/doc/ScrolledField.gif new file mode 100644 index 0000000000000000000000000000000000000000..d1942e3dab39644f5dbf60b8989bde1411bb18e2 GIT binary patch literal 615 zcmV-t0+{_rNk%v~VGIE!0Pz3-|Ns90007z9*@A+CEC2ui01N>o00091l#i*)?GK}z zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg>M$BL1+*#f@qT-gmiJ6>)L4lRDZjsB=US>2uh?_Mr1 zEFo*n-`)TI&ym1z^v+ESh_FF6ajE<{OxJK-sDTnGF044qVlMuA7AGcz_%C0Ced`Xg z+X%3vM1=-ds%+WHAg+rMYZ45X$`;O@CvTy|Ht8ojk(%U`Oo>#e$)yE1x|~=K=u>7& zT{4Avm1<9SpM=&3N09-*}fd(FkV1f!R zs04qUya8c^5>7~Ag%(~&#(x@a$YF;beh6ZSB92I6i6)+iVu~uR$YP5wzBoq#06PP6 BFVz45 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/ScrolledField.html b/Pmw/Pmw_1_2/doc/ScrolledField.html new file mode 100644 index 00000000..4c28cbc4 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ScrolledField.html @@ -0,0 +1,187 @@ + + + + + + Pmw.ScrolledField reference manual + + + + +

Pmw.ScrolledField

+ +
+
+

Name

+

Pmw.ScrolledField() - + single line scrollable output field +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledFrame.gif b/Pmw/Pmw_1_2/doc/ScrolledFrame.gif new file mode 100644 index 0000000000000000000000000000000000000000..089a201ec85945dc8bc2499fe1307f6e65c18d47 GIT binary patch literal 3926 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/ScrolledFrame.html b/Pmw/Pmw_1_2/doc/ScrolledFrame.html new file mode 100644 index 00000000..5cfe3b3b --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ScrolledFrame.html @@ -0,0 +1,479 @@ + + + + + + Pmw.ScrolledFrame reference manual + + + + +

Pmw.ScrolledFrame

+ +
+
+

Name

+

Pmw.ScrolledFrame() - + frame with optional scrollbars +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        # Create the ScrolledFrame.
+        self.sf = Pmw.ScrolledFrame(parent,
+                labelpos = 'n', label_text = 'ScrolledFrame',
+                usehullsize = 1,
+                hull_width = 400,
+                hull_height = 220,
+        )
+
+        # Create a group widget to contain the flex options.
+        w = Pmw.Group(parent, tag_text='Flex')
+        w.pack(side = 'bottom', padx = 5, pady = 3)
+
+        hflex = Pmw.OptionMenu(w.interior(),
+                labelpos = 'w',
+                label_text = 'Horizontal:',
+                items = ['fixed', 'expand', 'shrink', 'elastic'],
+                command = self.sethflex,
+                menubutton_width = 8,
+        )
+        hflex.pack(side = 'left', padx = 5, pady = 3)
+        hflex.invoke('fixed')
+
+        vflex = Pmw.OptionMenu(w.interior(),
+                labelpos = 'w',
+                label_text = 'Vertical:',
+                items = ['fixed', 'expand', 'shrink', 'elastic'],
+                command = self.setvflex,
+                menubutton_width = 8,
+        )
+        vflex.pack(side = 'left', padx = 5, pady = 3)
+        vflex.invoke('fixed')
+
+        # Create a group widget to contain the scrollmode options.
+        w = Pmw.Group(parent, tag_text='Scroll mode')
+        w.pack(side = 'bottom', padx = 5, pady = 0)
+
+        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 = 3)
+        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 = 3)
+        vmode.invoke('dynamic')
+
+        self.radio = Pmw.RadioSelect(parent, selectmode = 'multiple',
+            command = self.radioSelected)
+        self.radio.add('center', text = 'Keep centered vertically')
+        self.radio.pack(side = 'bottom')
+
+        buttonBox = Pmw.ButtonBox(parent)
+        buttonBox.pack(side = 'bottom')
+        buttonBox.add('add', text = 'Add a button', command = self.addButton)
+        buttonBox.add('yview', text = 'Show yview', command = self.showYView)
+        buttonBox.add('scroll', text = 'Page down', command = self.pageDown)
+
+        # Pack this last so that the buttons do not get shrunk when
+        # the window is resized.
+        self.sf.pack(padx = 5, pady = 3, fill = 'both', expand = 1)
+
+        self.frame = self.sf.interior()
+
+        self.row = 0
+        self.col = 0
+
+        for count in range(15):
+            self.addButton()
+
+    def sethscrollmode(self, tag):
+        self.sf.configure(hscrollmode = tag)
+
+    def setvscrollmode(self, tag):
+        self.sf.configure(vscrollmode = tag)
+
+    def sethflex(self, tag):
+        self.sf.configure(horizflex = tag)
+
+    def setvflex(self, tag):
+        self.sf.configure(vertflex = tag)
+
+    def addButton(self):
+        button = Tkinter.Button(self.frame,
+            text = '(%d,%d)' % (self.col, self.row))
+        button.grid(row = self.row, column = self.col, sticky = 'nsew')
+
+        self.frame.grid_rowconfigure(self.row, weight = 1)
+        self.frame.grid_columnconfigure(self.col, weight = 1)
+        if self.sf.cget('horizflex') == 'expand' or \
+                self.sf.cget('vertflex') == 'expand':
+            self.sf.reposition()
+
+        if 'center' in self.radio.getcurselection():
+            self.sf.update_idletasks()
+            self.centerPage()
+
+        if self.col == self.row:
+            self.col = 0
+            self.row = self.row + 1
+        else:
+            self.col = self.col + 1
+
+    def showYView(self):
+        print self.sf.yview()
+
+    def pageDown(self):
+        self.sf.yview('scroll', 1, 'page')
+
+    def radioSelected(self, name, state):
+        if state:
+            self.centerPage()
+
+    def centerPage(self):
+        # Example of how to use the yview() method of Pmw.ScrolledFrame.
+        top, bottom = self.sf.yview()
+        size = bottom - top
+        middle = 0.5 - size / 2
+        self.sf.yview('moveto', middle)
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 18 February 2001 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledListBox.gif b/Pmw/Pmw_1_2/doc/ScrolledListBox.gif new file mode 100644 index 0000000000000000000000000000000000000000..9a595618f8dde05dfba8d4653dd57c017e9894d7 GIT binary patch literal 1855 zcmV-F2f+A8Nk%v~VbTDo0P+9;|Ns90007z9*)ULG!^6XZf`WB*bpQYWEC2ui0MY=c z000C2D7xJKFv>}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhHyD?nrf97myY zc_}KK$)rHatXho?>h#L(ZXrivQ7WdEy=a*h`~5O`2_Ec7>;;qN}W}uCK7Mva__cwzs&s zy1OL>zQ4f1!o$SH#>dFX%FE2n&cF=M6wlPv*4NnC)Bw@V+!MaMd;s4Hz69v$1O@8p zbMFi1?EviU1oRT&@@f18*i(luAHi}F{0(v>f#JUr0SBTZCvhS|2nvljTm=5= zVTygG;(~o!;fEbS$HdeJlL+3R7@Dq7lxpHI+B9-?J2tIZjB^G7yjjkpb@JIY?7| z`bO95T)M|;)KDL{{_z^NUD>l;pS7KuG3neqYTH%~6L|35ykm1VzC$={;v*}gKn(Yx zbJWoN@kOM8`mO7|*W%sb-4^(JzE>yR6lf>=_D2D+*LX9j`|rq;-(GGte*R(q{s96Y zQi>3$N-gIpH`98ZR96)xRTY@UcIAbV;7{Vc)u4T-ti;KNS*$S?E*I{%pjB*)RiB0h zs`x+{8c8=xiJP6sqJ%g;xS@+X>ZJ>f*>$#8gafkpp@0T<5+8~A=@%q}@^QF{kx}-y zqJTK%0%Ur{F_*)Z8G300n1hKqW|PT1Y37+v>1X0lYqGhTn{R%_TAVSEi5s3WfJV-r zfCj22pLt>?=%ED+DoBMDP6(WzQ4M;Nca2sD8JTt@^98TtX`>SSf}Jq8kvVSZ;rx!ZPbnn_ep}wZ$eo?T}gmtLe8w5^~C} zP?*avuJ#d#AGg7VIbVpXQf62oZ=gC~t`B=^$hvkaN~jAIH{h+o7q?{ZsQ7jaL&gM` zDYC~UgUs>CD3H9G#Voh{F|8rTyn@Rx!ECcxDbp<8h#*Mp8O|d`D{v+@6TR_ZlI$FU z(uvkAVk+=?sK|Y0LT$8?{H|AIoLWoGtfN-r5ii&?vnw{I*!GwspJD$j?YU7Nx!t2_ zSG@M6#lmQ}&@9Exbc|iQ3oqPxYaI2@+OkR+lxMFg_?}MwXVtUXD_8z>;+Mmzx#cf+ zyST}pi!eEVrH^pBjj3j-Ll8;`R#I9-*9RMKo9s2cm*_|0G~s^1a9Df#&h88=7c|d9qNJ@%%BE0 z$iWVJ@Pi->p$GxhCN~8M0CY;B3RlR&7P|0-Fhq?3An2?Z+VF-r%%KidIKu^E$Aaw$ zfIfss03yOr3@bF^4wuNp6!x%$P6DDjl!y)@QZfFCMkGQCuh_&cdNCbOq@W3RoTfOxSxQz~bB)+c;R&P3OiogAkgIg3CtWGccTV%1Urc8Ox7kc- z9uk&&yd*I9IL=%K@}Kx*qdpy}sdHAdh5ipsXcre6#cf(MqWbBiM2+bu4_dUC7|m!v zH`>N@a&UAFC8
c+)zrbg^CfJ|pf)0*1!rZ~;1PIt=Fp8E8sKn-e8=faqC#7=?~ zAnH)+6hWkBpeboVO9P#10jOR?ErV-|r>K{%#GJ;e&CAPHIh8)IHi;iW*_%!*Re`G* z25(RlOjgR1&pv{#nk#jgC4r-p=?zu)noa# ztWYf$nTm3l!>X4&%_b|dOA!uc8|c}$(rrR{HCFu;8&`B>6Q+6_p=@VM+uGXpwi)D> tN5O&H-um{p!1Zl3LP*u(8uz%!6HTsim&@GdI`_HIjjnX3i_`=F06XLSo + + + + Pmw.ScrolledListBox reference manual + + + + +

Pmw.ScrolledListBox

+ +
+
+

Name

+

Pmw.ScrolledListBox() - + listbox with optional scrollbars +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledText.gif b/Pmw/Pmw_1_2/doc/ScrolledText.gif new file mode 100644 index 0000000000000000000000000000000000000000..b766c95bde7ff1cf82ff242b823b4db1e4865da4 GIT binary patch literal 12007 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 + + + + Pmw.ScrolledText reference manual + + + + +

Pmw.ScrolledText

+ +
+
+

Name

+

Pmw.ScrolledText() - + text widget with optional scrollbars +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+
+        # Create the ScrolledText with headers.
+        fixedFont = Pmw.logicalfont('Fixed')
+        self.st = Pmw.ScrolledText(parent,
+                # borderframe = 1,
+                labelpos = 'n',
+                label_text='ScrolledText with headers',
+                columnheader = 1,
+                rowheader = 1,
+                rowcolumnheader = 1,
+                usehullsize = 1,
+                hull_width = 400,
+                hull_height = 300,
+                text_wrap='none',
+                text_font = fixedFont,
+                Header_font = fixedFont,
+                Header_foreground = 'blue',
+                rowheader_width = 3,
+                rowcolumnheader_width = 3,
+                text_padx = 4,
+                text_pady = 4,
+                Header_padx = 4,
+                rowheader_pady = 4,
+        )
+
+        self.st.pack(padx = 5, pady = 5, fill = 'both', expand = 1)
+
+        funcs = 'atan cos cosh exp log log10 sin sinh sqrt tan tanh'
+        funcs = string.split(funcs)
+
+        # Create the header for the row headers
+        self.st.component('rowcolumnheader').insert('end', 'x')
+
+        # Create the column headers
+        headerLine = ''
+        for column in range(len(funcs)):
+            headerLine = headerLine + ('%-7s   ' % (funcs[column],))
+        headerLine = headerLine[:-3]
+        self.st.component('columnheader').insert('0.0', headerLine)
+
+        self.st.tag_configure('yellow', background = 'yellow')
+
+        # Create the data rows and the row headers
+        numRows = 50
+        tagList = []
+        for row in range(1, numRows):
+            dataLine = ''
+            x = row / 5.0
+            for column in range(len(funcs)):
+                value = eval('math.' + funcs[column] + '(' + str(x) + ')')
+                data = str(value)[:7]
+                if value < 0:
+                    tag1 = '%d.%d' % (row, len(dataLine))
+                    tag2 = '%d.%d' % (row, len(dataLine) + len(data))
+                    tagList.append(tag1)
+                    tagList.append(tag2)
+                data = '%-7s' % (data,)
+                dataLine = dataLine + data + '   '
+            dataLine = dataLine[:-3]
+            header = '%.1f' % (x,)
+            if row < numRows - 1:
+                dataLine = dataLine + '\n'
+                header = header + '\n'
+            self.st.insert('end', dataLine)
+            self.st.component('rowheader').insert('end', header)
+        apply(self.st.tag_add, ('yellow',) + tuple(tagList))
+
+        # Prevent users' modifying text and headers
+        self.st.configure(
+            text_state = 'disabled',
+            Header_state = 'disabled',
+        )
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 30 August 1998 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/ScrolledText_test.py b/Pmw/Pmw_1_2/doc/ScrolledText_test.py new file mode 100644 index 00000000..53a5ab48 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/ScrolledText_test.py @@ -0,0 +1,116 @@ +# Based on iwidgets2.2.0/tests/scrolledtext.test code. + +import Test +import Pmw + +Test.initialise() + +c = Pmw.ScrolledText + +def _testYView(doBottom): + w = Test.currentWidget() + top, bottom = w.yview() + if type(top) != type(0.0) or type(bottom) != type(0.0): + return 'bad type ' + str(top) + ' ' + str(bottom) + if doBottom: + if bottom != 1.0: + return 'bottom is ' + str(bottom) + else: + if top != 0.0: + return 'top is ' + str(top) + +kw_1 = {'labelpos': 'n', 'label_text': 'ScrolledText'} +tests_1 = ( + (c.pack, (), {'padx' : 10, 'pady' : 10, 'fill' : 'both', 'expand' : 1}), + (Test.num_options, (), 10), + (c.importfile, 'ScrolledText_test.py'), + ('hull_background', 'aliceblue'), + ('text_borderwidth', 3), + ('Scrollbar_borderwidth', 3), + ('hull_cursor', 'gumby'), + ('text_exportselection', 0), + ('text_exportselection', 1), + ('text_foreground', 'Black'), + ('text_height', 10), + ('text_width', 20), + ('text_insertbackground', 'Black'), + ('text_insertborderwidth', 1), + ('text_insertofftime', 200), + ('text_insertontime', 500), + ('text_insertwidth', 3), + ('label_text', 'Label'), + ('text_relief', 'raised'), + ('text_relief', 'sunken'), + ('Scrollbar_repeatdelay', 200), + ('Scrollbar_repeatinterval', 105), + ('vscrollmode', 'none'), + ('vscrollmode', 'static'), + ('vscrollmode', 'dynamic'), + ('hscrollmode', 'none'), + ('hscrollmode', 'static'), + ('hscrollmode', 'dynamic'), + ('Scrollbar_width', 20), + ('text_selectborderwidth', 2), + ('text_state', 'disabled'), + ('text_state', 'normal'), + ('text_background', 'GhostWhite'), + ('text_wrap', 'char'), + ('text_wrap', 'none'), + ('vscrollmode', 'bogus', 'ValueError: bad vscrollmode ' + + 'option "bogus": should be static, dynamic, or none'), + ('hscrollmode', 'bogus', 'ValueError: bad hscrollmode ' + + 'option "bogus": should be static, dynamic, or none'), + (c.cget, 'vscrollmode', 'bogus'), + (c.cget, 'hscrollmode', 'bogus'), + ('vscrollmode', 'dynamic'), + ('hscrollmode', 'dynamic'), + (c.insert, ('end', 'Hello there\n')), + (_testYView, 0), + (c.yview, ('moveto', 0.02)), + (c.yview, ('moveto', 0.04)), + (c.yview, ('moveto', 0.06)), + (c.yview, ('moveto', 0.08)), + (c.yview, ('moveto', 0.10)), + (c.yview, ('moveto', 0.12)), + (c.yview, ('moveto', 0.14)), + (c.yview, ('moveto', 0.16)), + (c.yview, ('moveto', 0.18)), + (c.yview, ('moveto', 0.20)), + (c.yview, ('moveto', 0.22)), + (c.yview, ('moveto', 0.24)), + (c.yview, ('moveto', 0.26)), + (c.yview, ('moveto', 0.28)), + (c.yview, ('moveto', 0.98)), + (_testYView, 1), + (c.yview, ('scroll', -1, 'page')), + (c.yview, ('scroll', -50, 'page')), + (_testYView, 0), + (c.yview, ('scroll', 1, 'page')), + (c.yview, ('scroll', 50, 'page')), + (_testYView, 1), + (c.clear, ()), + (c.get, (), '\n'), +) + +kw_2 = { + 'hscrollmode' : 'dynamic', + 'label_text' : 'Label', + 'labelpos' : 'n', + 'scrollmargin': 20, +} +tests_2 = ( + (c.pack, (), {'padx' : 10, 'pady' : 10, 'fill' : 'both', 'expand' : 1}), + (c.importfile, 'ScrolledText_test.py'), + ('text_relief', 'raised'), + ('text_relief', 'sunken'), +) + +alltests = ( + (tests_1, kw_1), + (tests_2, kw_2), +) + +testData = ((Pmw.ScrolledText, alltests),) + +if __name__ == '__main__': + Test.runTests(testData) diff --git a/Pmw/Pmw_1_2/doc/SelectionDialog.gif b/Pmw/Pmw_1_2/doc/SelectionDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d6f3dd916773e370091156fbf6dbeee9035bcb0 GIT binary patch literal 3204 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 literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/SelectionDialog.html b/Pmw/Pmw_1_2/doc/SelectionDialog.html new file mode 100644 index 00000000..c4708232 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/SelectionDialog.html @@ -0,0 +1,281 @@ + + + + + + Pmw.SelectionDialog reference manual + + + + +

Pmw.SelectionDialog

+ +
+
+

Name

+

Pmw.SelectionDialog() - + selection dialog displaying a scrolled list +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        # Create the dialog.
+        self.dialog = Pmw.SelectionDialog(parent,
+            title = 'My SelectionDialog',
+            buttons = ('OK', 'Cancel'),
+            defaultbutton = 'OK',
+            scrolledlist_labelpos = 'n',
+            label_text = 'What do you think of Pmw?',
+            scrolledlist_items = ('Cool man', 'Cool', 'Good', 'Bad', 'Gross'),
+            command = self.execute)
+        self.dialog.withdraw()
+
+        # Create button to launch the dialog.
+        w = Tkinter.Button(parent, text = 'Show selection dialog',
+                command = self.dialog.activate)
+        w.pack(padx = 8, pady = 8)
+
+    def execute(self, result):
+        sels = self.dialog.getcurselection()
+        if len(sels) == 0:
+            print 'You clicked on', result, '(no selection)'
+        else:
+            print 'You clicked on', result, sels[0]
+        self.dialog.deactivate(result)
+
+
+
+
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home +
Manual page last reviewed: 18 May 2002 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/TextDialog.gif b/Pmw/Pmw_1_2/doc/TextDialog.gif new file mode 100644 index 0000000000000000000000000000000000000000..4438828dc8e49335a38b8fc93a8fc880aad666a1 GIT binary patch literal 4953 zcmV-f6Q=A(Nk%v~VQK*%0rCI<|Ns90007z9*}!0T!^6X1Fgt>Rg8zo6EC2ui0BQjr z0RRL3c)HwPF3L%(y*TU5yZ>M)juJ#-g?X-Q>%MR-moc&_iq?*G7`a7Zi~kI1BQ z$!t2G&|eSPQ$(-Wtai)odcWYK)v7|x&gisy%|4YcZ_ACWskQI;yna8jqv8~HHzosx zhKGlCh>MJkj*pO$l9QB`mY0~Bnwy-RjEa(=k%DvwlcJufs-6J>h^>;Xva*!0g|n`= zxr?@|zQ4c&sE@;rq*Dr~gu%?syt}%Uy|ufx(~Z~8+S`rA-OHnM$flv-+~=vZx~{$1 z(T20{u<--!?78&T>h<^N{;A$RnIk4H;39+n5=Pob%O19B`1h}_6A<4Tq&gwUf)cn#HEbmXuiy^1(z9-669(`?-igcgB@u4X=N|#cWS~u9-#wjLG=+t*Pl+6Zz#4 zSZb=Qw#w#cm&iYt@>oY^alzwRohuEI7MESSf}{+MjBX%fqy7PX!F1$>>OK^|V4qR`z3m+@6j1QmNtHT5Td$5xRU#w%c;65Djz8%jPvBmf5 z%PzYbBYNehDf1|A!xH05GQ=XIJ2S;KmfW(B8Sk7k%`#8?Z@mkXTeHP6Bb~6!KJ%Pt z(+ESnFVo(3>ua4f!`s=XA4*H9%+o-whxaY3>?!5Qz`|rSyp6BW;(=IuTn`5qg zln>Hw00GcPPr&oiL*IOjw=b`Klh;2=z4QQl4}S43X21RUM0S6q_||V;Jpt;=eZ2GN z*B_+%?vJ1U__ohqz5(_NV2|*}zUJ-EdgObQ|GX!_2Ih!>{99l3;-{(wuFruOtPupG z*S!N$5P23%UIs@9qYc7uc;fq@@m6L#0Fv;90x)6x_NT(~h0ujC9N`8jNW%mk>4rHZ z;SO1rzZxo#h1kPk5FH3X6&BHl=362YQFy|yJMvvUm$h;KEMxO0Zm6Q=7lW0gcwUBI}yxS#bmLs@jl5aL!TiV>VHbpMdl0RD3 zDYL|{R03&}R_r96KAFm;Q4D8=GbNoSiL^_O?3gy1Wif3jEuby)mUDz+AE7wLTGn!C zR7;n`+=eofDUFp(lNc*;Cbp8D%$CWk;2BSF zc9TZ9yyG?+Vyr6iaJWsM29~IfEo@P-iQ2S6wz9BnELt%-+pV_MtJpm4 zWnG)vn%4G#dd($YJ(Cw5imjq6h3-dbD_PvSwxrF??opd-*TH6Y ztBORaP93?>&i?PSFO5_p(e~3(dh2ZMEH8WADayCGva2YIFJb4&-+a1KpWo!CN@)t; zviUZm=lrk84D8%~krS_Z^{h10i%5ZTN||)S@S0j`RSFwaQ?FEBhz-Tz(R!Gdl^XHo zR9vVMOPHX;8L9eeM_i4101mvq#!s)@Tf zZjq7Khhz&od8ScnGLU&?(-}{Bb5#Z;!}uB3j@=W=3f88AN&3#Qrn$f8yyuby`DM_4 zt(w?1n@XqqT!zjx&ym&s?neQg(kREU#xCtKOn>ZHJ-_z2)`f4Q3$58M@3hNaMs$Z2 ztzIj?R-KzYaFh2N>U@H?Cl2-3)Iy8WFo<1%J-eW&!d!>yL&KQej0 z?+C|)HdW*+|JnY=J`Qso$sFA<_HoMP?PQ{tbKdN3r_}ZtSA5}uvpwh0&k-2(Ma#I< zSY|Gv1#RnZKGd*LkNLj&P4&?B)#L9TxsZ8H>`~8o)i`hX)WhiSv#EhBK+)!O-tZwO88ap zH1VH=X5%{w`DTx?m9q>^=SvFub(j9~t=}^2)4cQ&=l;&TPkOsgU;HT}e+9vBc=V?~ z_6i?{2jhP$WPaO+fYhRZHUxly z zaU}R*GYEqzOJJ2-mlCxoU4Q6uJd zj>1?fmxRnmNli6!PUvk*5`@~9ftLqzfoCXMn1*xaBu`i*`Q~{-LWcS`Y}RCi^kr8Z zMP^QSYUJg2y~Is&c6nOmPiOW@c$J4Dg?DjAh}CCvPB&)n#CS|XhgL^>lZA&{gH_+g z{&gc|G~#w^%avT&N`-66)<|HrcU+i0wTOS;M}-o{iJE9##6(w+w~UjfQ){)2 zuyt2*b$gGfYOvKX;iz_xSZr)JRBw1__IH1kcU7oHTaYD=yS91bD2!=GYW=8d=mcry zMU2mgh69;(#OR7_NQ?6*di5AozLbe!B{ZXUj5O1EiG@%-Ws%G_ZXj7*9;sUhd3xg& zjQq$v(@1yKScV_CO1$Na1$le1_;N7WZhwYS*VK8Vn2@r#Qoe|7yy%P@>0LzrC13F< zkNY*~UIm|}6cDMSV>!6aW(QkOVLDSOE*gGnTX>0es{m_GP}vZ9!1 z$C!<|k`akqVAx(qlb5Izc8-~HY`9%th?y)Wc$>L@Mwg8{2bpOyn%hToSoksR_*Pa) zZxYpCedujpNlNQBUzzrhlxKiLh;=c^j~>&Lj|G%|8E&mNoUxcks%e6dHdi4Ncni5- zI)`sr_l}44jm#;TzFCE5n2mWzlu!j>>*!WmR$GsUk#xqLJ?L?Xmv{ck=7++`QRq3B z-dJlW*^OM(oG(e48+lpN3831kcJ(=HZMU0C$&{0Mhm;wh6d8)eDPG`KjHpPJY9*mk z#Ge4ip#NEK*%_M)c9m7LNSxSB7W!bg2by%Fp;hQBr=p^J!=mBmq8E0Y`^lcSc!>>& zETIBn8H%I%r=xC(nyn(E?MI}pVx$3xq^zQ(6Ud~e;-pZTq(It|xOkUS8l_e0lvfIs zSvo3G`lYB6rebO;WLl=8a;9hsDr&l>o6@FknkjG^r<5|Mbb5VTI)zW!qIX&;cG{~FmG(qg)%Q=0*k-l4h=?eNPnUbxn3j&l zh=<5ua#$y^T6!$ElI!}ZqAIQtNU0(;tVk7!$mW^YiC`g$b>%6Bh-o;r z+Gd)SFzASzz7?#=b&iX&tj+j}@A_c)D3b1#OhT2P9J7z27K{KpSqFKax@e(qkvpVzBe7v9B%BJFO_U*aW~D-krJV`0I1;+5%C`YGx>m%JTza}tS(;_L zy3ORe9+8*uL6>zN2M} zLE4u6>1=D4k872%a(k}_OTPt*q9@~Si;F94q`x`pzXtc7pK6`dsk*BZ#P#8#fSA4o(h~VyVtyQtF;7dqK-Pfu@^oE%}%0!FK7TWL(A$41Zq?#^VaSGkUq03&$g<#uJ7jeB8%={KtSC$bvk`CL&>) ztH-uO$cntkjNHhM{K$b!J0G&Xb`1VCmQ%^_a>sno0BAv9L&Nz%*0&G#{9>!Jj1Fg{V z{5TEWB@c~33r#l@%_SA>Ko=c18NDSN-9Q~3HXofcpSZ;#EkGmfH6{JQfC#TC9Y8B> z$p?+Q6sjXJZ9g;JG%f9))BcGgIbAHy?6bo|RIq03<>b>3!GA0}V2z(IV@;%@5UEe72-ZlW=_PyWy-QWH#0)DUo Xg1rR#!QKXb;0T`JNl@TLkN^NXCRZ+t literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/TextDialog.html b/Pmw/Pmw_1_2/doc/TextDialog.html new file mode 100644 index 00000000..3f4995f4 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/TextDialog.html @@ -0,0 +1,301 @@ + + + + + + Pmw.TextDialog reference manual + + + + +

Pmw.TextDialog

+ +
+
+

Name

+

Pmw.TextDialog() - + a dialog displaying a scrolled text +

+ + +
+

Inherits

+Pmw.Dialog
+
+

Description

+

+ 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 +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/TimeCounter.gif b/Pmw/Pmw_1_2/doc/TimeCounter.gif new file mode 100644 index 0000000000000000000000000000000000000000..26cbdba5d62e5497e8cb8e7307b5f031e3413e3d GIT binary patch literal 1077 zcmV-51j_qINk%v~VX6RC0Pz3-|Ns90007z9*@A+CEC2ui0IC3000091l#i*)?GK}z zwAzca-n{z{hT=$;=82~2%C>F^#PUqn_KoNI{q_yu`wW7_18|o!AaTm2O)xAHk4{>& zYHea;!>H6pwG6Jn%D5@+euH5%IgNHh*I+>mZZA{LdAOI}(zf>|*C+P}xFR^gcUR~* zIF}e`s1VT5sF!fbkjcQgaE3UEvUm`H+DW*X8oG*r3Ys8F%3^8|s~X2Di{NS5sz6(- zavK}$`-*$)x_injtVWz-dYn6}Y>jO2`)nO8Iek*C4PLqYjqNO;-3uixZnD_E-OWy~ zeoo&z91o+9FPXD_`5@hEr*4!#5Q6q0>*i1vM27+uF7$8P^)3Prd2zp4BVe`=f-8*R_wd3b@`h03pOu= zv4Iyj;v=?ig*$}>|Jb`&apJ#`@ltTd3G=1~nK>`G25Xxg$dgG=INUe^V-A|xS=#&w zm*>#Wmen?5+O@Z9sCS1B)*GEHXnj&UXx;iYE8DTd{NZ5U2w43 z=N*0s9h6Rd5~c^8d-r_i&U6KC2p@LDDR|ItpxmcHe(O<4;eRM%$Rch7h9_Pe^lir= zWeXWSC`?2Kq+mpu&l0 zM2?OvmRkf%Ix5*|iY|Iuqk}~%!K0TtNht$vW{N4KHcHBArwV*3s-+KTy6U8+uKLav zsL5Ivt);%|BCT@i$_=k~n(9?bzjhidNW)S}{)Mf1D66ZhxO%$m7G%get+cm3OA{tI z)wHd)*W#M3E-S$_u1m)*8g4V?=Cm%i-@clzIR>%xlDW@1+OD_xiaRe%=Q`F9MF&ho z(7>xiRMEYI0ra530|n$T!{sEbumkfzOqoFiN31c%d;KdIIT3Q4Rl_9nLY%`O=OuE= z8J9eToT-bHg vT!F*&F0gjk)d=EOC|)?RVcESC0E$l%PB~hAUyga^ns3f|=bnH5Yyki}CVUYf literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/TimeCounter.html b/Pmw/Pmw_1_2/doc/TimeCounter.html new file mode 100644 index 00000000..6fbdea33 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/TimeCounter.html @@ -0,0 +1,363 @@ + + + + + + Pmw.TimeCounter reference manual + + + + +

Pmw.TimeCounter

+ +
+
+

Name

+

Pmw.TimeCounter() - + counter for display and input of time +

+ + +
+

Inherits

+Pmw.MegaWidget
+
+

Description

+

+ 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.

+
+class Demo:
+    def __init__(self, parent):
+        self._time = Pmw.TimeCounter(parent,
+                labelpos = 'w',
+                label_text = 'HH:MM:SS',
+                min = '00:00:00',
+                max = '23:59:59')
+        self._time.pack(padx=10, pady=5)
+
+        button = Tkinter.Button(parent, text = 'Show', command = self.show)
+        button.pack()
+
+    def show(self):
+        stringVal = self._time.getstring()
+        intVal =  self._time.getint()
+        print stringVal + '  (' + str(intVal) + ')'
+
+
+
+
+ +

+ +

+ + + +

+ 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 0000000000000000000000000000000000000000..2063df02f739afc67713b3ac3c7dc00a56fa3182 GIT binary patch literal 981 zcmV;`11kJSNk%v~VL$-|0QCR>>+}2K>-*j2_to9^(Ao3H(DQ?r;lj)AzQ^;q!tS)a z>UxdgbB5e$e%xVq*8m{GvAXW7wd$p=-**9_u}IF-QD-u+4I%a_t4Pu$H()+!tS}b?zFV(tE=jzrR4ws z00000EC2ui06+l+000L5Ko|@VD;8x)nSjO|IBhio;dU!naX7@`kV|-VItWCuiRBHH7CMGF^6B8;b6p1T~6^$1bkQOa18yg*$mmDu1oE{(` zA0eWnD5a*SsHv)}tgWb{qaUB0oi7|5moAkpkro$?6^n@!hlPWK4h|>Fd?gIed3ALL z26J%NZf$E47(6^@I|^c8UI{r{=vG!#QZ+SBOf&)lNi#+<0766fF*5x!Gh{FkFrWqv zcTsK-Sa)L!4lW1E=}?eBfw(gf)T~kS=GwJ68l>SFk!MdIK7mX)Na0`tp$Uo%aKn_wi zoZ z3Ov-3qf0q)WXhaL!!cV1k80-_kVdkkvl4+C08*K(&@e@f7WIOZbHh%lnmT;~0gF`9 z-@sWdg(Vb(Cr(jsDX+945(^dwx=wK1*At*ljBi@=L~Ape2cI{ zF6N5n&e_FFrT*S`edhrT5TGAEeTDURSU>_D^iDzUJoeaK@_C`aL^{X?7Y`e;kxd+; zO*2{@B>X&cT1p@aatur<48w>871Y#AZOYlQ2`#dG0!t}Np-|(EA=sEBjym?p7$S|hS1a}O?AS72bVC%+*OdQ5ZxkLZIyyCESa!O1KKsyAp>`iAWcXkq=iizJ*4N> zdS=XJQ8^G{0a;}AML__9OVEH=68;n+m=Hw#69a+q3}7H*j#+Wn7UeiN5d;`f7y&n( zeO8_bX^He*9%T8!rAjPy#g$AHoCuvwwb|xE2e%-n8z{Yr65On`meN~LNGi$da=TCh z2@6ur)JP(TBytQgUu{R0cblGN=9z3&C;>QRKtPTcT`XEaeG1(W#esb(!DpXB1OWg$ DX=Sp( literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/blueball.gif b/Pmw/Pmw_1_2/doc/blueball.gif new file mode 100644 index 0000000000000000000000000000000000000000..013183af28e872a833d371c8cf5312ec185edc0d GIT binary patch literal 318 zcmZ?wbh9u|I#b6f2V35pUoy}ldEZ|Yh;MpSJ*J7B^!{9T8 z!EcUN`5cDGwG44v8RGXcWb9?gI#xaJSoN}F3|Z#{D$Y6eo=cv3E_vQLhO%oMMb{Y0 z?lDw9XQ+P9(D9#P;(v~w{{r3r1t$Mjoc`Z%?f;(7|Cj#%@&EsSpyiYU9gqR zJ4`9?(2?pta`I@>PMV!Z literal 0 HcmV?d00001 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.

    +
     import Tkinter
    + import Pmw
    + import tkFileDialog
    + import string 
    + 
    + def askOpen():
    +     file = tkFileDialog.askopenfile(filetypes=[("all files", "*")])  
    +     print file
    + 
    + def printMe():
    +     print "Me"
    + 
    + root = Tkinter.Tk()
    + Pmw.initialise(root)
    + 
    + frame1 = Tkinter.Frame(root)
    + lst = string.split("abc def ghi jkl mno pqr stu vwx yz")
    + lstbox = Pmw.ScrolledListBox(frame1, items=lst, selectioncommand=printMe)
    + lstbox.grid(row=0, column=0, columnspan=2)
    + Tkinter.Button(frame1, text='open', command=askOpen).grid(row=1, column=0)
    + Tkinter.Button(frame1, text='exit', command=root.destroy).grid(row=1, column=1)
    + frame1.pack()
    + 
    + root.mainloop()
    + + +

    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:

    +
     listbox .l
    + .l insert 0 1 2 3 4
    + bind .l <ButtonRelease-1> {puts AAAGGHHH!}
    +
    + button .b -text open -command tk_getOpenFile
    + pack .l .b
    + + +

    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.)

    +
     import Tkinter
    + import Pmw
    + 
    + root = Tkinter.Tk()
    + Pmw.initialise(root, fontScheme = 'pmw1')
    + exitButton = Tkinter.Button(root, text = 'Exit', command = root.destroy)
    + exitButton.pack(side = 'bottom')
    + 
    + def makeGroup(tagClassName):
    +     tagClass = eval(tagClassName)
    +     group = Pmw.Group(
    +         tag_pyclass = tagClass,
    +         hull_background = 'red',
    +         groupchildsite_background = 'blue',
    +     )
    +     group.pack(fill = 'both', expand = 1, padx = 6, pady = 6)
    +     child = Tkinter.Label(group.interior(),
    +         text = 'Group with tag ' + tagClassName,
    +         background = 'aliceblue',
    +     )
    +     child.pack(padx = 10, pady = 5, expand = 1, fill = 'both')
    +
    +     return group
    + 
    + grp1 = makeGroup('Pmw.EntryField')
    + grp2 = makeGroup('Pmw.ComboBox')
    + grp3 = makeGroup('Tkinter.Entry')
    + 
    + root.mainloop()
    + +

    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.)

    +
     import Tkinter
    + import Pmw
    + 
    + def _setRegion(self):
    +     # Attempt to fix PmwScrolledCanvas._setRegion.
    +     self.setregionTimer = None
    + 
    +     region = self._canvas.bbox('all')
    +     canvasmargin = self['canvasmargin']
    +     if region is None:
    +         region = (0, 0, 0, 0)
    +     region = (region[0] - canvasmargin, region[1] - canvasmargin,
    +         region[2] + canvasmargin, region[3] + canvasmargin)
    +     self._canvas.configure(scrollregion = region)
    + 
    + def show():
    +     canvas.component('canvas').delete('all')
    +     canvas.create_oval(0, 0, 800, 600, fill = 'red')
    +     canvas.configure(canvas_width = 600, canvas_height = 450)
    +     canvas.resizescrollregion()
    + 
    + def delete():
    +     canvas.component('canvas').delete('all')
    +     canvas.configure(canvas_width = 0, canvas_height = 0)
    +     canvas.resizescrollregion()
    + 
    + root=Tkinter.Tk()
    + Pmw.initialise(root)
    + 
    + buttonbox=Pmw.ButtonBox()
    + buttonbox.pack(fill='x',side='bottom',padx=5,pady=5)
    + buttonbox.add('Show',command=show)
    + buttonbox.add('Delete',command=delete)
    + buttonbox.alignbuttons()
    + 
    + canvas=Pmw.ScrolledCanvas(canvasmargin=2)
    + canvas.__class__._setRegion = _setRegion
    + canvas.pack(fill='both',side='right',expand=1)
    + 
    + root.mainloop()
    + + +
  • +
  • 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
    + + +
+

+ + + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/changes.html b/Pmw/Pmw_1_2/doc/changes.html new file mode 100644 index 00000000..f3dd6402 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/changes.html @@ -0,0 +1,1741 @@ + + + + + + Changes to Pmw + + + + +

Changes to Pmw

+ +

+ 6 January 1997

+ +
  • Release of version 0.1

    + +
+

14 February 1997

+ +
  • 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.ScrolledCanvas megawidget. (Joe Saltiel)

    + +
  • +
  • Added Pmw.TreeBrowse megawidget. (Michael McLay)

    + +
  • +
  • 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.

    + +
  • +
  • Pmw.ScrolledCanvas: simplified widget structure. Added + borderframe, canvasmargin, scrollmargin and usehullsize options. + Added label.

    + +
  • +
  • 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.

      + +
    + +
+

5 August 2003

+ +
  • Release of version 1.2

    + +
+

+ + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/copyright.html b/Pmw/Pmw_1_2/doc/copyright.html new file mode 100644 index 00000000..0f5e7e8a --- /dev/null +++ b/Pmw/Pmw_1_2/doc/copyright.html @@ -0,0 +1,57 @@ + + + + + + Pmw copyright + + + + +

Pmw copyright

+ +

+ 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. +

+ + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/counter1.gif b/Pmw/Pmw_1_2/doc/counter1.gif new file mode 100644 index 0000000000000000000000000000000000000000..64efe355359da3e44ac9458be5474d0c238d5166 GIT binary patch literal 541 zcmV+&0^y*V)}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kH};a zz-&67(5Q4uty-_xtai)oQaJ!nU`#HX&*-#z&2GEj@c0`<0E^}LynfH`tLb(FUJ7Fb zhKGoWii?bmj*pO$l9QB0xav`V-T zOsldNx33wooffyD7OS~Hy8)QP6~BSK#Gtmo63EFu%gwW{(asdb)eOuFXxYlD<4Nu&#v@>FQ f_3PNPYv0bjyZ7(l!;2qJzP$PK=+mpmkpKWYaWWSZ literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/counter2.gif b/Pmw/Pmw_1_2/doc/counter2.gif new file mode 100644 index 0000000000000000000000000000000000000000..be894ed3c2d701622c03a6e1a05bcd227f45108c GIT binary patch literal 1333 zcmV-51y*V)}*y*TU5ySGCqj$~<`XsWJk>%MR-&vdO4fUWO*@BhFc4JRxbkI1A_ zMqE0d(5ST4oLaBgY_F>AdcWWSH%u;@jpMU=&4#7h@VNXfuiMG=yMAxY^Z$TIeu0FA zJcEXbiZ6(Zj*lgckduy*l$V8;n45f>oS$``prdS}As?uzs;jK6t`sw-135bZwzs&s zy1Tr+zQ4f1!o$SH#fP!9G0HZ^&d<=%($mt&Ow2E|9wD{_-rwNi;^XAy=I7|?>g(+7 z>9(gGAq2@Y+8p!)-R}JT{{H|2wgUif7QT7)WZaA4jaz_*r0OUrsDNR=n!I!kRp?iT*>HS!eumFK>XOOWK1P94W1Np69&hcEirN< zfonulm_LmKt;mvSN`*O5gxvWM<1MFP^*MzaRmfCkUsFI-%1C32qbHiq^VpSX*rj4c zq%A9zpiim}_eQdL6{pa+xkPYviMNDL$7K2bI6F4+V3ZkE9%i~rFB)Xy`-*KfGuF+iJI|F(J2c|Qw{cTM+iL{t!bY~R!$xSbzsZR3Hvq-xHk30*NZpSSDJeb@9e3s7VpL_3%JL5^VB{)pk zifUASquo}>+=&Z(a{(@|>m@LaICC)wz zNwm^dB5AdzUW;w2+HT8gx8A-AZn(0JOKz>^zD4XRSFFqK5zD%p3Yt#HiweCy#GCFF zpg{p*8~y&dFNOn85pcZ)OL1_%39s2O6bl3O@DmXqGI0t2mV&RucT~KCz8!BY)5S}8 ztOLk)nA}&$f{;8y#xmHJU5ZSIj0DV((cFX1;kA4O&Mx@(7z48iD7qRqk@H#DB3=aAv_McW40kzK5kp`1|Y2(=S(IC~f)Yd~yakf@s z=k3tm?D1U?-743B@=J2Z7ewG@sY&zE_QV)KGl|kL_&l1-Z{xheExFEWcg;9Ov^OJRa?*IlB4V z)33hu>DxUy8u4ow{Qh|ApAFs@2E^6L2LuFz0fCUfFDwv7vrCx(A(TJh&5wQc!{GfA zSHUPW& + + + + 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, + +

      +
      +
      +
      +(c.exportfile, '/tmp/ScrolledText_test.py'),
      +(os.unlink, '/tmp/ScrolledText_test.py'),
      +
      +
      +
      + +
    • +
    • +

      +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, + +

      +
      +
      +
      +(c.search, ('abc', '0.0'), {'nocase': 1}, '2.24'),
      +
      +
      +
      + +
    • +
    • +

      +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, + +

      +
      +
      +
      +(c.components, (), ['hull', 'label']),
      +(c.add, ('Legumes',),
      +  'ValueError: name "Legumes" already exists'),
      +
      +
      +
      + +
    • +
    +
  • +
+ +

+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: + +

+
+
+
+Test.setverbose(1)
+
+
+
+ +
+
+ + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/dynamicloader.html b/Pmw/Pmw_1_2/doc/dynamicloader.html new file mode 100644 index 00000000..01d701c3 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/dynamicloader.html @@ -0,0 +1,147 @@ + + + + + + Dynamic loader + + + + +

Dynamic loader

+ +

+ 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:

+ +
 bundlepmw.py [-noblt] [-nocolor] /path/to/Pmw/Pmw_X_X_X/lib
+ +

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 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/example.py b/Pmw/Pmw_1_2/doc/example.py new file mode 100644 index 00000000..0eed16fa --- /dev/null +++ b/Pmw/Pmw_1_2/doc/example.py @@ -0,0 +1,79 @@ +import Tkinter +import Pmw + +class ThresholdScale(Pmw.MegaWidget): + """ Megawidget containing a scale and an indicator. + """ + + def __init__(self, parent = None, **kw): + + # Define the megawidget options. + optiondefs = ( + ('colors', ('green', 'red'), None), + ('threshold', 50, None), + ('value', None, Pmw.INITOPT), + ) + self.defineoptions(kw, optiondefs) + + # Initialise base class (after defining options). + Pmw.MegaWidget.__init__(self, parent) + + # Create the components. + interior = self.interior() + + # Create the indicator component. + self.indicator = self.createcomponent('indicator', + (), None, + Tkinter.Frame, interior, + width = 16, + height = 16, + borderwidth = 2, + relief = 'raised') + self.indicator.grid() + + # 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) + + # Check keywords and initialise options. + self.initialiseoptions() + + def _doCommand(self, valueStr): + if self.scale.get() > self['threshold']: + color = self['colors'][1] + else: + color = self['colors'][0] + self.indicator.configure(background = color) + +Pmw.forwardmethods(ThresholdScale, Tkinter.Scale, 'scale') + +# Initialise Tkinter and Pmw. +root = Pmw.initialise() +root.title('Pmw ThresholdScale demonstration') + +# Create and pack two ThresholdScale megawidgets. +mega1 = ThresholdScale() +mega1.pack(side = 'left', padx = 10, pady = 10) + +mega2 = ThresholdScale( + colors = ('green', 'yellow'), + threshold = 75, + value = 80, + indicator_width = 32, + scale_width = 25) +mega2.pack(side = 'left', padx = 10, pady = 10) + +# Let's go. +root.mainloop() diff --git a/Pmw/Pmw_1_2/doc/example1.gif b/Pmw/Pmw_1_2/doc/example1.gif new file mode 100644 index 0000000000000000000000000000000000000000..b54ca9352bfd9b2458886458d19f286e223c7663 GIT binary patch literal 1546 zcmV+l2KD(zNk%v~VL<_m0P+9;|Ns90008>y*V)}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4uty-_xAYjYwdcWYXcuX#v&*-#z&2FEw7yx`8B+x7JyIyDCNAhlY3Iv3O zhKGoWii?bmj*pO$l9P`NfrEa33T}Oal%JrXqNAjff&-kGnGb-c7K9A2t4~{&t`)MK zvkR>nvYxw6wY;|!xxtp3#S^~+&B#c@%D#QN9|71)y&28V&_>dz%M!;R*$U_8F54L0 zo!IH{@DB0|^6B>T`S{;|r{S-vg$U4q;J|g$D5P_Tj)6gg5FieCC_y4cd;KPa3#a}s zLOBl->2dfe1@H73=gGtY)-xeq9?1+u7~6baESTCHWd z+S=RJ?ptdc$m&#T7HwU(f-|&?YIo}0$Mmp1CY(5gK>!wp3klKj*!@llbdzv5}gNwHf4Lq|ljC&RTRj z@261bItI<%IBx5D8ze_Lw*hVEA50%0L81MZ?>Q1o^9!-vL%2%$2d zFc-*+Fvck3jB41@qBF2<5=tyI_UPk}K%!yEjyNJ`;*nwHh~$zOA_G7vP(~@`lvGw3 zC6icYspXbjcIoApV1_B?m}Hh|=9y@wspgt&w&~`ZaKZzzc z(%>rCr0VLcu*Uic0IO!wYJ!LAutlwY+*$>%XYP6&9llZlteL`^{^QpL!=_N|6vvjC z>`?h=(5z(6c~e?;_{_Cjc^T9bEt%7DCYnO#W{YcR=?Q05Zo8qoPn_k}c9(kk6_k=m z>ybwjS?Y&TR-iQ$WP?e16w#jkMCxCz{yNt$8*6v$B#WAPt~ki9$E`sIFZ}St7w-k^RxJ@veYFaG%Cmv8?0=%=s#`s}yw{`>I9FaP}X z*Khy*_~)C}s2xKr^&uJL5O7IKN!H+?TI?xCNhk<6Pu!LTV zpM`RG8ft~EB#47txAwI}y{Y6T!FkUOy`rzC6*1ghBAFP(v?v`e>g{h(1k4Y^_o2*` zNF8Mh+Tg6yvC5TDibAAf6~Xnw8KzNfYpmJITC>7%nl6T4+)Ca?=|#Tb1~vNQWP?1JLVkEllt|y*V)}*y*TU5yZ>M)j$~<`XsWJk>%MR-&vb3yc&_h!@BhG{a7Zi~kI1BQ z$!t2G(5Q4uty-_xtai)odcWYXcuX#v&*-#z&2GEj@VIs;jK20I#sIva__cwzsbq z1iQSwzQ4f1!o$SH#>5u5%FE2n%gN5s($mh7)Yr`fy2sqz-rwK^0MOXw=Cj%r=j-gX z>5sWQyW48<6!uT^>f>7a@ccXcO%P}Xp9F(V2u46yMd2cbHXJ^XCmM&DPfMCD+V!qz28RXEM+;p>j29ip0*Ff~ohs}7hhkZWQshOQIr z9to?pgx(uyKm2vj*6V}8BaNGfMzp4dIb|BEn zry(d7fq3_w~{Ac&Ap~fOF;8pI>j^xPJKW>hR+mm+!v5X=sMK%U28D{r>#v)CDM7 zcsc0x-+}z;C!lT#0_b0Zh%GhNT-*WJpK{|7mSK7n&V`(G!SQDtUD%PxAc-OFgCBZ_ zeOIAt7hcdCc^q2kVu#-OccWAr#xPcnI^tNNeHRYspp6~g)83IU-e_52jwQL^epEV$ zAbnFFxfpEc{f66dyG>{%aQCUm;%#CYsb-QQ&PFC%J;Gq%j!4=^ZQI# zx+$Qjeaa%3WT}}Znz1@5W{OIpnkuDIx@M@Pt(uAHkgFD&<6@F6{#O@`r)sIGv!W8p zXrH8J8DpT9Vjvu`(E4iPs;zC==t_;62w{=uVre9Xx~l4_wdq=kBZS;e6z2;D#(QOX z^j5m>fzzHjWLEv57%aQmGU@A~oJPyAyAW{cmBC^1iz30>;+k!)dENS4#st>~q2uMUJN3w41a86c6`cXa#(BqtFON|TU##!5<4+tVmT=Lgn89oKvW7)ZWf)&Ab(gL zZNkA!vakU|@pD-X-XL@m|E0CT(I_O{mk>R-)UIG}(y%qxX=gw**e8fRLf1f)&BWDI ztc?fUCdfT^+dS9}mdSh%q4ynyli+tn<0g&+-cuZIhvOptEFOm7IuSmu*^p2kg5_Xf zo{{ETNM48MAb|db=tw{=h3Ry>63*<$Y}3x|xIeQG?Y#F63^cw6FZ}PF4?nyvxhJo@ zEXf$}{5Q=%FFoz8RB!$D*k`Z(_S|>x{rBL9FaG%Cmv8?0=%=s#`s}yw{`>I9FaP}X z*Khy*_~)p$JDv!V;SBgeXj*3RlR&7P|0-FpQxLXGp^u+VF-r%%Ki<$ip7`@P|MQ zq7a9;zvV@Ph~6_|Hjvmo)bWUk+;iexOa?_$NKxiSRIDN?uIMT)vVw~n^J4YDh%hmZ z@lik86&B5CJY(y+C8O%)#bCkvG#4+uaOl9h_Z@_FOB4jr`Zb;LZ z)$GPKx5>?Jdh?s$45v89NzQVb^PK2Rr#jck&UU) + + + + Pmw features + + + + +

Pmw features

+ +

+ 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.

+ +

+ + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/halfblueball.gif b/Pmw/Pmw_1_2/doc/halfblueball.gif new file mode 100644 index 0000000000000000000000000000000000000000..6977920dc3f074c1759fb9eafc693f6ff6d15637 GIT binary patch literal 299 zcmZ?wbh9u|c3&k0nVOP+d;q3jyN#QzK({~4;^Gh`jBUUrNj z>zu&k|AuS-bMycOpZ9$Jzx4kPf$sl`)BiJ+-D8N`%8;>_A$~7IOETk{J}elINXcu+C=CjbhO9GEC?Z@F?~wpTj^^paU`uBv8!r~v^f5Iv3r$pDXLnC-V&T!?KeebyBtl2r$E`Rd$4FXAMpn*U YUO_=osav^LMNv^jHFwHXCr1Wr0R5Ft#sB~S literal 0 HcmV?d00001 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: + +

+ +

+ Scale 2 +

+ +

+ 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. + +

+ +
+        # Define the megawidget options.
+        optiondefs = (
+            ('colors',    ('green', 'red'), None),
+            ('threshold', 50,               None),
+            ('value',     None,             Pmw.INITOPT),
+        )
+        self.defineoptions(kw, optiondefs)
+
+ +

+ 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. + +

+ +
+        # Create the indicator component.
+        self.indicator = self.createcomponent('indicator',
+                (), None,
+                Tkinter.Frame, (interior,),
+                        width = 16,
+                        height = 16,
+                        borderwidth = 2,
+                        relief = 'raised')
+        self.indicator.grid()
+
+ +

+ 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. + +

+ +
+Pmw.forwardmethods(ThresholdScale, Tkinter.Scale, 'scale')
+
+ +

+ 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: + +

+
+    def __init__(self, parent = None, **kw):
+	optionDefs = ...
+	self.defineoptions(kw, optionDefs)
+	BaseClass.__init__(self, parent)
+	...
+	self.initialiseoptions()
+
+ +
+

Creating instances of the megawidget

+ +

+ 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. + +

+ +
+
+
+# Create and pack two ThresholdScale megawidgets.
+mega1 = ThresholdScale()
+mega1.pack(side = 'left', padx = 10, pady = 10)
+
+mega2 = ThresholdScale(
+        colors = ('green', 'yellow'),
+        threshold = 75,
+        value = 80,
+        indicator_width = 32,
+        scale_width = 25)
+mega2.pack(side = 'left', padx = 10, pady = 10)
+
+
+
+ +

+ Scale 1 +

+ +
+

The complete code

+ +

+ The complete code for this example can be seen + here. + +

+ +
+

Exercises

+ +

+ These exercises build on the example presented so far. + +

+ +
    +
  1. + 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. + +
  2. +
  3. + 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. + +
  4. +
  5. + 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. + +
  6. +
  7. + Add an orient initialisation option and lay out + the components horizontally or vertically depending on its value. + +
  8. +
  9. + 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. + +
  10. +
+ +

+ 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. + +
  • +
+
+
+ + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + 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: + +

+ +
+
+
+import Tkinter
+root = Tkinter.Tk()
+import Pmw
+Pmw.initialise(root)
+
+
+
+ +
+

Megawidget construction

+ +Creating a counter +
+

+ 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: + +

+ +
+
+
+counter1 = Pmw.Counter()
+counter1.pack(padx = 10, pady = 10)
+
+
+
+ +

+ Now enter a number and click on the arrow buttons to see the number + increment or decrement. The result looks something like this: + +

+ +

+ Counter 1 +

+ +

+ 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): + +

+ +
+
+
+counter2 = Pmw.Counter(
+    datatype = 'time',
+    increment = 60)
+counter2.setentry('00:00:00')
+counter2.pack(padx = 10, pady = 10)
+
+
+
+ +

+ 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: + +

+ +
+
+
+counter3 = Pmw.Counter(orient = 'vertical')
+counter3.pack(padx = 10, pady = 10)
+
+
+
+ +Querying options +
+

+ 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. + +

+ +
+
+
+print counter3.cget('increment')
+    --> 1
+print counter3.configure('orient')
+    --> ('orient', 'orient', 'Orient', 'horizontal', 'vertical')
+
+
+
+ +

+ 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): + +

+ +
+
+
+counter2.configure(
+    downarrow_background = 'green',
+    uparrow_background = 'red')
+
+
+
+ +The hull +
+

+ 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: + +

+ +
+
+
+counter4 = Pmw.Counter(
+    hull_relief = 'sunken',
+    hull_borderwidth = 5 
+)
+
+
+
+ + +The interior +
+

+ 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: + +

+ +
+
+
+counter2.configure(entryfield_entry_background = 'yellow')
+
+
+
+ +

+ Most component path names (like entryfield_entry) + have a shorter alias defined for them. In this + case, you can use the equivalent: + +

+ +
+
+
+counter2.configure(entry_background = 'yellow')
+
+
+
+ +Changing the python class of a component +
+

+ 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: + +

+ +
+
+
+counter5 = Pmw.Counter(
+        labelpos = 'w',
+        label_text = 'Hello',
+        label_pyclass = Tkinter.Button
+)
+
+
+
+
+ +
+

Forwarding methods

+

+ 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: + +

+ +
+
+
+dialog = Pmw.Dialog(
+        title = 'Counter dialog',
+        buttons = ('OK', 'Cancel'))
+interior = dialog.interior()
+counter = Pmw.Counter(interior)
+counter.pack(padx = 20, pady = 20)
+
+
+
+ +

+ Counter 2 +

+ +

+ 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: + +

+ +
+
+
+class MinuteCounter1(Pmw.Counter):
+
+    def getminutes(self):
+	return Pmw.timestringtoseconds(self.getvalue()) / 60
+
+class MinuteCounter2(Pmw.Counter):
+
+    def __init__(self, parent = None, **kw):
+        kw['datatype'] = 'time'
+        kw['entry_background'] = 'white'
+        kw['entryfield_value'] = '00:00:00'
+        kw['increment'] = 60
+	apply(Pmw.Counter.__init__, (self, parent), kw)
+
+
+
+ +
+

A quick example

+

+ 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. + +

+
+
+
+import Pmw
+root = Pmw.initialise(fontScheme = 'pmw1')
+
+counter = Pmw.Counter(
+        label_text = 'Counter:',
+        labelpos = 'w',
+        entryfield_value = '00:00:00',
+        entryfield_validate = 'time',
+        datatype='time',
+        increment=5*60,
+)
+counter.pack(fill = 'x', padx = 10, pady = 10)
+
+entry = Pmw.EntryField(
+        label_text = 'Real entry:',
+        labelpos = 'w',
+        value = '+2.9979e+8',
+        validate = 'real',
+)
+entry.pack(fill = 'x', padx = 10, pady = 10)
+
+combo = Pmw.ComboBox(
+        label_text = 'ComboBox:',
+        labelpos = 'w',
+        scrolledlist_items = map(str, range(20))
+)
+combo.pack(fill = 'x', padx = 10, pady = 10)
+
+# Make the labels line up neatly
+Pmw.alignlabels((counter, entry, combo))
+
+root.title('Pmw megawidgets example')
+root.mainloop()
+
+
+
+ +

+ Example 1 +

+ +
+

Another example

+

+ 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()
+
+
+
+ +

+ Example 2 +

+ +
+

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: + +

+ +
+
+
+root.option_add('*EntryField.Label.background', 'green')
+
+
+
+ +

+ To set the background of all Pmw.EntryField components, including + the hull component: + +

+ +
+
+
+root.option_add('*EntryField*background', 'blue')
+
+
+
+ +

+ 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: + +

+ +
+
+
+root.option_add('*EntryField.labelpos', 'w')
+
+
+
+ +
+
+ + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/index.html b/Pmw/Pmw_1_2/doc/index.html new file mode 100644 index 00000000..ef531a23 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/index.html @@ -0,0 +1,131 @@ + + + + + + Pmw megawidgets 1.2 + + + + +

Pmw 1.2

+ +

Python megawidgets

+ +

+ +

+ +

+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. + +

+ +

+Local documentation +

+ +
+
+ + + Main features +
+ Getting started - including downloading + and installation +
+ How to use Pmw megawidgets - creating + and configuring megawidgets +
+ How to build Pmw megawidgets - inheriting + (sub-classing) from Pmw megawidgets +
+ Demonstrations and tests - how to run +
+ Dynamic loader - also discusses how + to "freeze" Pmw +
+ Reference manuals - complete documentation + of all Pmw classes and functions +
+ Porting between different versions of Pmw +
+ Change log +
+ Todo list and list of known bugs +
+ Copyright +
+
+ +

+External links +

+ +
+
+ + + 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. + +
+
+ +

+See the +Pmw megawidgets home page +for the latest information about Pmw. + +

+ +

+ +Comments, bugs, fixes to the Pmw +discussion and announcement mailing list. + +

+ + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + + +

+
+ + + + 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:

    +
     someWidget.tk.call('font', 'measure', someFont, 'W')
    + + +
  • +
  • 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).

    + +
  • +
  • Add to classes currently without any options:

    +
     optiondefs = ()
    + self.defineoptions(kw, optiondefs)
    + + +
  • +
  • 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.

    + +
  • +
  • Example megawidget class definition:

    + +
+
class MyBigWidget(Pmw.MegaWidget):
+    def __init__(self, parent = None, **kw):
+
+        # Define the megawidget options.
+        optiondefs = (
+            ('errorbackground',   'pink',      None),
+            ('maxwidth',          0,           self._myfunc),
+            ('myinit',            'good',      Pmw.INITOPT),
+        )
+        self.defineoptions(kw, optiondefs)
+
+        # Initialise the base class (after defining the options).
+        Pmw.MegaWidget.__init__(self, parent)
+
+        # Create the components.
+        interior = self.interior()
+        self._widget = self.createcomponent('component',
+                (('alias', 'component_alias'),), None,
+                Tkinter.Button, (interior,))
+        self._widget.grid(column=0, row=0, sticky='nsew')
+
+        self.createlabel(interior)
+
+        # Initialise instance variables.
+        self.deriveddummy = None
+
+        # Check keywords and initialise options.
+        self.initialiseoptions(MyBigWidget)
+
+ + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/refindex.html b/Pmw/Pmw_1_2/doc/refindex.html new file mode 100644 index 00000000..19a549e0 --- /dev/null +++ b/Pmw/Pmw_1_2/doc/refindex.html @@ -0,0 +1,79 @@ + + + + + + Pmw reference manual index + + + + +

Pmw reference manual
index

+ + +

+ +

+ +
Base classes
+Pmw.MegaArchetype +Pmw.MegaWidget +Pmw.MegaToplevel +
+
Widgets
+Pmw.ButtonBox +Pmw.ComboBox +Pmw.Counter +Pmw.EntryField +Pmw.Group +Pmw.HistoryText +Pmw.LabeledWidget +Pmw.MainMenuBar +Pmw.MenuBar +Pmw.MessageBar +Pmw.NoteBook +Pmw.OptionMenu +Pmw.PanedWidget +Pmw.RadioSelect +Pmw.ScrolledCanvas +Pmw.ScrolledField +Pmw.ScrolledFrame +Pmw.ScrolledListBox +Pmw.ScrolledText +Pmw.TimeCounter +
+
Dialogs
+Pmw.AboutDialog +Pmw.ComboBoxDialog +Pmw.CounterDialog +Pmw.Dialog +Pmw.MessageDialog +Pmw.PromptDialog +Pmw.SelectionDialog +Pmw.TextDialog +
+
Miscellaneous
+Pmw.Balloon +Pmw.Blt +Pmw.Color +Module functions +
+ +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/scale1.gif b/Pmw/Pmw_1_2/doc/scale1.gif new file mode 100644 index 0000000000000000000000000000000000000000..5cf5d60bb335123e116f6dd0b5806a3b350030fd GIT binary patch literal 1016 zcmVy*Z%+j+1c5{!^47tf|&pS|9^h~00000 z00000000000000000000EC2ui07d}x000F3kjP1^y*TU5yZ>M)j$~<`XsWJk>%MR- z&vcCzQkFeG-2$|%$ML`0=css?&RPPJQW*P8`jxZ|(+EFKTk z>k7IHk5A^;x}AW>?&WQ1Wq*B2dUirgii?YX6bOuwjgFL+mY0|&2AiCno}G@LqMiVu z1_h|8s;dB{f19hZs;#E7wzRLOwz0T-u)D0TzPiAvy>`FFsK;^1%FJud#n5Kbz|>&Y zyVzRVx5CK8&)_Tp0Tbrt=;;&QvfL-?66XZ;_4DoG)8r}X^z!Ne(sRd)p9+EV&LJc~ zFc^%50sjrucge-e>tj57|Ip!+K+>2=6Y@01^p{VW%UU)I zz;n`a*-Iilb^i1bbSKb`-*DPAN)+k4p*D&_tszzEIIH`xR@CZ|Ytmdfg?fEDwqRL@ zU~@8!>eOu7rBi8CeS0-mtGjsf-mO71Va!c>0|PLy7Uss3ED65^9G3*bg^V{up7D63 zV#$|j^o5)`!(Q#j9D*WS1ItVY#s_lx~*0!tQ9jDg3S$ zJm2jZj7O1bEQ7INyv3;u7apBw_37QNS3j!ycysOEV_>gssylP>;LpPt|GKpj!TcK$}eV00^3Bh;bxff*r&J;Y1T^X3vF* zWk}g(mU##oMx2SrT1F)z$QOjJIXEIp3%UrLiM-J`ql$E8mE%@BcGcro2f}q$NkiWB zBUwkf6=YpY>ewWYPx=@okm1-!oR!%WNMw=*R*B=3NP?-PmqPj=&|g{_$rnH^rsM0tXF8BjthkRGTEtDQ1_aa@wn>vccG> zs^zqH523!kaGE@ruqqqpoVLPw7>2~QK--yG&=sPBpzFRAmIx@oqlCYvw5t5(~pzpnxutH84oTr0ZYA&j2F`Y}wP!<0hYLbw6z zyXLSK=XtDz1{ce%#E$Km@rWOHyaKlHN?Y>CeU@wT$uX*1FS|3ldvD77;@mIG74w@Z m&jSO^)^mb|LUhrYB(3z)OgHWH(@;k(_0&{XZFLM00029+_62MJ literal 0 HcmV?d00001 diff --git a/Pmw/Pmw_1_2/doc/scale2.gif b/Pmw/Pmw_1_2/doc/scale2.gif new file mode 100644 index 0000000000000000000000000000000000000000..5682715ea75621526b4bc20d4979aa6672218d7d GIT binary patch literal 1943 zcmV;I2Wa?5Nk%v~VU_^&0P_F<|Ns90008>y*8u+j|Nj8l+1bOx!-9f>0GR-P|9_d8 z0RR7g000000000000000EC2ui0G0ss000F3u*gZPy*TU5yZ>M)j$~<`XsWJk>%MR- z&vb3yc&_h!@BhG{a7Zi~b%~^M$xI9v(5Q4utxAW@Y!dObdcRQxHZdrh&t(Kx2qn1R z@VI=g5DSy&{6O8E`~PrtV|r+OYzu&ibap{_gl2|8ZHkm`f_G$(X={>*m6Vr_nVOM6 zlb?y9K#ruGrk<#Psz0ocr9Y>!ezQKcgttDqx^lcdzIwnt!oz`#tE0BAxUkG|#XQG( z$vn%|1lK!TYUAYOU3KW`>g(+2Smp5MZ0+>*=|}ka`uqI-{{H|27C1n#puvL%hagdo}?Txon^=9R})vpb}Yz2EIEY+}x00AaIhAesV z1jIEJm!K?Ra^%jIC15_PnFQwopFgASe3>y^7^hQ9W-Z#a)6yY4gWk=V^JvE(bfZok zx%cPME`ftE&YO7crOJalA5OhG^1QI8Q)WKUcH->2sdK+R7JT*X(|_ZBti5=8?`O?3 z9}mB-eCPD(zJ3v#_UixLLH@U1ZmP*fn`-2#G~jXthBn-3>Y4XogAmr2+=4Ph7?ytD zZRit*F(e4qO#(K>p?x04m!f{rg;-yUFo?JxiMN@^A&f6*NaKk(x}YOZCuU|NX+zT0 zV+%i)6(ou~s@NopAjbG&lsO*o(Un+cspXbMV#m^!V1{WWl|D}S5RL>L$wHE8p*d!k z<$XzInq(qrrko|v38#W*&iUqw7xtOwpHBvgCkc82>g7#ts<{H2ay44#ns+klr=u!B zdY7a%2sdGCCDP!jr-_bGY7E>N7+{Svr0O4?6;Xt#2J^iastmP;M`xJ4UP&mb_}R)T zuEFa1YY3+To9c0u{t~-vZJf4RtaZ)acOJ9R65E`yw*tE@wb^=m-mBH}ryaTBDoY`P z<(eCtgUNyruUy@hm2O(~wt4BKkG8w%zI%?y)4lW#J21eC#%bxGv!bBsULVB@QNt%Z zJQx5HPt0$o{_eFT#U@z1*vA{EAhKH)E()ZqK2pH$tj!*po~6CTS0zkw{V)<%sQudfevC zLax;M{kVJnkt=@rwT*w>_PBF19k<)$TJCIR6~^o?>g<}XwdPer3HH@uyDqbnUdujp z-G#0dwyB~YHa4HTci4Mhv;(iY$7~-@yz`AEF9O`c+kV&bH#eWVq0nQGH0-Z?-aYTz z`z}4Q!Ph{y@#T{pyOHP1n?4Qe3q3yj@0&k6*W9=Ny#LYLU-594Klg=CclWa&0KL~V z$z{)R1^izG13190O^|_;BTniZ=mO(x5Q3-sPwP0CK?98tgs>4$;RuK-6=qI+t#V=I zNT>qL1rCO|lA&+rX963p5P><=Vc%$of@$s0dV2FrXpTt46DVS+&0W!m`GxlJmI zoya8T>fmX{9=_{^^7Q82s2I)+?vt9gG^Phnm`y7R$BWf$U_Za7PEfk@mx^?eF#gL( z%v{Ejhl@<;Uoa}sfI`%l4y~gp`M1Vi^75kv-RML!>d}yv6r~S!=_i@jO_cRYOC+7? z#cql*i*`Vku>9$ zS52x{jq1vSb=9XF0IHzGiq@`bRCry^3 z0JNs&G8RvJ8dSpJGpabC4_^z*xp+eM29kAZUpHsjNai53XKid{9_!i2zGt$crDsJ` zd!W{!mIrTJEo|YnS-BeXub0(VXmct--LjRn7*Ok>>`K|-%67QME$#(`Q!CZv0(ZH` zZ7y_`OVsEdELPO50CNW>vFuV{yY^bFcU>#qUMZx!;}s2h%`1@hy7#^Cjjw#?OW*q1 d_rCbeuYUK--~RgdzW@%ffCo(A0?Ri706UE>;!FSl literal 0 HcmV?d00001 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: + +

+ +
+
+
+cd /usr/lib/python2.2/site-packages
+gunzip /tmp/Pmw.1.2.tar.gz (or gzip -d /tmp/Pmw.1.2.tar.gz)
+tar xvf /tmp/Pmw.1.2.tar
+
+
+
+ +

+ +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: +

+ +
+
+
+cd Pmw/Pmw_1_2
+gunzip Pmw.1.2.docsrc.tar.gz
+tar xvf Pmw.1.2.docsrc.tar
+mv doc doc.old
+cd docsrc
+./createmanuals.py
+
+
+
+ +

+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. + +

+
+
+ + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + 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:

    +
    1. Current behaviour - move to the next multiple of the + increment, eg: 1.0 -> 2.0, 1.234 -> 2.0

      + +
    2. +
    3. Add or subtract the increment to whatever is displayed, + eg: 1.0 -> 2.0, 1.234 -> 2.234

      + +
    4. +
    5. 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

    + +
+ +

Arrowed megawidgets (Counter, ComboBox, TimeCounter)

+
  • 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:

    +
     def listbox_focus(self, event):
    +     self.indexlist.component('listbox').focus_set()
    + +
         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 class hierarchy diagram to documentation:

    +
     MegaArchetype
    +     MegaToplevel
    +        etc
    +     MegaWidget
    +        etc
    + + +
  • +
  • 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:

    +
     import Pmw
    + root = Pmw.initialise(useTkOptionDb = 1)
    + root.option_add('*entryfield24*Label.text', 'German')
    + e = Pmw.EntryField(hull_name = 'entryfield24', labelpos = 'w')
    + e.pack()
    + root.update()
    + + +
  • +
  • Also document hull_name and hull_class.

    + +
  • +
  • Finish FAQ, ReleaseProcedure and StructuredText test.

    + +
  • +
  • Put html through gifwizard and html lint.

    +
     http://www.cen.uiuc.edu/cgi-bin/weblint
    + (eg: http://www.cre.canon.co.uk/~neilb/weblint/manpage.html)
    + + +
  • +
  • Delete comments from source if they have been added to docs + (should not have two copies of anything).

    + +
  • +
  • Need to document non-standard initial values for component + options, such as border in ButtonBox and Dialog's childsite.

    + +
  • +
  • Docs should have DEFAULT BINDINGS section (like iwidget combobox).

    + +
  • +
  • Promote home page:

    +
     http://www.geocities.com/homestead/promote.html
    + http://www.submit-it.com/subopt.htm, etc
    + + +
  • +
  • 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
    +
    + + +
+ + + +

+ +

+ + + +

+ Pmw 1.2 - + 5 Aug 2003 + - Home + +

+
+ + + + diff --git a/Pmw/Pmw_1_2/doc/transdove.gif b/Pmw/Pmw_1_2/doc/transdove.gif new file mode 100644 index 0000000000000000000000000000000000000000..a9d83cdc4a3f0145965f91c92cb5068f60ac878f GIT binary patch literal 438 zcmZ?wbhEHbbYt*l_{abP|G@yrQ2fcl$-uzGp!iQyLBTV(Ait<2HANwixHMbzq$kNQzQZGF-jX?)w1jw+1$VM^!o6^7X^jm((8OFD|1D7s)#-BCM zxNTVpS8CR}8LNW|PIn$KEjL%cA9;>Rt;%G+zx%42Eo+v2=4^e(cSfVbVoj8?drbN1 zzinF{+&Dhtb?4sL$Z0v352{{P*s!;5*Xcj|f?qCg7s*(@$Wg+jw4-9#GKLd37EDtY z*Npt`h*g4rc+DjUgC=&xf3Gs%l{%D|DLp?{AK&pYaO3mV1soojOV>oq8C4^po;pE@sU-R$YoyhBkC&i7f z-%Al$k>z?KyvwZT;))L~dy|V38YWpxnzuiZ*>#yZ|>6wUwc_~ a(z)eTHq-9T=J==@)E=|Dsx*Ls!5RRg55tlG literal 0 HcmV?d00001 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 _