tkinter-web-backend 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. tkinter_web/__init__.py +89 -0
  2. tkinter_web/__main__.py +69 -0
  3. tkinter_web/_tkinter.py +321 -0
  4. tkinter_web/_vendor/LICENSE-Python.txt +277 -0
  5. tkinter_web/_vendor/README.md +9 -0
  6. tkinter_web/_vendor/tkinter/__init__.py +4988 -0
  7. tkinter_web/_vendor/tkinter/__main__.py +7 -0
  8. tkinter_web/_vendor/tkinter/colorchooser.py +86 -0
  9. tkinter_web/_vendor/tkinter/commondialog.py +53 -0
  10. tkinter_web/_vendor/tkinter/constants.py +110 -0
  11. tkinter_web/_vendor/tkinter/dialog.py +49 -0
  12. tkinter_web/_vendor/tkinter/dnd.py +324 -0
  13. tkinter_web/_vendor/tkinter/filedialog.py +492 -0
  14. tkinter_web/_vendor/tkinter/font.py +239 -0
  15. tkinter_web/_vendor/tkinter/messagebox.py +146 -0
  16. tkinter_web/_vendor/tkinter/scrolledtext.py +56 -0
  17. tkinter_web/_vendor/tkinter/simpledialog.py +441 -0
  18. tkinter_web/_vendor/tkinter/ttk.py +1647 -0
  19. tkinter_web/app.py +358 -0
  20. tkinter_web/client/fonts/LICENSE-DejaVu.txt +47 -0
  21. tkinter_web/client/fonts/mono-bold-italic.woff2 +0 -0
  22. tkinter_web/client/fonts/mono-bold.woff2 +0 -0
  23. tkinter_web/client/fonts/mono-italic.woff2 +0 -0
  24. tkinter_web/client/fonts/mono.woff2 +0 -0
  25. tkinter_web/client/fonts/sans-bold-italic.woff2 +0 -0
  26. tkinter_web/client/fonts/sans-bold.woff2 +0 -0
  27. tkinter_web/client/fonts/sans-italic.woff2 +0 -0
  28. tkinter_web/client/fonts/sans.woff2 +0 -0
  29. tkinter_web/client/fonts/serif-bold-italic.woff2 +0 -0
  30. tkinter_web/client/fonts/serif-bold.woff2 +0 -0
  31. tkinter_web/client/fonts/serif-italic.woff2 +0 -0
  32. tkinter_web/client/fonts/serif.woff2 +0 -0
  33. tkinter_web/client/index.html +17 -0
  34. tkinter_web/client/js/bitmaps.js +82 -0
  35. tkinter_web/client/js/main.js +1427 -0
  36. tkinter_web/client/js/paint.js +694 -0
  37. tkinter_web/client/tkweb.css +342 -0
  38. tkinter_web/embed.py +204 -0
  39. tkinter_web/page.py +49 -0
  40. tkinter_web/tk/LICENSE-Tk.txt +40 -0
  41. tkinter_web/tk/__init__.py +11 -0
  42. tkinter_web/tk/_keysyms.py +547 -0
  43. tkinter_web/tk/_specs.py +1137 -0
  44. tkinter_web/tk/colors.json +1 -0
  45. tkinter_web/tk/dialogs.py +554 -0
  46. tkinter_web/tk/events.py +458 -0
  47. tkinter_web/tk/fontmetrics.json +1 -0
  48. tkinter_web/tk/fonts.py +467 -0
  49. tkinter_web/tk/geometry.py +1170 -0
  50. tkinter_web/tk/images.py +875 -0
  51. tkinter_web/tk/input.py +361 -0
  52. tkinter_web/tk/interp.py +1287 -0
  53. tkinter_web/tk/layout.py +192 -0
  54. tkinter_web/tk/options.py +368 -0
  55. tkinter_web/tk/render.py +258 -0
  56. tkinter_web/tk/tcl.py +262 -0
  57. tkinter_web/tk/ttk/__init__.py +16 -0
  58. tkinter_web/tk/ttk/style.py +357 -0
  59. tkinter_web/tk/ttk/treeview.py +817 -0
  60. tkinter_web/tk/ttk/widgets.py +1818 -0
  61. tkinter_web/tk/variables.py +152 -0
  62. tkinter_web/tk/widgets/__init__.py +89 -0
  63. tkinter_web/tk/widgets/base.py +255 -0
  64. tkinter_web/tk/widgets/buttons.py +452 -0
  65. tkinter_web/tk/widgets/canvas.py +1643 -0
  66. tkinter_web/tk/widgets/entry.py +752 -0
  67. tkinter_web/tk/widgets/frame.py +189 -0
  68. tkinter_web/tk/widgets/listbox.py +450 -0
  69. tkinter_web/tk/widgets/menu.py +723 -0
  70. tkinter_web/tk/widgets/message.py +85 -0
  71. tkinter_web/tk/widgets/panedwindow.py +249 -0
  72. tkinter_web/tk/widgets/scale.py +423 -0
  73. tkinter_web/tk/widgets/scrollbar.py +224 -0
  74. tkinter_web/tk/widgets/text.py +1546 -0
  75. tkinter_web/tk/winfo.py +147 -0
  76. tkinter_web/tk/wm.py +236 -0
  77. tkinter_web/transport/__init__.py +1 -0
  78. tkinter_web/transport/base.py +34 -0
  79. tkinter_web/transport/port.py +88 -0
  80. tkinter_web/transport/websocket.py +142 -0
  81. tkinter_web_backend-0.1.0.dist-info/METADATA +247 -0
  82. tkinter_web_backend-0.1.0.dist-info/RECORD +84 -0
  83. tkinter_web_backend-0.1.0.dist-info/WHEEL +4 -0
  84. tkinter_web_backend-0.1.0.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,441 @@
