Dear Folks,
My python Combobox doesn't populate the windows drives. Please Help!!!
import tkinter as tk
from tkinter import ttk
from tkinter import font
import os.path
win = tk.Tk()
win.title("AR Duplicate File Search")
win.geometry("600x600")
win.configure(bg = 'green')
#----------------------------------Combo Box-----------------------------
dl = ['ABCDEFGHIJKLMNOPQRSTUVWXYZ']
drives = ['%s:' % d for d in dl if os.path.exists('%s:' % d)]
def convert(list):
return tuple(list)
listdrive = convert(drives)
search_loc_var = tk.StringVar()
search_loc_cmbbx1 = ttk.Combobox(win, width = 22, textvariable =
search_loc_var, state = 'readonly', values = drives)
# Defining the state readonly will restrict the user from typing anything
# in the combobox.
search_loc_cmbbx1['values'] = listdrive
search_loc_cmbbx1.grid(row = 2, column = 1)
win.mainloop()
I tried to populate the combobox from the tuple and list. But the combobox remains blank.
I suppose you want to populate your ttk.Combobox vertically with your existing drives on the local PC, such as :
C:
D:
E:
To provide this, just need to convert dl to an ordinary string as
dl = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Related
import filecmp
import os
import tkinter as tk
import tkinter.font as tkFont
from tkinter import *
def gg():
disk = (number_entry.get())
if disk == "2" :
DIRS = [r'C:\Newtest\1', r'C:\Newtest\2', r'C:\Newtest\3',r'C:\Newtest\4',r'C:\Newtest\5',r'C:\Newtest\6',r'C:\Newtest\7',r'C:\Newtest\8',r'C:\Newtest\9',r'C:\Newtest\10']
FILES = [('copy1.txt', 'copy2.txt'), ('fcmp1.txt', 'fcmp2.txt'), ('filecp1.txt', 'filecp2.txt')]
for e, dir in enumerate(DIRS, 1):
cmp = True
for file in FILES:
try:
if not filecmp.cmp(os.path.join(dir, file[0]), os.path.join(dir, file[1])):
cmp = False
break
except Exception as ex:
print(f'Error -> {ex}', file=sys.stderr)
continue
x = (f'E_{e} compare {"pass" if cmp else "fail"}')
print(x)
result_label.configure(text=x,wraplength=300,font=fontExample3)
DIRS = [r'C:\Newtest\1', r'C:\Newtest\2', r'C:\Newtest\3',r'C:\Newtest\4',r'C:\Newtest\5',r'C:\Newtest\6',r'C:\Newtest\7',r'C:\Newtest\8',r'C:\Newtest\9',r'C:\Newtest\10']
FILES = [('copy1.txt', 'copy2.txt'), ('fcmp1.txt', 'fcmp2.txt'), ('filecp1.txt', 'filecp2.txt')]
for e, dir in enumerate(DIRS, 1):
cmp = True
window = tk.Tk()
window.title('XXX')
window.geometry('1200x700')
window.configure(background='Azure')
fontExample = tkFont.Font(family="Segoe UI", size=20)
fontExample2 = tkFont.Font(family="Segoe UI", size=10)
fontExample3 = tkFont.Font(family="Segoe UI", size=15)
header_label = tk.Label(window, text='XXXX',font=fontExample)
header_label.pack()
number_frame = tk.Frame(window)
number_frame.pack(side=tk.TOP)
number_label = tk.Label(number_frame, text='Number of disks',font=fontExample2)
number_label.pack(side=tk.LEFT)
number_entry = tk.Entry(number_frame)
number_entry.pack(side=tk.LEFT)
result_label = tk.Label(window)
result_label.pack()
calculate_btn = tk.Button(window, text='First calculate', command=gg,font=fontExample3)
calculate_btn.pack()
window.mainloop()
Dear All ,
I have the question in the line:
result_label.configure(text=x,wraplength=300,font=fontExample3)
I want the result can print complete like my console.
Consele result is :
E_1 compare pass
E_2 compare fail
E_3 compare pass
E_4 compare pass
E_5 compare pass
E_6 compare pass
E_7 compare pass
E_8 compare pass
E_9 compare pass
E_10 compare fail
But in the tkinter result is -> E_10 compare fail
Please tolerate me as a newbie in tkinter.
Thanks!
If you want to add to the text that is already on the label, you can do this:
result_label.configure(text=result_label['text'] + x + '\n')
result_label['text'] returns the current text of the widget (equivalent to result_label.cget('text'))
You also don't need to configure wraplength and font each time, just do it once when creating the label like this:
result_label = tk.Label(window, wraplenght=300, font=fontExample3)
Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Have two blank lines around function and class declarations.
How to justify the values listed in drop-down part of a ttk.Combobox? I have tried justify='center' but that seems to only configure the selected item. Could use a resource link too if there is, I couldn't find it.
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
import tkinter.ttk as ttk
except ImportError:
import Tkinter as tk
import ttk
if __name__ == '__main__':
root = tk.Tk()
cbb = ttk.Combobox(root, justify='center', values=(0, 1, 2))
cbb.pack()
root.mainloop()
I have a one-liner solution. Use the .option_add() method after declaring ttk.Combobox. Example:
cbb = ttk.Combobox(root, justify='center', values=(0, 1, 2)) # original
cbb.option_add('*TCombobox*Listbox.Justify', 'center') # new line added
Here's one pure Python way that gets close to what you want. The items in the dropdown list all get justified to fit within the Combobox's width (or a default value will be used).
Update
Part of the reason the initial version of my answer wasn't quite right was because the code assumed that a fixed-width font was being used. That's not the case on my test platform at least, so I've modified the code to actually measure the width of values in pixels instead of whole characters, and do essentially what it did originally, but in those units of string-length measure.
import tkinter as tk
import tkinter.font as tkFont
from tkinter import ttk
class CenteredCombobox(ttk.Combobox):
DEFAULT_WIDTH = 20 # Have read that 20 is the default width of an Entry.
def __init__(self, master=None, **kwargs):
values = kwargs.get('values')
if values:
entry = ttk.Entry(None) # Throwaway for getting the default font.
font = tkFont.Font(font=entry['font'])
space_width = font.measure(' ')
entry_width = space_width * kwargs.get('width', self.DEFAULT_WIDTH)
widths = [font.measure(str(value)) for value in values]
longest = max(entry_width, *widths)
justified_values = []
for value, value_width in zip(values, widths):
space_needed = (longest-value_width) / 2
spaces_needed = int(space_needed / space_width)
padding = ' ' * spaces_needed
justified_values.append(padding + str(value))
kwargs['values'] = tuple(justified_values)
super().__init__(master, **kwargs)
root = tk.Tk()
ccb = CenteredCombobox(root, justify='center', width=10, values=('I', 'XLII', 'MMXVIII'))
ccb.pack()
root.mainloop()
(Edit: Note that this solution works for Tcl/Tk versions 8.6.5 and above. #CommonSense notes that some tkinter installations may not be patched yet,
and this solution will not work).
In Tcl ( I don't know python, so one of the python people can edit the question).
A combobox is an amalgamation of an 'entry' widget and a 'listbox' widget. Sometimes to make the configuration changes you want, you need to access the internal widgets directly.
Tcl:
% ttk::combobox .cb -values [list a abc def14 kjsdf]
.cb
% pack .cb
% set pd [ttk::combobox::PopdownWindow .cb]
.cb.popdown
% set lb $pd.f.l
.cb.popdown.f.l
% $lb configure -justify center
Python:
cb = ttk.Combobox(value=['a', 'abc', 'def14', 'kjsdf'])
cb.pack()
pd = cb.tk.call('ttk::combobox::PopdownWindow', cb)
lb = cb.tk.eval('return {}.f.l'.format(pd))
cb.tk.eval('{} configure -justify center'.format(lb))
Some caveats. The internals of ttk::combobox are subject to change.
Not likely, not anytime soon, but in the future, the hard-coded .f.l
could change.
ttk::combobox::PopdownWindow will force the creation of the listbox when it is called. A better method is to put the centering adjustment into
a procedure and call that procedure when the combobox/listbox is mapped.
This will run for all comboboxes, you will need to check the argument
in the proc to make sure that this is the combobox you want to adjust.
proc cblbhandler { w } {
if { $w eq ".cb" } {
set pd [ttk::combobox::PopdownWindow $w]
set lb $pd.f.l
$lb configure -justify center
}
}
bind ComboboxListbox <Map> +[list ::cblbhandler %W]
After digging through combobox.tcl source code I've come up with the following subclass of ttk.Combobox. JustifiedCombobox justifies the pop-down list's items almost precisely after1 pop-down list's been first created & customized and then displayed. After the pop-down list's been created, setting self.justify value to a valid one will again, customize the justification almost right after the pop-down list's first been displayed. Enjoy:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
from tkinter import ttk
except:
import Tkinter as tk
import ttk
class JustifiedCombobox(ttk.Combobox):
"""
Creates a ttk.Combobox widget with its drop-down list items
justified with self.justify as late as possible.
"""
def __init__(self, master, *args, **kwargs):
ttk.Combobox.__init__(self, master, *args, **kwargs)
self.justify = 'center'
def _justify_popdown_list_text(self):
self._initial_bindtags = self.bindtags()
_bindtags = list(self._initial_bindtags)
_index_of_class_tag = _bindtags.index(self.winfo_class())
# This dummy tag needs to be unique per object, and also needs
# to be not equal to str(object)
self._dummy_tag = '_' + str(self)
_bindtags.insert(_index_of_class_tag + 1, self._dummy_tag)
self.bindtags(tuple(_bindtags))
_events_that_produce_popdown = tuple([ '<KeyPress-Down>',
'<ButtonPress-1>',
'<Shift-ButtonPress-1>',
'<Double-ButtonPress-1>',
'<Triple-ButtonPress-1>',
])
for _event_name in _events_that_produce_popdown:
self.bind_class(self._dummy_tag, _event_name,
self._initial_event_handle)
def _initial_event_handle(self, event):
_instate = str(self['state'])
if _instate != 'disabled':
if event.keysym == 'Down':
self._justify()
else:
_ = self.tk.eval('{} identify element {} {}'.format(self,
event.x, event.y))
__ = self.tk.eval('string match *textarea {}'.format(_))
_is_click_in_entry = bool(int(__))
if (_instate == 'readonly') or (not _is_click_in_entry):
self._justify()
def _justify(self):
self.tk.eval('{}.popdown.f.l configure -justify {}'.format(self,
self.justify))
self.bindtags(self._initial_bindtags)
def __setattr__(self, name, value):
self.__dict__[name] = value
if name == 'justify':
self._justify_popdown_list_text()
def select_handle():
global a
_selected = a['values'][a.current()]
if _selected in ("left", "center", "right"):
a.justify = _selected
if __name__ == '__main__':
root = tk.Tk()
for s in ('normal', 'readonly', 'disabled'):
JustifiedCombobox(root, state=s, values=[1, 2, 3]).grid()
a = JustifiedCombobox(root, values=["Justify me!", "left", "center", "right"])
a.current(0)
a.grid()
a.bind("<<ComboboxSelected>>", lambda event: select_handle())
root.mainloop()
1 It basically makes use of bindtag event queue. This was mostly possible thanks to being able to creating a custom bindtag.
I'm writing a simple script that create a ttk treeview (that act as a table) and, when you double-click it, it opens a file (with the path saved in the dictionary). Double click opening is possible by this method:
t.bind("<Double-1>", lambda f=nt[x]["URIallegato"]: os.startfile(str(f)))
However, this doesn't gave me the ID of the row (stored in the #0 column). With the ID I can get the path of the file saved in a dictionary.
Here is the full Treeview code:
t=Treeview(w)
t.pack(padx=10,pady=10)
for x in list(nt.keys()):
t.insert("",x,text=nt[x]["allegati"])
if nt[x]["allegati"]!="":
t.bind("<Double-1>",
lambda f=nt[x]["URIallegato"]: os.startfile(str(f)))
Thanks!
The normal way to do this is to bind a single binding on the treeview for a double click. The default binding for single-click will select the item, and in your double-click binding you can ask the treeview for the selected item.
If you associate values with the treeview item, you can fetch them so that you don't have to store them in a dictionary.
Here's an example:
import tkinter as tk
from tkinter import ttk
def on_double_click(event):
item_id = event.widget.focus()
item = event.widget.item(item_id)
values = item['values']
url = values[0]
print("the url is:", url)
root = tk.Tk()
t=ttk.Treeview(root)
t.pack(fill="both", expand=True)
t.bind("<Double-Button-1>", on_double_click)
for x in range(10):
url = "http://example.com/%d" % x
text = "item %d" % x
t.insert("", x, text=text, values=[url])
root.mainloop()
I have an application in which the (tkinter) LabelFrame widget on the tab of a ttk Notebook will not update itself. In a much simplified version of that program (code extracts below) the widget will not even appear on the GUI.
Everything else on the GUI works properly, including updating the tab titles, the application title (and icon) and updating the Label, Checkbutton and Radiobutton widgets on all notebook tabs. Using the ttk versions (e.g. ttk.LabelFrame) to create those widgets did not fix the issue. I also tried using “update_idletasks” (some think this as a kludge) immediately after updating the widget attributes without success.
In the real application the text of all GUI widgets change according to the state of a “choose language” widget on the same GUI (for details, see: Need Python/tkinter GUI to dynamically update itself (for a multi-lingual GUI)). It’s known that all GUI text values (the WidgetName["text”] attribute), including the missing LabelFrame, are being correctly updated to match the state of that widget.
Is there something “special” about LabelFrame widgets on Notebook tabs? What (probably simple) thing am I overlooking?
Also, any confirmation/denial by others will help determine if the problem is unique to my system - a distinct possiblity since my machine is administered by corporate IM (who don't have the best record when handling the needs of unusual users like me).
Thanks
The following is a complete example of the problem. When run, the LabelFrame widget (which should appear at (0, 0) of Tab 1) does not appear. Clicking on the "language" widget causes everything else to display text in the language selected by the "language" widget.
From “LanguageInUse.py” the code that switches languages:
import sys
c_cedille_lower = "\u00E7" # UTF 8/16 (code page 863?) French character
e_circumflex_lower = "\u00EA"
English = 'English' # string shown on GUI
Francais = 'Fran' + c_cedille_lower + 'ais' # string shown on GUI
DefaultLanguage = Francais
DefaultLanguage = English # comment out this line to use French
user_language = DefaultLanguage # set up language shown on GUI
# Define all language-dependent GUI strings (as "Application-Level" globals)
ComplianceMessage = None
ReportTab1Title = None
ReportTab2Title = None
XCheckbuttonMessage = None
XLabelFrameMessage = None
XLabelMessage = None
XRadioButtonMessage = None
'''=========================================================================='''
def SetGuiLanguage( user_language ) :
global ComplianceMessage, LanguagePrompt
global ReportTab1Title, ReportTab2Title
global XLabelFrameMessage, XCheckbuttonMessage, XLabelMessage, XRadioButtonMessage
if ( user_language == English ):
LanguagePrompt = "Language"
ReportTab1Title = "Message Counts"
ReportTab2Title = "Communications Compliance"
XLabelFrameMessage = "LabelFrame"
XCheckbuttonMessage = "Checkbox"
XLabelMessage = "Label"
XRadioButtonMessage = 'Radiobutton'
ComplianceMessage = "Compliance (engish)"
elif ( user_language == Francais ):
LanguagePrompt = "Langage"
ReportTab1Title = "Comtes de message"
ReportTab2Title = "Compliance Communications"
XLabelFrameMessage = "LabelFrame en " + Francais
XCheckbuttonMessage = "Checkbox en " + Francais
XLabelMessage = "Label en " + Francais
XRadioButtonMessage = "Radiobutton en " + Francais
ComplianceMessage = "Compliance - " + Francais
else:
print (' An unknown user language was specified' )
sys.exit()
return
'''=========================================================================='''
SetGuiLanguage( user_language ) # initialize all tkinter strings at startup
'''========================== End of File ================================'''
From “SelectReports.py”) the code that builds the notebook:
from tkinter import Checkbutton, Radiobutton, Label, LabelFrame, Frame
from tkinter import ttk
import LanguageInUse
# Locally defined entities importable by other modules (often
# Tkinter Application level objects whose language can be changed)
ComplianceMessageText = None
NotebookFrame = None
XCheckbutton = None
XLabel = None
XLabelFrame = None # NOT APPEARING ON THE GUI
XRadiobutton = None
'''=========================================================================='''
def TabbedReports( ParentFrame ) :
global ComplianceMessageText, NotebookFrame
global SelectReportFrame, UplinkFileWarningText
global XCheckbutton, XLabel, XLabelFrame, XRadiobutton
# Builds the notebook and it's widgits
NotebookFrame = ttk.Notebook( ParentFrame )
NotebookFrame.grid( row = 0, column = 1 )
Tab1Frame = Frame( NotebookFrame )
Tab2Frame = Frame( NotebookFrame )
NotebookFrame.add( Tab1Frame )
NotebookFrame.add( Tab2Frame )
# Create widgets on Tab 1
XLabelFrame = LabelFrame( Tab1Frame ) # NOT APPEARING ON GUI
XCheckbutton = Checkbutton( Tab1Frame )
XLabel = Label( Tab1Frame )
XRadiobutton = Radiobutton( Tab1Frame )
XLabelFrame.grid( row = 1, column = 0 ) # NOT ON GUI
XCheckbutton.grid( row = 1, column = 1 )
XLabel.grid( row = 2, column = 0 )
XRadiobutton.grid( row = 2, column = 1 )
XLabelFrame.configure( text = LanguageInUse.XLabelFrameMessage ) # NOT ON GUI
XCheckbutton.configure( text = LanguageInUse.XCheckbuttonMessage )
XLabel.configure( text = LanguageInUse.XLabelMessage )
XRadiobutton.configure( text = LanguageInUse.XRadioButtonMessage )
# .tab() gives same effect as .configure() for other widget types
NotebookFrame.tab( 0 , text = LanguageInUse.ReportTab1Title )
NotebookFrame.tab( 1 , text = LanguageInUse.ReportTab2Title )
# Create the only widget on Tab 2 (uses other method to specify text)
ComplianceMessageText = Label( Tab2Frame )
ComplianceMessageText.grid( row = 0, column = 0 )
ComplianceMessageText['text'] = LanguageInUse.ComplianceMessage
return
From “ChangeLanguageOnGui.py” the code that updates all notebook widgets:
import sys, os
from tkinter import StringVar, Radiobutton, PhotoImage
#from TkinterRoot import root
import LanguageInUse
import SelectReports
'''=========================================================================='''
def ChangeLanguageOnGui() :
SelectReports.XLabelFrame.configure( text = LanguageInUse.XLabelFrameMessage ) # NOT ON GUI
SelectReports.XCheckbutton.configure( text = LanguageInUse.XCheckbuttonMessage )
SelectReports.XLabel.configure( text = LanguageInUse.XLabelMessage )
SelectReports.XRadiobutton.configure( text = LanguageInUse.XRadioButtonMessage )
# .tab() gives the same effect as .configure() for other widget types
SelectReports.NotebookFrame.tab( 0 , text = LanguageInUse.ReportTab1Title )
SelectReports.NotebookFrame.tab( 1 , text = LanguageInUse.ReportTab2Title )
SelectReports.ComplianceMessageText['text'] = LanguageInUse.ComplianceMessage
'''=========================================================================='''
def SetUpGuiLanguage( LanguageFrame ) :
GUI_Language = StringVar( value = LanguageInUse.user_language )
#---------------------------------------------------------------------------
def switchLanguage():
LanguageInUse.user_language = GUI_Language.get()
LanguageInUse.SetGuiLanguage( LanguageInUse.user_language )
ChangeLanguageOnGui()
return
#---------------------------------------------------------------------------
UsingEnglish = Radiobutton( LanguageFrame, indicatoron = False,
variable = GUI_Language,
command = lambda: switchLanguage(),
value = LanguageInUse.English )
UsingFrancais = Radiobutton( LanguageFrame, indicatoron = False,
variable = GUI_Language,
command = lambda: switchLanguage(),
value = LanguageInUse.Francais )
UsingEnglish.grid( row = 0, column = 0 )
UsingFrancais.grid( row = 1, column = 0 )
UsingEnglish.configure( text = LanguageInUse.English )
UsingFrancais.configure( text = LanguageInUse.Francais )
From "TkinterRoot.py" the code that makes root importable everywhere (explictly importing this avoided problems such as IntVar() being unavailable during the intitialization phase of other modules):
from tkinter import Tk # possibly the worlds shortest useful python module
root = Tk() # makes root an importable "Application Level" global
And finally "A.py", the mainline file:
from TkinterRoot import root
from tkinter import LabelFrame
from tkinter import ttk
import ChangeLanguageOnGui, LanguageInUse, SelectReports, sys
LanguageFrame = None
if __name__ == "__main__":
LanguageChoice = LanguageInUse.English
if ( LanguageChoice == LanguageInUse.English ) :
LanguageInUse.user_language = LanguageChoice
elif ( LanguageChoice == 'Francais' ) :
LanguageInUse.user_language = LanguageInUse.Francais
else :
print( "Unknown Language: " + LanguageChoice )
sys.exit()
mainframe = ttk.Frame( root )
mainframe.grid( row = 0, column = 0 )
LanguageFrame = LabelFrame( mainframe, text = LanguageInUse.LanguagePrompt )
LanguageFrame.grid( row = 0, column = 0 )
ChangeLanguageOnGui.SetUpGuiLanguage( LanguageFrame )
SelectReports.TabbedReports( mainframe )
try:
root.mainloop()
except:
print( 'Exception Occurred' )
sys.exit()
The Environment is 64-bit Python 3.5.1, 64-bit Win 7 Enterprise SP 1, 64-bit Eclipse Mars 2 (the Java EE IDE edition) running 64-bit PyDev 5.1.2.201606231256. The "one user" (no admin rights) version of Pydev was used, this required Microsoft patch KB2999226 (part of Win10) to run on Win7. Eventual target distribution is a 32-bit Windows app (so it can run on 32 & 64 bit Windows) - and if/when time permits - Linux.
There’s one minor complication to keep in mind: In the real program several packages are being used. Inside each package each function is isolated inside its own file. All objects (e.g. the tkinter widgets) that must be externally visible (or need be shared amongst the package’s files) are declared in the package’s _ _ init.py _ _ file. Functions that must be externally visible are explicitly imported into _ _ init.py _ _ by using relative imports (e.g. “from .Function1 import Function1” ).
Your title is misleading because you place the LabelFrame in a Frame, not directly on a Notebook tab. Your problem is that the labelframe does not appear in its parent frame. The Notebook is irrelevant and all associated code should have been deleted before posting.
Even the frame is irrelevant in that the same problem arises when putting the labelframe directly in root. Here is minimal code that demonstrate both the problem and a solution.
from tkinter import Tk
from tkinter import ttk
root = Tk()
lf1 = ttk.LabelFrame(root, text='labelframe 1')
lf2 = ttk.LabelFrame(root, text='labelframe 2', width=200, height=100)
lf1.pack()
lf2.pack()
I ran this on Win 10 with 3.6a2, which comes with tk 8.6.4. Only lf2 is visible because the default size of a labelframe, as with a frame, is 0 x 0. A non-default size arises either from explicit sizing or from contents. Somewhat surprisingly, the label does not count as content and does not force a non-default size. I reproduced the same result with the labelframe in a frame (your situation) and on a tab.
I am trying to use a entry to append the dbf part of a shapefile. So far I can only make a change to the dbf file by directly assigning the variable a value. I can only get the entry box to print a variable. What am I missing? I am using python 3.3.
import shapefile
from tkinter import filedialog
import tkinter as tk
class application:
def __init__(self,window):
""" Initalize the Application """
self.myentrybox = tk.Entry(window)
self.myentrybox.pack()
self.myentrybox.insert(0,"some default value")
self.myentrybox.bind("<Return>",self.Enter)
def Enter(self,event):
""" Someone Pressed Enter """
print (self.myentrybox.get())
aep = 'self.myentrybox.get()'
root=tk.Tk()
myapp = application(root)
r = shapefile.Reader('Mississippi')
w = shapefile.Writer()
w.fields = list(r.fields)
w.field (aep, 'C', '40')
i=1
for rec in r.records():
rec.append(i)
i+=1
w.records.append(rec)
w._shapes.extend(r.shapes())
w.save('AMissl6KM')
root.mainloop()