From aranea.network at gmail.com Sat Apr 6 07:12:43 2019 From: aranea.network at gmail.com (Robert Okadar) Date: Sat, 6 Apr 2019 13:12:43 +0200 Subject: [Tkinter-discuss] Performance impact in Windows on grid resize Message-ID: Hi community, I have developed a tkinter GUI component, Python v3.7. It runs very well in Linux but seeing a huge performance impact in Windows 10. While in Linux an almost real-time performance is achieved, in Windows it is slow to an unusable level. The code is somewhat stripped down from the original, but the performance difference is the same anyway. The columns can be resized by clicking on the column border and dragging it. Resizing works only for the top row (but it resizes the entire column). In this demo, all bindings are avoided to exclude influence on the component performance and thus not included. If you resize the window (i.e., if you maximize it), you must call the function table.fit() from IDLE shell. Does anyone know where is this huge difference in performance coming from? Can anything be done about it? All the best, -- Robert Okadar IT Consultant Schedule an *online meeting * with me! Visit *aranea-mreze.hr* or call * +385 91 300 8887* -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- import tkinter class Resizer(tkinter.Frame): def __init__(self, info_grid, master, **cnf): self.table_grid = info_grid tkinter.Frame.__init__(self, master, **cnf) self.bind('', self.resize_column) self.bind('', self.resize_start) self.bind('', self.resize_end) self._resizing = False self.bind('', self.onDestroyEvent) def onDestroyEvent(self, event): self.table_grid = [] def resize_column(self, event, width = None): #if self._resizing: top = self.table_grid.Top grid = self.table_grid._grid col = self.master.grid_info()["column"] if not width: width = self._width + event.x_root - self._x_root top.columnconfigure(col, minsize = width) grid.columnconfigure(col, minsize = width) def resize_start(self, event): top = self.table_grid.Top self._resizing = True self._x_root = event.x_root col = self.master.grid_info()["column"] self._width = top.grid_bbox(row = 0, column = col)[2] #print event.__dict__ col = self.master.grid_info()["column"] #print top.grid_bbox(row = 0, column = col) def resize_end(self, event): pass #self.table_grid.xscrollcommand() #self.table_grid.column_resize_callback(col, self) class Table(tkinter.Frame): def __init__(self, master, columns = 10, rows = 20, width = 100,**kw): tkinter.Frame.__init__(self, master, **kw) self.columns = [] self._width = width self._grid = grid = tkinter.Frame(self, bg = "#CCCCCC") self.Top = top = tkinter.Frame(self, bg = "#DDDDDD") self.create_top(columns) self.create_grid(rows) #self.bind('', self.on_table_configure) #self.bind('', self.on_table_map) top.pack(anchor = 'nw')#, expand = 1, fill = "both") grid.pack(anchor = 'nw')#fill = "both",expand = 1 def on_table_map(self, event): theight = self.winfo_height() def fit(self):#on_table_configure(self, event): i = 0 for frame in self.Top.grid_slaves(row = 0): frame.resizer.resize_column(None, width = frame.winfo_width()) i += 1 theight = self.winfo_height() fheight = self._grid.winfo_height() + self.Top.winfo_height() #print('', theight, fheight) if theight > fheight: rheight = self.grid_array[0][0].winfo_height() ammount = int((-fheight + theight) / rheight) #print(rheight, ammount) for i in range(ammount): self.add_row() self.update() def add_row(self, ammount = 1): columnsw = self.columns row = [] i = len(self.grid_array) for j in range(len(columnsw)): bg = self.bgcolor0 if i % 2 == 1: bg = self.bgcolor1 entry = tkinter.Label(self._grid, bg = bg, text = '%i %i' % (i, j)) entry.grid(row = i, column = j, sticky = "we", padx = 2) row.append(entry) self.grid_array.append(row) bgcolor0 = "#FFFFFF" bgcolor1 = "#EEEEEE" def create_grid(self, height): #grid.grid(row = 0, column = 0, sticky = "nsew") columnsw = self.columns# = self.Top.grid_slaves(row = 1) self.grid_array = [] for i in range(height): row = [] for j in range(len(columnsw)): bg = self.bgcolor0 if i % 2 == 1: bg = self.bgcolor1 #entry = self.EntryClass(False, self, self._grid, bg = bg, width = 1, ) entry = tkinter.Label(self._grid, bg = bg, text = '%i %i' % (i,j)) entry.grid(row = i, column = j, sticky = "we", padx = 2) row.append(entry) self.grid_array.append(row) def create_top(self, columns = 10): top = self.Top #columns = self._columns #maybe to rename for i in range(columns): name = 'column %i' % i self.add_column(name, top) def add_column(self, name, top, width = None): if not width: width = self._width col = tkinter.Frame(top) i = len(self.columns) #filter = Filter(self, name, i, top) entry = tkinter.Entry(col, width = 1) #readonlybackground #col.ColumnIndex = i #col.array_index = i entry.insert(0, name) resizer = Resizer(self, col, bg = "#000000", width = 3, height = 21, cursor = 'sb_h_double_arrow') #entry.grid(row = 0, column = 0, sticky = "we") #resizer.grid(row = 0, column = 1, sticky = "e") entry.pack(side = "left", fill = "both", expand = 1) resizer.pack(side = "right") top.columnconfigure(i, minsize = width, weight = 1) #filter.grid(row = 0, column = i, sticky = "we") col.grid(row = 0, column = i, sticky = "we") col.entry = entry #col.filter = filter #col.index = filter.index = i col.resizer = resizer #filter.Column = col entry.Column = col self.columns.append(col) if __name__ == '__main__': columns = 30 rows = 20 width = 60 root = tkinter.Tk() root.wm_title('TableGridTest') table = self = Table(root, columns = columns, rows = rows, width = width) table.pack(expand = 1, fill = 'both') #table.create_grid( From nulla.epistola at web.de Mon Apr 29 07:16:50 2019 From: nulla.epistola at web.de (Sibylle Koczian) Date: Mon, 29 Apr 2019 13:16:50 +0200 Subject: [Tkinter-discuss] ttk.Treeview: coloring rows using tags doesn't work with Python 3.7.3 Message-ID: Hello, the following script shows a Treeview with names and country codes of some towns in Germany. Towns with country code "HE" or "BY" should be shown with coloured background, in the case of "BY" additionally with white text. This works using Python 3.5 or 3.6. I seem to remember that it worked with earlier versions of Python 3.7, but that's not certain. Using Python 3.7.3 all the entries have white background and black text. Opening an entry with Enter or double click shows the name of the town in the Entry field, together with the country name, if the row has the tag for HE or BY. So the entries have the tags they should, but the color doesn't change. Changing the font of an entry using tags does work. All of these Python versions come with tcl/tk version 8.6, but I don't know the patch numbers, they probably changed. The official documentation for tkinter and for tcl/tk seems to show that the script is correct. I can see no hint of recent changes in the use of tags, tag_configure and the options usable with tags. Here is the script: ############################################################################ #!/usr/bin/env python3 # treeview_forum.py """Treeview-Komponente erforschen""" import tkinter as tk from tkinter import ttk CITIES = [ "1,Frankfurt,HE", "2,Augsburg,BY", "3,Kiel,SH", "4,Flensburg,SH", "5,Stuttgart,BW" ] class TreeFrame(ttk.Frame): column_defs = { "#0": {"label": "IDN", "width": 40, "anchor": tk.E}, "Name": {"label": "Name", "minwidth": 200, "stretch": True}, "Country": {"label": "CC", "width": 80} } default_width = 100 default_minwidth = 10 default_anchor = tk.W def __init__(self, parent, export_city, *args, **kwargs): super().__init__(parent, *args, **kwargs) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.export_namecolumn = export_city self.treeview = ttk.Treeview(self, columns=["Name", "Country"], selectmode='browse') for (name, definition) in self.column_defs.items(): label = definition.get('label', '') anchor = definition.get('anchor', self.default_anchor) minwidth = definition.get('minwidth', self.default_minwidth) width = definition.get('width', self.default_width) stretch = definition.get('stretch', False) self.treeview.heading(name, text=label, anchor=anchor) self.treeview.column(name, anchor=anchor, minwidth=minwidth, width=width, stretch=stretch) self.treeview.tag_configure('hessen', background='lightgreen') self.treeview.tag_configure('bayern', background='darkgray', foreground='white') self.treeview.bind('<>', self.on_open_record) self.scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, command=self.treeview.yview) self.treeview.configure(yscrollcommand=self.scrollbar.set) self.treeview.grid(row=0, column=0, sticky='NSEW') self.scrollbar.grid(row=0, column=1, sticky='NSW') def on_open_record(self, *args): selected_item = self.treeview.selection()[0] selected_name = self.treeview.set(selected_item, 0) in_hessen = (" (Hessen)" if self.treeview.tag_has('hessen', selected_item) else "") in_bayern = (" (Bayern)" if self.treeview.tag_has('bayern', selected_item) else "") msg = "{0}{1}{2}".format(selected_name, in_hessen, in_bayern) self.export_namecolumn(msg) def populate(self, rows): """Clear the treeview & write the supplied data rows to it.""" for row in self.treeview.get_children(): self.treeview.delete(row) for rec in rows: idstr = str(rec['ID']) values = [rec['Name'], rec['CC']] if rec['CC'] == 'HE': cc = 'hessen' elif rec['CC'] == 'BY': cc = 'bayern' else: cc = '' self.treeview.insert('', 'end', iid=idstr, text=idstr, values=values, tags=(cc,)) if rows: self.treeview.focus_set() first = self.treeview.identify_row(0) self.treeview.selection_set(first) self.treeview.focus(first) class RecordFrame(ttk.Frame): def __init__(self, parent): super().__init__(parent) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) ttk.Label(self, text="Ausgew?hlt:").grid(row=0, column=0) self.entryvar = tk.StringVar() ttk.Entry(self, textvariable=self.entryvar).grid(row=1, column=0, sticky='EW') def set(self, value): self.entryvar.set(value) def get(self): return self.entryvar.get() class Application(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.geometry("360x500") self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.recordlist = TreeFrame(self, self.show_city) self.recordlist.grid(row=0, padx=10, pady=10, sticky="NSEW") self.dataframe = RecordFrame(self) self.dataframe.grid(row=1, padx=10, pady=10, sticky="NSEW") self.recordlist.populate(self.get_all_cities(CITIES)) def get_all_cities(self, citynames): fieldnames = ("ID", "Name", "CC") allcities = [dict(zip(fieldnames, row.split(','))) for row in citynames] return allcities def show_city(self, city): self.dataframe.set(city) root = Application() root.mainloop() From klappnase at web.de Mon Apr 29 16:51:13 2019 From: klappnase at web.de (Michael Lange) Date: Mon, 29 Apr 2019 22:51:13 +0200 Subject: [Tkinter-discuss] ttk.Treeview: coloring rows using tags doesn't work with Python 3.7.3 In-Reply-To: References: Message-ID: <20190429225113.fee007a812e6ae504a3daba2@web.de> Hi, On Mon, 29 Apr 2019 13:16:50 +0200 Sibylle Koczian wrote: > Hello, > > the following script shows a Treeview with names and country codes of > some towns in Germany. Towns with country code "HE" or "BY" should be > shown with coloured background, in the case of "BY" additionally with > white text. > > This works using Python 3.5 or 3.6. I seem to remember that it worked > with earlier versions of Python 3.7, but that's not certain. Using > Python 3.7.3 all the entries have white background and black text. > Opening an entry with Enter or double click shows the name of the town > in the Entry field, together with the country name, if the row has the > tag for HE or BY. So the entries have the tags they should, but the > color doesn't change. > > Changing the font of an entry using tags does work. > > All of these Python versions come with tcl/tk version 8.6, but I don't > know the patch numbers, they probably changed. The official > documentation for tkinter and for tcl/tk seems to show that the script > is correct. I can see no hint of recent changes in the use of tags, > tag_configure and the options usable with tags. just a shot into the dark: maybe the problem is not at all how the treeview handles tags, but how Tk handles named colors? Did you try to use hex color specs like '#d9d9d9' instead of 'darkgray' or 'lightgreen'? According to https://www.tcl-lang.org/man/tcl8.6/TkCmd/colors.htm there should be "dark gray" and "LightGreen", but maybe your version of Tk somehow fails to treat the color names case-insensitive resp. "space-insensitive". Best regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Space: the final frontier. These are the voyages of the starship Enterprise. Its five-year mission: to explore strange new worlds; to seek out new life and new civilizations; to boldly go where no man has gone before. -- Captain James T. Kirk From emilianogavilan at gmail.com Tue Apr 30 09:38:27 2019 From: emilianogavilan at gmail.com (Emiliano) Date: Tue, 30 Apr 2019 10:38:27 -0300 Subject: [Tkinter-discuss] ttk.Treeview: coloring rows using tags doesn't work with Python 3.7.3 In-Reply-To: References: Message-ID: <49FDEC6B-264E-40D4-863C-2F149C89CEF5@gmail.com> El 29 de abril de 2019 8:16:50 AM GMT-03:00, Sibylle Koczian escribi?: >Hello, > >the following script shows a Treeview with names and country codes of >some towns in Germany. Towns with country code "HE" or "BY" should be >shown with coloured background, in the case of "BY" additionally with >white text. > >This works using Python 3.5 or 3.6. I seem to remember that it worked >with earlier versions of Python 3.7, but that's not certain. Using >Python 3.7.3 all the entries have white background and black text. >Opening an entry with Enter or double click shows the name of the town >in the Entry field, together with the country name, if the row has the >tag for HE or BY. So the entries have the tags they should, but the >color doesn't change. > >Changing the font of an entry using tags does work. > >All of these Python versions come with tcl/tk version 8.6, but I don't >know the patch numbers, they probably changed. The official >documentation for tkinter and for tcl/tk seems to show that the script >is correct. I can see no hint of recent changes in the use of tags, >tag_configure and the options usable with tags. > >Here is the script: > >############################################################################ > >#!/usr/bin/env python3 ># treeview_forum.py > >"""Treeview-Komponente erforschen""" > >import tkinter as tk >from tkinter import ttk > >CITIES = [ > "1,Frankfurt,HE", > "2,Augsburg,BY", > "3,Kiel,SH", > "4,Flensburg,SH", > "5,Stuttgart,BW" > ] > > >class TreeFrame(ttk.Frame): > > column_defs = { > "#0": {"label": "IDN", "width": 40, "anchor": tk.E}, > "Name": {"label": "Name", "minwidth": 200, "stretch": True}, > "Country": {"label": "CC", "width": 80} > } > default_width = 100 > default_minwidth = 10 > default_anchor = tk.W > > def __init__(self, parent, export_city, *args, **kwargs): > super().__init__(parent, *args, **kwargs) > self.columnconfigure(0, weight=1) > self.rowconfigure(0, weight=1) > self.export_namecolumn = export_city > self.treeview = ttk.Treeview(self, > columns=["Name", "Country"], > selectmode='browse') > for (name, definition) in self.column_defs.items(): > label = definition.get('label', '') > anchor = definition.get('anchor', self.default_anchor) > minwidth = definition.get('minwidth', self.default_minwidth) > width = definition.get('width', self.default_width) > stretch = definition.get('stretch', False) > self.treeview.heading(name, text=label, anchor=anchor) > self.treeview.column(name, anchor=anchor, minwidth=minwidth, > width=width, stretch=stretch) > self.treeview.tag_configure('hessen', background='lightgreen') > self.treeview.tag_configure('bayern', background='darkgray', > foreground='white') > self.treeview.bind('<>', self.on_open_record) > self.scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL, > command=self.treeview.yview) > self.treeview.configure(yscrollcommand=self.scrollbar.set) > self.treeview.grid(row=0, column=0, sticky='NSEW') > self.scrollbar.grid(row=0, column=1, sticky='NSW') > > def on_open_record(self, *args): > selected_item = self.treeview.selection()[0] > selected_name = self.treeview.set(selected_item, 0) > in_hessen = (" (Hessen)" > if self.treeview.tag_has('hessen', selected_item) >else "") > in_bayern = (" (Bayern)" > if self.treeview.tag_has('bayern', selected_item) >else "") > msg = "{0}{1}{2}".format(selected_name, in_hessen, in_bayern) > self.export_namecolumn(msg) > > def populate(self, rows): > """Clear the treeview & write the supplied data rows to it.""" > for row in self.treeview.get_children(): > self.treeview.delete(row) > for rec in rows: > idstr = str(rec['ID']) > values = [rec['Name'], rec['CC']] > if rec['CC'] == 'HE': > cc = 'hessen' > elif rec['CC'] == 'BY': > cc = 'bayern' > else: > cc = '' > self.treeview.insert('', 'end', iid=idstr, text=idstr, > values=values, tags=(cc,)) > if rows: > self.treeview.focus_set() > first = self.treeview.identify_row(0) > self.treeview.selection_set(first) > self.treeview.focus(first) > > >class RecordFrame(ttk.Frame): > > def __init__(self, parent): > super().__init__(parent) > self.columnconfigure(0, weight=1) > self.rowconfigure(1, weight=1) > ttk.Label(self, text="Ausgew?hlt:").grid(row=0, column=0) > self.entryvar = tk.StringVar() > ttk.Entry(self, textvariable=self.entryvar).grid(row=1, column=0, > sticky='EW') > > def set(self, value): > self.entryvar.set(value) > > def get(self): > return self.entryvar.get() > >class Application(tk.Tk): > > def __init__(self, *args, **kwargs): > super().__init__(*args, **kwargs) > self.geometry("360x500") > self.columnconfigure(0, weight=1) > self.rowconfigure(0, weight=1) > self.recordlist = TreeFrame(self, self.show_city) > self.recordlist.grid(row=0, padx=10, pady=10, sticky="NSEW") > self.dataframe = RecordFrame(self) > self.dataframe.grid(row=1, padx=10, pady=10, sticky="NSEW") > self.recordlist.populate(self.get_all_cities(CITIES)) > > def get_all_cities(self, citynames): > fieldnames = ("ID", "Name", "CC") > allcities = [dict(zip(fieldnames, row.split(','))) for row in >citynames] > return allcities > > def show_city(self, city): > self.dataframe.set(city) > > >root = Application() >root.mainloop() > Maybe you hit this bug? http://core.tcl.tk/tk/tktview?name=509cafafae -- Emiliano From nulla.epistola at web.de Tue Apr 30 09:43:54 2019 From: nulla.epistola at web.de (Sibylle Koczian) Date: Tue, 30 Apr 2019 15:43:54 +0200 Subject: [Tkinter-discuss] ttk.Treeview: coloring rows using tags doesn't work with Python 3.7.3 In-Reply-To: <20190429225113.fee007a812e6ae504a3daba2@web.de> References: <20190429225113.fee007a812e6ae504a3daba2@web.de> Message-ID: Am 29.04.2019 um 22:51 schrieb Michael Lange: > Hi, > > On Mon, 29 Apr 2019 13:16:50 +0200 > Sibylle Koczian wrote: > >> Hello, >> >> the following script shows a Treeview with names and country codes of >> some towns in Germany. Towns with country code "HE" or "BY" should be >> shown with coloured background, in the case of "BY" additionally with >> white text. >> >> This works using Python 3.5 or 3.6. I seem to remember that it worked >> with earlier versions of Python 3.7, but that's not certain. Using >> Python 3.7.3 all the entries have white background and black text. >> Opening an entry with Enter or double click shows the name of the town >> in the Entry field, together with the country name, if the row has the >> tag for HE or BY. So the entries have the tags they should, but the >> color doesn't change. >> >> Changing the font of an entry using tags does work. >> >> All of these Python versions come with tcl/tk version 8.6, but I don't >> know the patch numbers, they probably changed. The official >> documentation for tkinter and for tcl/tk seems to show that the script >> is correct. I can see no hint of recent changes in the use of tags, >> tag_configure and the options usable with tags. > > just a shot into the dark: > > maybe the problem is not at all how the treeview handles tags, but how Tk > handles named colors? Did you try to use hex color specs like '#d9d9d9' > instead of 'darkgray' or 'lightgreen'? According to > https://www.tcl-lang.org/man/tcl8.6/TkCmd/colors.htm > there should be "dark gray" and "LightGreen", but maybe your version of > Tk somehow fails to treat the color names case-insensitive resp. > "space-insensitive". > That would be very nice. But no, I just forgot to mention it: I tried with hex color specs and I tried with the most simple color names: just "green" (and "white" for the foreground color of bavarian towns). Nothing. BTW I used Python 3.7.3 with Windows 10 and with ArchLinux, LXQt as desktop, everything freshly updated. Thank you, Sibylle From nulla.epistola at web.de Tue Apr 30 13:28:57 2019 From: nulla.epistola at web.de (Sibylle Koczian) Date: Tue, 30 Apr 2019 19:28:57 +0200 Subject: [Tkinter-discuss] ttk.Treeview: coloring rows using tags doesn't work with Python 3.7.3 In-Reply-To: <49FDEC6B-264E-40D4-863C-2F149C89CEF5@gmail.com> References: <49FDEC6B-264E-40D4-863C-2F149C89CEF5@gmail.com> Message-ID: <3532db9f-af87-3066-e3bc-0a241f222414@web.de> Am 30.04.2019 um 15:38 schrieb Emiliano: > > > El 29 de abril de 2019 8:16:50 AM GMT-03:00, Sibylle Koczian escribi?: >> Hello, >> >> the following script shows a Treeview with names and country codes of >> some towns in Germany. Towns with country code "HE" or "BY" should be >> shown with coloured background, in the case of "BY" additionally with >> white text. >> >> This works using Python 3.5 or 3.6. I seem to remember that it worked >> with earlier versions of Python 3.7, but that's not certain. Using >> Python 3.7.3 all the entries have white background and black text. >> Opening an entry with Enter or double click shows the name of the town >> in the Entry field, together with the country name, if the row has the >> tag for HE or BY. So the entries have the tags they should, but the >> color doesn't change. >> >> Changing the font of an entry using tags does work. >> >> All of these Python versions come with tcl/tk version 8.6, but I don't >> know the patch numbers, they probably changed. The official >> documentation for tkinter and for tcl/tk seems to show that the script >> is correct. I can see no hint of recent changes in the use of tags, >> tag_configure and the options usable with tags. >> > > Maybe you hit this bug? > > http://core.tcl.tk/tk/tktview?name=509cafafae > Yes, that seems exactly right. I put the tkinter workaround by ulfalizer into my script and now the entries are coloured as they should. The discussion is helpful too. Many thanks! Sibylle