1
+ #
2
+ # An Introduction to Tkinter
3
+ #
4
+ # Copyright (c) 1997 by Fredrik Lundh
5
+ #
6
+ # This copyright applies to Dialog, askinteger, askfloat and asktring
7
+ #
8
+ # fredrik@pythonware.com
9
+ # http://www.pythonware.com
10
+ #
11
+ """This modules handles dialog boxes.
12
+
13
+ It contains the following public symbols:
14
+
15
+ SimpleDialog -- A simple but flexible modal dialog box
16
+
17
+ Dialog -- a base class for dialogs
18
+
19
+ askinteger -- get an integer from the user
20
+
21
+ askfloat -- get a float from the user
22
+
23
+ askstring -- get a string from the user
24
+ """
25
+
26
+ from tkinter import *
27
+ from tkinter import _get_temp_root, _destroy_temp_root
28
+ from tkinter import messagebox
29
+
30
+
31
+ class SimpleDialog:
32
+
33
+ def __init__(self, master,
34
+ text='', buttons=[], default=None, cancel=None,
35
+ title=None, class_=None):
36
+ if class_:
37
+ self.root = Toplevel(master, class_=class_)
38
+ else:
39
+ self.root = Toplevel(master)
40
+ if title:
41
+ self.root.title(title)
42
+ self.root.iconname(title)
43
+
44
+ _setup_dialog(self.root)
45
+
46
+ self.message = Message(self.root, text=text, aspect=400)
47
+ self.message.pack(expand=1, fill=BOTH)
48
+ self.frame = Frame(self.root)
49
+ self.frame.pack()
50
+ self.num = default
51
+ self.cancel = cancel
52
+ self.default = default
53
+ self.root.bind('<Return>', self.return_event)
54
+ for num in range(len(buttons)):
55
+ s = buttons[num]
56
+ b = Button(self.frame, text=s,
57
+ command=(lambda self=self, num=num: self.done(num)))
58
+ if num == default:
59
+ b.config(relief=RIDGE, borderwidth=8)
60
+ b.pack(side=LEFT, fill=BOTH, expand=1)
61
+ self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
62
+ self.root.transient(master)
63
+ _place_window(self.root, master)
64
+
65
+ def go(self):
66
+ self.root.wait_visibility()
67
+ self.root.grab_set()
68
+ self.root.mainloop()
69
+ self.root.destroy()
70
+ return self.num
71
+
72
+ def return_event(self, event):
73
+ if self.default is None:
74
+ self.root.bell()
75
+ else:
76
+ self.done(self.default)
77
+
78
+ def wm_delete_window(self):
79
+ if self.cancel is None:
80
+ self.root.bell()
81
+ else:
82
+ self.done(self.cancel)
83
+
84
+ def done(self, num):
85
+ self.num = num
86
+ self.root.quit()
87
+
88
+
89
+ class Dialog(Toplevel):
90
+
91
+ '''Class to open dialogs.
92
+
93
+ This class is intended as a base class for custom dialogs
94
+ '''
95
+
96
+ def __init__(self, parent, title = None):
97
+ '''Initialize a dialog.
98
+
99
+ Arguments:
100
+
101
+ parent -- a parent window (the application window)
102
+
103
+ title -- the dialog title
104
+ '''
105
+ master = parent
106
+ if master is None:
107
+ master = _get_temp_root()
108
+
109
+ Toplevel.__init__(self, master)
110
+
111
+ self.withdraw() # remain invisible for now
112
+ # If the parent is not viewable, don't
113
+ # make the child transient, or else it
114
+ # would be opened withdrawn
115
+ if parent is not None and parent.winfo_viewable():
116
+ self.transient(parent)
117
+
118
+ if title:
119
+ self.title(title)
120
+
121
+ _setup_dialog(self)
122
+
123
+ self.parent = parent
124
+
125
+ self.result = None
126
+
127
+ body = Frame(self)
128
+ self.initial_focus = self.body(body)
129
+ body.pack(padx=5, pady=5)
130
+
131
+ self.buttonbox()
132
+
133
+ if self.initial_focus is None:
134
+ self.initial_focus = self
135
+
136
+ self.protocol("WM_DELETE_WINDOW", self.cancel)
137
+
138
+ _place_window(self, parent)
139
+
140
+ self.initial_focus.focus_set()
141
+
142
+ # wait for window to appear on screen before calling grab_set
143
+ self.wait_visibility()
144
+ self.grab_set()
145
+ self.wait_window(self)
146
+
147
+ def destroy(self):
148
+ '''Destroy the window'''
149
+ self.initial_focus = None
150
+ Toplevel.destroy(self)
151
+ _destroy_temp_root(self.master)
152
+
153
+ #
154
+ # construction hooks
155
+
156
+ def body(self, master):
157
+ '''create dialog body.
158
+
159
+ return widget that should have initial focus.
160
+ This method should be overridden, and is called
161
+ by the __init__ method.
162
+ '''
163
+ pass
164
+
165
+ def buttonbox(self):
166
+ '''add standard button box.
167
+
168
+ override if you do not want the standard buttons
169
+ '''
170
+
171
+ box = Frame(self)
172
+
173
+ w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
174
+ w.pack(side=LEFT, padx=5, pady=5)
175
+ w = Button(box, text="Cancel", width=10, command=self.cancel)
176
+ w.pack(side=LEFT, padx=5, pady=5)
177
+
178
+ self.bind("<Return>", self.ok)
179
+ self.bind("<Escape>", self.cancel)
180
+
181
+ box.pack()
182
+
183
+ #
184
+ # standard button semantics
185
+
186
+ def ok(self, event=None):
187
+
188
+ if not self.validate():
189
+ self.initial_focus.focus_set() # put focus back
190
+ return
191
+
192
+ self.withdraw()
193
+ self.update_idletasks()
194
+
195
+ try:
196
+ self.apply()
197
+ finally:
198
+ self.cancel()
199
+
200
+ def cancel(self, event=None):
201
+
202
+ # put focus back to the parent window
203
+ if self.parent is not None:
204
+ self.parent.focus_set()
205
+ self.destroy()
206
+
207
+ #
208
+ # command hooks
209
+
210
+ def validate(self):
211
+ '''validate the data
212
+
213
+ This method is called automatically to validate the data before the
214
+ dialog is destroyed. By default, it always validates OK.
215
+ '''
216
+
217
+ return 1 # override
218
+
219
+ def apply(self):
220
+ '''process the data
221
+
222
+ This method is called automatically to process the data, *after*
223
+ the dialog is destroyed. By default, it does nothing.
224
+ '''
225
+
226
+ pass # override
227
+
228
+
229
+ # Place a toplevel window at the center of parent or screen
230
+ # It is a Python implementation of ::tk::PlaceWindow.
231
+ def _place_window(w, parent=None):
232
+ w.wm_withdraw() # Remain invisible while we figure out the geometry
233
+ w.update_idletasks() # Actualize geometry information
234
+
235
+ minwidth = w.winfo_reqwidth()
236
+ minheight = w.winfo_reqheight()
237
+ maxwidth = w.winfo_vrootwidth()
238
+ maxheight = w.winfo_vrootheight()
239
+ if parent is not None and parent.winfo_ismapped():
240
+ x = parent.winfo_rootx() + (parent.winfo_width() - minwidth) // 2
241
+ y = parent.winfo_rooty() + (parent.winfo_height() - minheight) // 2
242
+ vrootx = w.winfo_vrootx()
243
+ vrooty = w.winfo_vrooty()
244
+ x = min(x, vrootx + maxwidth - minwidth)
245
+ x = max(x, vrootx)
246
+ y = min(y, vrooty + maxheight - minheight)
247
+ y = max(y, vrooty)
248
+ if w._windowingsystem == 'aqua':
249
+ # Avoid the native menu bar which sits on top of everything.
250
+ y = max(y, 22)
251
+ else:
252
+ x = (w.winfo_screenwidth() - minwidth) // 2
253
+ y = (w.winfo_screenheight() - minheight) // 2
254
+
255
+ w.wm_maxsize(maxwidth, maxheight)
256
+ w.wm_geometry('+%d+%d' % (x, y))
257
+ w.wm_deiconify() # Become visible at the desired location
258
+
259
+
260
+ def _setup_dialog(w):
261
+ if w._windowingsystem == "aqua":
262
+ w.tk.call("::tk::unsupported::MacWindowStyle", "style",
263
+ w, "moveableModal", "")
264
+ elif w._windowingsystem == "x11":
265
+ w.wm_attributes(type="dialog")
266
+
267
+ # --------------------------------------------------------------------
268
+ # convenience dialogues
269
+
270
+ class _QueryDialog(Dialog):
271
+
272
+ def __init__(self, title, prompt,
273
+ initialvalue=None,
274
+ minvalue = None, maxvalue = None,
275
+ parent = None):
276
+
277
+ self.prompt = prompt
278
+ self.minvalue = minvalue
279
+ self.maxvalue = maxvalue
280
+
281
+ self.initialvalue = initialvalue
282
+
283
+ Dialog.__init__(self, parent, title)
284
+
285
+ def destroy(self):
286
+ self.entry = None
287
+ Dialog.destroy(self)
288
+
289
+ def body(self, master):
290
+
291
+ w = Label(master, text=self.prompt, justify=LEFT)
292
+ w.grid(row=0, padx=5, sticky=W)
293
+
294
+ self.entry = Entry(master, name="entry")
295
+ self.entry.grid(row=1, padx=5, sticky=W+E)
296
+
297
+ if self.initialvalue is not None:
298
+ self.entry.insert(0, self.initialvalue)
299
+ self.entry.select_range(0, END)
300
+
301
+ return self.entry
302
+
303
+ def validate(self):
304
+ try:
305
+ result = self.getresult()
306
+ except ValueError:
307
+ messagebox.showwarning(
308
+ "Illegal value",
309
+ self.errormessage + "\nPlease try again",
310
+ parent = self
311
+ )
312
+ return 0
313
+
314
+ if self.minvalue is not None and result < self.minvalue:
315
+ messagebox.showwarning(
316
+ "Too small",
317
+ "The allowed minimum value is %s. "
318
+ "Please try again." % self.minvalue,
319
+ parent = self
320
+ )
321
+ return 0
322
+
323
+ if self.maxvalue is not None and result > self.maxvalue:
324
+ messagebox.showwarning(
325
+ "Too large",
326
+ "The allowed maximum value is %s. "
327
+ "Please try again." % self.maxvalue,
328
+ parent = self
329
+ )
330
+ return 0
331
+
332
+ self.result = result
333
+
334
+ return 1
335
+
336
+
337
+ class _QueryInteger(_QueryDialog):
338
+ errormessage = "Not an integer."
339
+
340
+ def getresult(self):
341
+ return self.getint(self.entry.get())
342
+
343
+
344
+ def askinteger(title, prompt, **kw):
345
+ '''get an integer from the user
346
+
347
+ Arguments:
348
+
349
+ title -- the dialog title
350
+ prompt -- the label text
351
+ **kw -- see SimpleDialog class
352
+
353
+ Return value is an integer
354
+ '''
355
+ d = _QueryInteger(title, prompt, **kw)
356
+ return d.result
357
+
358
+
359
+ class _QueryFloat(_QueryDialog):
360
+ errormessage = "Not a floating-point value."
361
+
362
+ def getresult(self):
363
+ return self.getdouble(self.entry.get())
364
+
365
+
366
+ def askfloat(title, prompt, **kw):
367
+ '''get a float from the user
368
+
369
+ Arguments:
370
+
371
+ title -- the dialog title
372
+ prompt -- the label text
373
+ **kw -- see SimpleDialog class
374
+
375
+ Return value is a float
376
+ '''
377
+ d = _QueryFloat(title, prompt, **kw)
378
+ return d.result
379
+
380
+
381
+ class _QueryString(_QueryDialog):
382
+ def __init__(self, *args, **kw):
383
+ if "show" in kw:
384
+ self.__show = kw["show"]
385
+ del kw["show"]
386
+ else:
387
+ self.__show = None
388
+ _QueryDialog.__init__(self, *args, **kw)
389
+
390
+ def body(self, master):
391
+ entry = _QueryDialog.body(self, master)
392
+ if self.__show is not None:
393
+ entry.configure(show=self.__show)
394
+ return entry
395
+
396
+ def getresult(self):
397
+ return self.entry.get()
398
+
399
+
400
+ def askstring(title, prompt, **kw):
401
+ '''get a string from the user
402
+
403
+ Arguments:
404
+
405
+ title -- the dialog title
406
+ prompt -- the label text
407
+ **kw -- see SimpleDialog class
408
+
409
+ Return value is a string
410
+ '''
411
+ d = _QueryString(title, prompt, **kw)
412
+ return d.result
413
+
414
+
415
+ if __name__ == '__main__':
416
+
417
+ def test():
418
+ root = Tk()
419
+ def doit(root=root):
420
+ d = SimpleDialog(root,
421
+ text="This is a test dialog. "
422
+ "Would this have been an actual dialog, "
423
+ "the buttons below would have been glowing "
424
+ "in soft pink light.\n"
425
+ "Do you believe this?",
426
+ buttons=["Yes", "No", "Cancel"],
427
+ default=0,
428
+ cancel=2,
429
+ title="Test Dialog")
430
+ print(d.go())
431
+ print(askinteger("Spam", "Egg count", initialvalue=12*12))
432
+ print(askfloat("Spam", "Egg weight\n(in tons)", minvalue=1,
433
+ maxvalue=100))
434
+ print(askstring("Spam", "Egg label"))
435
+ t = Button(root, text='Test', command=doit)
436
+ t.pack()
437
+ q = Button(root, text='Quit', command=t.quit)
438
+ q.pack()
439
+ t.mainloop()
440
+
441
+ test()