preview_win.py


directory : D:\2018_py_proj\TkGridGUI\tkgridgui
Line Count : 245
Line Clip Size : No Clipping

tab_of_notebook_changed  Word MatchCase (0) 
1 #!/usr/bin/env python 2 # -*- coding: ascii -*- 3 from __future__ import print_function 4 from __future__ import unicode_literals 5 6 from future import standard_library 7 standard_library.install_aliases() 8 """ 9 Provide a Toplevel window to display widgets as they will look 10 in the target application. 11 12 Apply any new attributes that come from an EditWin. 13 """ 14 15 import sys 16 17 from tkinter import * 18 import tkinter.messagebox 19 from tkinter import Button, Canvas, Checkbutton, Entry, Frame, Label, LabelFrame 20 from tkinter import Listbox, Message, Radiobutton, Spinbox, Text 21 from tkinter import OptionMenu # ttk OptionMenu seems to be broken 22 from tkinter.ttk import Combobox, Progressbar, Separator, Treeview, Style, Notebook 23 24 class PreviewWin( Toplevel ): 25 26 27 def __init__(self, MainWin, grid_gui=None): 28 29 Toplevel.__init__(self, MainWin)#, bg='#ADD8E6') #'lightblue': '#ADD8E6', 30 self.title('Preview Window') 31 32 self.MainWin = MainWin 33 self.grid_gui = grid_gui 34 35 self.widget_ijD = {} # index=(i,j) grid position: value=widget 36 37 # only main window can close this window 38 self.protocol('WM_DELETE_WINDOW', self.cleanupOnQuit) 39 40 screen_width = MainWin.winfo_screenwidth() 41 screen_height = MainWin.winfo_screenheight() 42 43 if MainWin.state() == "zoomed": 44 MainWin.state("normal") 45 46 x_main = MainWin.winfo_x() 47 y_main = MainWin.winfo_y() 48 #print('MainWin (x,y) = (%s,%s)'%(x_main, y_main), ' MainWin.state()=',MainWin.state()) 49 50 # try to place PreviewWin right next to grid_notebook 51 # ... position to the upper right 52 x = x_main + MainWin.winfo_width() + 10 53 y = y_main + 25 # if row added to GridGUI, can still see close "x" of MainWin 54 55 # when launched from CLI, winfo_x and winfo_y are == 0 56 # check for bad placement and try to make the best of it 57 if (x > screen_width - 310) or (x < 340): 58 x=screen_width - 310 59 60 if (y > screen_height - 210): 61 y = screen_height - 210 62 63 #print('setting PreviewWin geometry to:',(300,200,x,y)) 64 self.geometry( '%ix%i+%i+%i'%(300,200,x,y)) 65 #self.geometry( '+%i+%i'%(10,10)) # <-- sets x,y only. w,h fill for widgets 66 67 self.prevFrame = Frame(self) 68 self.prevFrame.pack(fill=BOTH, expand=True) 69 70 self.menuBar = False 71 self.statusbar = False 72 self.OK_Cancel_Frame = False 73 74 #def position_next_to_main(self): 75 # x = self.MainWin.winfo_x() + self.MainWin.winfo_width() + 10 76 # y = self.MainWin.winfo_y() + 25 # if row added to GridGUI, can still see close "x" of MainWin 77 # if x<340: x=340 78 # if y<10: y=10 79 # # position over to the upper right 80 # self.geometry( '+%i+%i'%(x,y)) 81 82 self.bind("<Enter>", self.onPreviewWindowEnter) 83 84 def onPreviewWindowEnter(self, event): 85 """Only track Enter... Want last known location.""" 86 if self.grid_gui.mouse_location != 'preview_window': 87 print('mouse_location = preview_window') 88 self.grid_gui.mouse_location = 'preview_window' 89 90 def destroy_all_children(self): 91 """ 92 Delete all widgets directly attached to prevFrame. 93 Some could be compound widgets like Frame or Notebook objects. 94 """ 95 # should be the same as self.prevFrame.winfo_children() 96 97 for ij, child in list(self.widget_ijD.items()): 98 child.destroy() 99 100 for child in self.prevFrame.winfo_children(): 101 child.destroy() 102 103 104 self.widget_ijD = {} # index=(i,j) grid position: value=widget 105 106 #def setActive(self): 107 # self.lift() 108 # self.focus_force() 109 # self.grab_set() 110 # self.grab_release() 111 112 def remove_mock_statusbar(self): 113 if self.statusbar: 114 self.statusbar.destroy() 115 self.statusbar = False 116 #print('Status Bar Deleted from PreviewWin') 117 118 def add_mock_statusbar(self): 119 if self.OK_Cancel_Frame: 120 need_to_replace_OK_Cancel = True 121 self.remove_mock_OK_Cancel_Buttons() 122 else: 123 need_to_replace_OK_Cancel = False 124 125 126 if not self.statusbar: 127 self.statusbar = Label(self, text='Status Bar', bd=1, relief=SUNKEN) 128 self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM) 129 #print('Status Bar Added to PreviewWin') 130 131 if need_to_replace_OK_Cancel: 132 self.add_mock_OK_Cancel_Buttons() 133 134 135 def remove_mock_OK_Cancel_Buttons(self): 136 if self.OK_Cancel_Frame: 137 self.OK_Cancel_Frame.destroy() 138 self.OK_Cancel_Frame = False 139 #print("OK Cancel Buttons Deleted from PreviewWin") 140 141 142 def add_mock_OK_Cancel_Buttons(self): 143 if not self.OK_Cancel_Frame: 144 145 self.OK_Cancel_Frame = Frame(self) 146 frame = self.OK_Cancel_Frame 147 148 self.Button_1 = Button( frame , width="12", text="OK") 149 self.Button_2 = Button( frame , width="12", text="Cancel") 150 self.Label_1 = Label( frame , width="2", text="") 151 self.Label_2 = Label( frame , width="2", text="") 152 153 self.Label_1.grid( row=2, column=1, sticky='ew') 154 self.Button_1.grid(row=2, column=2, pady="5", padx="5") 155 self.Button_2.grid(row=2, column=4, pady="5", padx="5") 156 self.Label_2.grid( row=2, column=5, sticky='ew') 157 158 frame.columnconfigure(1, weight=1) 159 frame.columnconfigure(5, weight=1) 160 161 frame.pack(anchor=SW, fill=X, side=BOTTOM) 162 163 def delete_menu(self): 164 #print('Deleting Menu') 165 if self.menuBar: 166 #if hasattr(self, 'menuBar'): 167 self.menuBar.delete(0,1000) 168 #self.config(menu=None) 169 #print('... Deleted Menu') 170 self.menuBar = False 171 172 def add_menu(self, menuSrcL): 173 """add a menu to PreviewWin using user-input menuStr""" 174 if not self.menuBar: 175 176 for line in menuSrcL: 177 #print('====>',line.strip(), end='\n') 178 if line.find(', command')>=0: 179 line = line.split(', command')[0] + ')' 180 #print('========>',line.strip(), end='\n') 181 exec( line.strip() ) # should create self.menuBar 182 183 def add_widget(self, i,j, pw_widget): 184 185 self.widget_ijD[(i,j)] = pw_widget 186 187 if pw_widget.cobj.widget_type == 'Tab': 188 #print('Skipping the .grid for Tab ',pw_widget.cobj.widget_name) 189 pass 190 else: 191 #print('Doing the .grid for ',pw_widget.cobj.widget_name) 192 pw_widget.grid(row=i, column=j) 193 194 self.maybe_resize_preview_win() 195 196 def maybe_resize_preview_win(self): 197 198 self.update_idletasks() 199 200 wprev = self.prevFrame.winfo_reqwidth() 201 hprev = self.prevFrame.winfo_reqheight() 202 #print("PreviewWin Req: w=%s, h=%s"%(wprev, hprev)) 203 204 if wprev>300 or hprev>200: 205 self.geometry("") 206 return 207 208 #xmax_widget = pw_widget.winfo_x() + pw_widget.winfo_width() + 20 209 #ymax_widget = pw_widget.winfo_y() + pw_widget.winfo_height() + 60 210 211 #if self.statusbar: 212 # ymax_widget += 20 213 214 215 #if len(self.widget_ijD) >= 3: 216 # self.geometry("") 217 218 #elif xmax_widget > wprev: 219 # #print('Expanding Preview Window Width to:',xmax_widget) 220 # #self.MainWin.statusMessage.set( 'Expanding Preview Window Width to: %s'%xmax_widget ) 221 # #self.config( width=xmax_widget ) 222 # self.geometry("") 223 # #self.update() 224 225 #elif ymax_widget > hprev: 226 # #print('Expanding Preview Window Height to:',ymax_widget) 227 # #self.MainWin.statusMessage.set( 'Expanding Preview Window Height to: %s'%ymax_widget ) 228 # self.geometry("") 229 # #self.config( height=ymax_widget ) 230 # #self.update() 231 232 233 def cleanupOnQuit(self): 234 if self.MainWin.allow_subWindows_to_close: 235 # I'm not sure that transient windows need this, but I'm trying to be careful 236 self.parent.focus_set() 237 self.destroy() 238 239 print( 'To Exit Applicaton, Use Main Window.' ) 240 self.MainWin.statusMessage.set('To Exit Applicaton, Use Main Window.') 241 242 tkinter.messagebox.showinfo( 243 "Use Main Window to Exit", 244 "\n\n"+\ 245 "Please Use Main Window to Exit\n") 246