Tkinter and astral characters (was: Decoding bytes to text strings in Python 2)
On 2024-06-24 01:14:22 +0100, MRAB via Python-list wrote: > Tkinter in recent versions of Python can handle astral characters, at least > back to Python 3.8, the oldest I have on my Windows PC. I just tried modifying https://docs.python.org/3/library/tkinter.html#a-hello-world-program to display "Hello World \N{ROCKET}" instead (Python 3.10.12 as included with Ubuntu 22.04). I don't get a warning or error, but the emoji isn't displayed either. I suspect that the default font doesn't include emojis and Tk isn't smart enough to fall back to a different font (unlike xfce4-terminal which shows the emoji just fine). hp -- _ | Peter J. Holzer| Story must make more sense than reality. |_|_) || | | | h...@hjp.at |-- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" signature.asc Description: PGP signature -- https://mail.python.org/mailman/listinfo/python-list
Re: Amy known issues with tkinter /ttk on latest MacOS?
On 17/11/2023 03:38, Terry Reedy wrote: > There have been other reports on the cpython issue tracker than Sonoma > broke bits of tk behavior. > https://github.com/python/cpython/issues?q=is%3Aissue+label%3AOS-mac+is%3Aclosed > > shows a couple Thanks Terry, I had a browse and it seems I'm not alone. That's a relief. I'll upgrade to 3.13 when it comes out and hopefully it will go away. (Another suggestion was to use the homebrew python but I don't like having any more homebrew stuff than is absolutely necessary!) Meantime I'll just have to continue nudging the mouse as I click! Alan G. -- https://mail.python.org/mailman/listinfo/python-list
Amy known issues with tkinter /ttk on latest MacOS?
I have a little app that I wrote ages ago (2015) using tkinter/ttk and it just works. Or it did, up until the latest MacOS version upgrade and now it has become very sporadic in response to mouse clicks. For example I have a drop-down list and I can drop the list but then it won't let me select an item. Or sometimes, the selected item is highlighted but the corresponding action doesn't get fired. It is intermittent which makes debugging it difficult. And it's not just lists it also affects regular buttons as well. Right clicks seem to work ok, it's only the left mouse button. Also, I've just noticed that if I move the mouse slightly while clicking that seems to work. There are no error/warning messages in the Console. I'm just wondered if this is a known issue, or just my setup? Any suggestions welcomed. Python version - 3.10.4 OS version - Sonoma 14.1 M1 Mac Mini, 16GB Ram I could upgrade my Python version but I was planning on waiting for the 3.13 release to finalize first. And I doubt if that's the cause anyway. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On Wed, 2023-09-13 at 01:33 +0100, MRAB via Python-list wrote: > On 2023-09-13 00:40, John O'Hagan via Python-list wrote: > > On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: > > > Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > > > [...] > > > > > > > FWIW, here's a version without after(), solving this purely on > > > the > > > python side, not by temporarily unbinding the event, but by > > > selectively doing nothing in the callback function. > > > > > > from tkinter import * > > > from tkinter.ttk import * > > > > > > class Test: > > > def __init__(self): > > > self.inhibit = False > > > root=Tk() > > > self.tree = Treeview(root) > > > self.tree.pack() > > > self.iid = self.tree.insert('', 0, text='test') > > > Button(root, command=self.temp_inhibit).pack() > > > mainloop() > > > > > > def callback(self, *e): > > > if not self.inhibit: > > > print('called') > > > > > > def temp_inhibit(self): > > > self.inhibit = True > > > self.tree.selection_set(self.iid) > > > self.tree.selection_remove(self.iid) > > > self.tree.selection_set(self.iid) > > > self.inhibit = False > > > self.callback() > > > > > > c=Test() > > > > > > > > > I like this solution better - it's much more obvious to me what > > it's > > doing. > > > That code is not binding at all, it's just calling 'temp_inhibit' > when > the button is clicked. > > You can remove all uses of self.inhibit and rename 'temp_inhibit' to > something more meaningful, like 'delete_item'. You're right of course, not as obvious as I thought! -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On 2023-09-13 00:40, John O'Hagan via Python-list wrote: On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > My issue is solved, but I'm still curious about what is happening > here. MRAB already said it: When you enter the callback function, Tk's mainloop waits for it to return. So what's happening is: 1. Tk's mainloop pauses 2. temp_unbind() is called 3. TreeviewSelect is unbound 4. events are queued 5. TreeviewSelect is bound again 6. temp_unbind() returns 7. Tk's mainloop continues with the state: - TreeviewSelect is bound - events are queued [. . .] Thanks (also to others who have explained), now I get it! FWIW, here's a version without after(), solving this purely on the python side, not by temporarily unbinding the event, but by selectively doing nothing in the callback function. from tkinter import * from tkinter.ttk import * class Test: def __init__(self): self.inhibit = False root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_inhibit).pack() mainloop() def callback(self, *e): if not self.inhibit: print('called') def temp_inhibit(self): self.inhibit = True self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.inhibit = False self.callback() c=Test() I like this solution better - it's much more obvious to me what it's doing. That code is not binding at all, it's just calling 'temp_inhibit' when the button is clicked. You can remove all uses of self.inhibit and rename 'temp_inhibit' to something more meaningful, like 'delete_item'. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote: > Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: > > > My issue is solved, but I'm still curious about what is happening > > here. > > MRAB already said it: When you enter the callback function, Tk's > mainloop waits for it to return. So what's happening is: > > 1. Tk's mainloop pauses > 2. temp_unbind() is called > 3. TreeviewSelect is unbound > 4. events are queued > 5. TreeviewSelect is bound again > 6. temp_unbind() returns > 7. Tk's mainloop continues with the state: > - TreeviewSelect is bound > - events are queued > > [. . .] Thanks (also to others who have explained), now I get it! > FWIW, here's a version without after(), solving this purely on the > python side, not by temporarily unbinding the event, but by > selectively doing nothing in the callback function. > > from tkinter import * > from tkinter.ttk import * > > class Test: > def __init__(self): > self.inhibit = False > root=Tk() > self.tree = Treeview(root) > self.tree.pack() > self.iid = self.tree.insert('', 0, text='test') > Button(root, command=self.temp_inhibit).pack() > mainloop() > > def callback(self, *e): > if not self.inhibit: > print('called') > > def temp_inhibit(self): > self.inhibit = True > self.tree.selection_set(self.iid) > self.tree.selection_remove(self.iid) > self.tree.selection_set(self.iid) > self.inhibit = False > self.callback() > > c=Test() > I like this solution better - it's much more obvious to me what it's doing. Regards John -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On 12/09/2023 19:51, Mirko via Python-list wrote: I have also found that after() is a cure for some ills, though I avoid using it more than I have to because it feels ... a bit fragile, perhaps. Yeah. Though for me it was the delay which made it seem fragile. With a 0 delay, this looks much more reliable. At one point I found myself writing, or thinking of writing, this sort of code after(1, DoSomeThing) after(2, Do SomeThingElse) after(3, DoAThirdThing) ... but this just felt wrong (is it reliable if some Things take more than a millisecond? It may well be; I don't know), and error-prone if I want to add some more Things. Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On 2023-09-12 19:51, Mirko via Python-list wrote: Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: My issue is solved, but I'm still curious about what is happening here. MRAB already said it: When you enter the callback function, Tk's mainloop waits for it to return. So what's happening is: 1. Tk's mainloop pauses 2. temp_unbind() is called 3. TreeviewSelect is unbound 4. events are queued 5. TreeviewSelect is bound again 6. temp_unbind() returns 7. Tk's mainloop continues with the state: - TreeviewSelect is bound - events are queued Am 11.09.23 um 23:58 schrieb Rob Cliffe: Indeed. And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). Ah, nice, didn't know that! Well, strictly speaking, it's the order in which they were queued except for .after, which will be postponed if you specify a positive delay. [snip] -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list: My issue is solved, but I'm still curious about what is happening here. MRAB already said it: When you enter the callback function, Tk's mainloop waits for it to return. So what's happening is: 1. Tk's mainloop pauses 2. temp_unbind() is called 3. TreeviewSelect is unbound 4. events are queued 5. TreeviewSelect is bound again 6. temp_unbind() returns 7. Tk's mainloop continues with the state: - TreeviewSelect is bound - events are queued Am 11.09.23 um 23:58 schrieb Rob Cliffe: Indeed. And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). Ah, nice, didn't know that! I have also found that after() is a cure for some ills, though I avoid using it more than I have to because it feels ... a bit fragile, perhaps. Yeah. Though for me it was the delay which made it seem fragile. With a 0 delay, this looks much more reliable. FWIW, here's a version without after(), solving this purely on the python side, not by temporarily unbinding the event, but by selectively doing nothing in the callback function. from tkinter import * from tkinter.ttk import * class Test: def __init__(self): self.inhibit = False root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_inhibit).pack() mainloop() def callback(self, *e): if not self.inhibit: print('called') def temp_inhibit(self): self.inhibit = True self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.inhibit = False self.callback() c=Test() HTH and regards -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On 2023-09-12 06:43, John O'Hagan via Python-list wrote: On Mon, 2023-09-11 at 22:25 +0200, Mirko via Python-list wrote: Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: > I was surprised that the code below prints 'called' three times. > > > from tkinter import * > from tkinter.ttk import * > > root=Tk() > > def callback(*e): > print('called') > > tree = Treeview(root) > tree.pack() > > iid = tree.insert('', 0, text='test') > > tree.selection_set(iid) > tree.selection_remove(iid) > tree.selection_set(iid) > > tree.bind('<>', callback) > > mainloop() > > In other words, selection events that occurred _before_ the > callback > function was bound to the Treeview selections are triggering the > function upon binding. AFAIK, no other tk widget/binding > combination > behaves this way (although I haven't tried all of them). > > This was a problem because I wanted to reset the contents of the > Treeview without triggering a relatively expensive bound function, > but > found that temporarily unbinding didn't prevent the calls. > > I've worked around this by using a regular button-click binding for > selection instead, but I'm curious if anyone can cast any light on > this. > > Cheers > > John AFAIK (it's been quite some time, since I used Tk/Tkinter): These selection events are not triggered upon binding, but after the mainloop has startet. Tk's eventloop is queue-driven, so the tree.selection_{set,remove}() calls just place the events on the queue. After that, you setup a callback and when the mainloop starts, it processes the events from the queue, executing the registered callback. I seem to remember, that I solved a similar issue by deferring the callback installation using root.after(). from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) root.after(100, lambda: tree.bind('<>', callback)) mainloop() This does not print "called" at all after startup (but still selects the entry), because the callback has not been installed when the mainloop starts. But any subsequent interaction with the list (clicking) will print it (since the callback is then setup). HTH Thanks for your reply. However, please see the example below, which is more like my actual use-case. The selection events take place when a button is pressed, after the mainloop has started but before the binding. This also prints 'called' three times. from tkinter import * from tkinter.ttk import * class Test: def __init__(self): root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_unbind).pack() mainloop() def callback(self, *e): print('called') def temp_unbind(self): self.tree.unbind('<>') self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.tree.bind('<>', self.callback) #self.tree.after(0, lambda: self.tree.bind('<>', self.callback)) c=Test() It seems the events are still queued, and then processed by a later bind? However, your solution still works, i.e. replacing the bind call with the commented line. This works even with a delay of 0, as suggested in Rob Cliffe's reply. Does the call to after clear the event queue somehow? My issue is solved, but I'm still curious about what is happening here. Yes, it's still queuing the events. When an event occurs, it's queued. So, you unbound and then re-bound the callback in temp_unbind? Doesn't matter. All that matters is that on returning from temp_unbind to the main event loop, there are events queued and there's a callback registered, so the callback is invoked. Using the .after trick queues an event that will re-bind the callback _after_ the previous events have been handled. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On Mon, 2023-09-11 at 22:25 +0200, Mirko via Python-list wrote: > Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: > > I was surprised that the code below prints 'called' three times. > > > > > > from tkinter import * > > from tkinter.ttk import * > > > > root=Tk() > > > > def callback(*e): > > print('called') > > > > tree = Treeview(root) > > tree.pack() > > > > iid = tree.insert('', 0, text='test') > > > > tree.selection_set(iid) > > tree.selection_remove(iid) > > tree.selection_set(iid) > > > > tree.bind('<>', callback) > > > > mainloop() > > > > In other words, selection events that occurred _before_ the > > callback > > function was bound to the Treeview selections are triggering the > > function upon binding. AFAIK, no other tk widget/binding > > combination > > behaves this way (although I haven't tried all of them). > > > > This was a problem because I wanted to reset the contents of the > > Treeview without triggering a relatively expensive bound function, > > but > > found that temporarily unbinding didn't prevent the calls. > > > > I've worked around this by using a regular button-click binding for > > selection instead, but I'm curious if anyone can cast any light on > > this. > > > > Cheers > > > > John > > > AFAIK (it's been quite some time, since I used Tk/Tkinter): > > These selection events are not triggered upon binding, but after the > mainloop has startet. Tk's eventloop is queue-driven, so the > tree.selection_{set,remove}() calls just place the events on the > queue. After that, you setup a callback and when the mainloop > starts, it processes the events from the queue, executing the > registered callback. > > I seem to remember, that I solved a similar issue by deferring the > callback installation using root.after(). > > > from tkinter import * > from tkinter.ttk import * > > root=Tk() > > def callback(*e): > print('called') > > tree = Treeview(root) > tree.pack() > > iid = tree.insert('', 0, text='test') > > tree.selection_set(iid) > tree.selection_remove(iid) > tree.selection_set(iid) > > root.after(100, lambda: tree.bind('<>', callback)) > > mainloop() > > > > This does not print "called" at all after startup (but still selects > the entry), because the callback has not been installed when the > mainloop starts. But any subsequent interaction with the list > (clicking) will print it (since the callback is then setup). > > HTH Thanks for your reply. However, please see the example below, which is more like my actual use-case. The selection events take place when a button is pressed, after the mainloop has started but before the binding. This also prints 'called' three times. from tkinter import * from tkinter.ttk import * class Test: def __init__(self): root=Tk() self.tree = Treeview(root) self.tree.pack() self.iid = self.tree.insert('', 0, text='test') Button(root, command=self.temp_unbind).pack() mainloop() def callback(self, *e): print('called') def temp_unbind(self): self.tree.unbind('<>') self.tree.selection_set(self.iid) self.tree.selection_remove(self.iid) self.tree.selection_set(self.iid) self.tree.bind('<>', self.callback) #self.tree.after(0, lambda: self.tree.bind('<>', self.callback)) c=Test() It seems the events are still queued, and then processed by a later bind? However, your solution still works, i.e. replacing the bind call with the commented line. This works even with a delay of 0, as suggested in Rob Cliffe's reply. Does the call to after clear the event queue somehow? My issue is solved, but I'm still curious about what is happening here. Regards John -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
On 11/09/2023 21:25, Mirko via Python-list wrote: Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: I was surprised that the code below prints 'called' three times. from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) tree.bind('<>', callback) mainloop() In other words, selection events that occurred _before_ the callback function was bound to the Treeview selections are triggering the function upon binding. AFAIK, no other tk widget/binding combination behaves this way (although I haven't tried all of them). This was a problem because I wanted to reset the contents of the Treeview without triggering a relatively expensive bound function, but found that temporarily unbinding didn't prevent the calls. I've worked around this by using a regular button-click binding for selection instead, but I'm curious if anyone can cast any light on this. Cheers John AFAIK (it's been quite some time, since I used Tk/Tkinter): These selection events are not triggered upon binding, but after the mainloop has startet. Tk's eventloop is queue-driven, so the tree.selection_{set,remove}() calls just place the events on the queue. After that, you setup a callback and when the mainloop starts, it processes the events from the queue, executing the registered callback. I seem to remember, that I solved a similar issue by deferring the callback installation using root.after(). from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) root.after(100, lambda: tree.bind('<>', callback)) mainloop() This does not print "called" at all after startup (but still selects the entry), because the callback has not been installed when the mainloop starts. But any subsequent interaction with the list (clicking) will print it (since the callback is then setup). HTH Indeed. And you don't need to specify a delay of 100 milliseconds. 0 will work (I'm guessing that's because queued actions are performed in the order that they were queued). I have also found that after() is a cure for some ills, though I avoid using it more than I have to because it feels ... a bit fragile, perhaps. E.g. suppose the mouse is clicked on a widget and tk responds by giving that widget the focus, but I don't want that to happen. I can't AFAIK prevent the focus change, but I can immediately cancel it with X.after(0, SomeOtherWidget.focus_set) where X is any convenient object with the "after" method (just about any widget, or the root). Best wishes Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter ttk Treeview binding responds to past events!
Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list: I was surprised that the code below prints 'called' three times. from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) tree.bind('<>', callback) mainloop() In other words, selection events that occurred _before_ the callback function was bound to the Treeview selections are triggering the function upon binding. AFAIK, no other tk widget/binding combination behaves this way (although I haven't tried all of them). This was a problem because I wanted to reset the contents of the Treeview without triggering a relatively expensive bound function, but found that temporarily unbinding didn't prevent the calls. I've worked around this by using a regular button-click binding for selection instead, but I'm curious if anyone can cast any light on this. Cheers John AFAIK (it's been quite some time, since I used Tk/Tkinter): These selection events are not triggered upon binding, but after the mainloop has startet. Tk's eventloop is queue-driven, so the tree.selection_{set,remove}() calls just place the events on the queue. After that, you setup a callback and when the mainloop starts, it processes the events from the queue, executing the registered callback. I seem to remember, that I solved a similar issue by deferring the callback installation using root.after(). from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) root.after(100, lambda: tree.bind('<>', callback)) mainloop() This does not print "called" at all after startup (but still selects the entry), because the callback has not been installed when the mainloop starts. But any subsequent interaction with the list (clicking) will print it (since the callback is then setup). HTH -- https://mail.python.org/mailman/listinfo/python-list
Tkinter ttk Treeview binding responds to past events!
I was surprised that the code below prints 'called' three times. from tkinter import * from tkinter.ttk import * root=Tk() def callback(*e): print('called') tree = Treeview(root) tree.pack() iid = tree.insert('', 0, text='test') tree.selection_set(iid) tree.selection_remove(iid) tree.selection_set(iid) tree.bind('<>', callback) mainloop() In other words, selection events that occurred _before_ the callback function was bound to the Treeview selections are triggering the function upon binding. AFAIK, no other tk widget/binding combination behaves this way (although I haven't tried all of them). This was a problem because I wanted to reset the contents of the Treeview without triggering a relatively expensive bound function, but found that temporarily unbinding didn't prevent the calls. I've worked around this by using a regular button-click binding for selection instead, but I'm curious if anyone can cast any light on this. Cheers John -- https://mail.python.org/mailman/listinfo/python-list
TKinter in Python - advanced notions - ok
Well, its kind of obvious to make a skeleton, copy it in for some basic functionality and modularly ( is that a word ? ) manage each piece. That ( like your example ) is fine stuff. As a side note, I am sure large, large highly generalised programs are pretty hard to make. One thing I do is make each file have a null class like: # Empty object maker ( M T ) ... get it say it ! class MT(): pass # Hook point for this module generally mod = MT() Then, a category of symbols ( mostly 'variables ), grow under mod.(Whatever) # This window gets to exist, and it's exit via op sys clicks mod.ws = sb.make_Tk_Window( "seqdecodeshow" + str( a_Num ), gi.kCONFIGWIN ) This basic notion is that self.(stuff) is not quite multi class enough, yet 'global' is unpopular as a notation, due to name pollution. IN A BIG PROGRAM NOT A LITTLE WEENEY One YOU SCRATCH ON A BLACKBOARD SOMEPLACE !! Generally, The way I proceed is to try to avoid CLASSes in each module, but only a little. If you need it, you sure do. So early on ( like < 100 lines, if you avoided a class, roll back and add it ). Then, mod.(anything) is 'sort of' like self to class, but its politics is the filename that made it alone. If mod. is not used exactly in a class, roll it back to self. If its way more abstractley used, upgrade it to your concept of really global, which generally should be somewhat sparely used. All my TK calls are wrapped in a custom layer, it reduces the line count to 1/3. like so: sb.checkableBoole(cFrmL, 0, 0, gi.us, e_Txt, setting_ClickCb ) sb.textCmdLine( cFrmL, 1, 0, gi.us, 'Apply', applyThoseSelects ) sb.textCmdLine( cFrmL, 1, 1, gi.us, 'Reset', resetSelects ) sb.textCmdLine( cFrmL, 1, 2, gi.us, 'Select all', cbSelectAll ) cFrmL is the TK thing that contains these few text lines, with all the bg colors, whitepace, fonts, managed inside This calls 'grid' of course for placement. But all colors, and callbacks for changes are entirely in called pieces, which have been tested like 150% crazy. sb is import screenBuilder1 assb # Screen maker for TKinter and TKinter ++ windows If you want to use my 'screenbuilder'... talk to me, I suppose. this is a biology IDE, the screen part is just a little piece of a huge initiative. Obviously, the human being's ideas in there head matter so the TK stuff is important, to say the least Regs, Daniel B. Kolis my ref: 24 Jun 2023, https://groups.google.com/g/comp.lang.python/ -- https://mail.python.org/mailman/listinfo/python-list
Re: TKinter in Python - advanced notions
On Sat, 24 Jun 2023 at 15:57, Thomas Passin via Python-list wrote: > As a general comment (and I have not done anything tricky or complex > with Tk), MVC or the other approaches in a similar vein, though good, > can lead you into more complexity than you need, because of the extra > abstractions involved. Yes, for sure the GUI should not be doing domain > or business logic. Yes, it's good to keep database access separate from > the other parts of your program. But you may not need all the classes > and layers that you think you might. It all depends on what you need to > do, of course. > > Another useful design thought is to try to keep as much of the GUI logic > separate from Tk itself as possible. Basically, you would write a more > abstract (and simpler) GUI API, and then write an adapter that knows how > to make Tk do those things. One advantage is that this approach makes > it easier to change to another GUI toolkit later (say PyQt, for > example). Another is that it helps you avoid getting sucked into too > many Tk details that aren't needed for the program concept. I'd agree, although what I would call this is a GUI *skeleton*. It's not usually worth trying to isolate that from the actual GUI once you reach production, but it's a great first step as you're building. MVC and other such design patterns are excellent tools for learning and conceptualizing, but I agree, it's not something you have to feel locked into. When talking with students, I'll ask them to show me whether something is part of the model, the view, or the controller, but only to make sure they know what their code is doing. It's not like I would ask them to make three separate files (usually - maybe I'd pitch that to a struggling student as a teaching tool, but not in prod). ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: TKinter in Python - advanced notions
On 6/23/2023 4:16 AM, Andreas Heckel via Python-list wrote: Hi, Apologies for potentially mis-using this thread. But I have been struggling recently making exactly this leap from simple GUI examples to a more elaborate MVVM concept. Mainly I have been struggling finding nice example python code bases, that allow some understanding to the beginner, which I certainly still am, but also show enough complexity to see the concept in action. Any hints / links to github or similar highly welcome. If the list is not the appropriate place, I am happy if you email me directly. Cheers, Andreas -Original Message- From: Python-list On Behalf Of Diego Souza via Python-list Sent: Friday, June 23, 2023 4:14 AM To: aapost Cc: python-list Subject: Re: TKinter in Python - advanced notions Have you considered improving the architecture itself, not your GUI library skills? I recommend you look at the Model View ViewModel (MVVM) concept and implement something similar (this is largely used in the Android framework nowadays). This would separate your program logic from the rendering and visualization. It would also make your program more reactive, decoupled, and easier to maintain. When you mentioned threads I immediately thought of this because it is much easier to implement parallel jobs and present results back in the GUI, as everything becomes reactive. This is overkill for a small project such as the code you showed, but I recommend it for larger projects. As a general comment (and I have not done anything tricky or complex with Tk), MVC or the other approaches in a similar vein, though good, can lead you into more complexity than you need, because of the extra abstractions involved. Yes, for sure the GUI should not be doing domain or business logic. Yes, it's good to keep database access separate from the other parts of your program. But you may not need all the classes and layers that you think you might. It all depends on what you need to do, of course. Another useful design thought is to try to keep as much of the GUI logic separate from Tk itself as possible. Basically, you would write a more abstract (and simpler) GUI API, and then write an adapter that knows how to make Tk do those things. One advantage is that this approach makes it easier to change to another GUI toolkit later (say PyQt, for example). Another is that it helps you avoid getting sucked into too many Tk details that aren't needed for the program concept. Here is a simple (or simple-minded :) ) example: class AbstractApi: """An abstract class for standardizing access to a display widget.""" def __init__(self, parent): self.parent = parent self.client = None def registerClient(self, client): self.client = client def loadPanel(self, panel_name, html): """Load html into display panel.""" pass def focusPanel(self, panel_name): """Select a named display panel.""" pass def handleSearchText(self): pass def writeStatusBar(self, msg): pass def handleLinkClicked(self, uri, source): """Handle a link clicked in the "source" display panel.""" pass These (let us say for the purposes of illustration) are the only things you need from the GUI. You can write a Tk-specific version of this, and the rest of your program doesn't need to know that Tk is even involved. If you want to change to say GTK, this class is the only thing that would need to change. Even if this approach turns out to be too simple for a really complicated UI, the closer you can come to realizing it the better. On Wed, Jun 21, 2023 at 7:20 PM aapost via Python-list < python-list@python.org> wrote: On 6/21/23 09:47, Dan Kolis wrote: I've write a huge biotech program ( an IDE for synthetic biology ), and am slowly outgrowing TKINTER. Has anybody out there merged a little bit of TCL direct calls from Python 3.X to get more freedom then TKINTER for just some Windows ? I wish it looked better, but its 'ok'. I believe X11 IO is considerably superior for serious work the HTML. I mean 'serious' work. with lots of multi media windows. I am not talking about fb "Oh ! There is a window it opened inthe corner !"... trivial functionality. I don't know if it would help, but you can extend/add tcl/tk packages I don't remember the full instructions right off, but quickly reverse engineering my old stuff I think you just need to drop them in /usr/share/tcltk/ or equivalent. (I needed to do that to replace the terrible looking default file dialog for unix/linux with fsdialog.) then running something like the following from your Tk object self.eval('package require fsdialog') (reverse engineering the python tkinter source you can likely find other ways of doing more tcl direct
Re: TKinter in Python - advanced notions - reactive
I am not specifically having any problems implementing what I want to make work. Callbacks etc make it fairly easy to make TKinter react to things without any specific fancy plan for it. Add callbacks for real time changes early in any new notion, after it looks right go to the IO part make it react. Regards, thanks, Dan -- https://mail.python.org/mailman/listinfo/python-list
Re: TKinter in Python - advanced notions
If you have a problem,. ask a super specific question, here. If I can help, I will, but TKINTER knowledge is pretty spread around. Many others migth jump in, too. Its works, its slightly quirky, has no licencing hangups. X11 makes fine fine programs ! Keep hacking,Dan -- https://mail.python.org/mailman/listinfo/python-list
RE: TKinter in Python - advanced notions
Hi, Apologies for potentially mis-using this thread. But I have been struggling recently making exactly this leap from simple GUI examples to a more elaborate MVVM concept. Mainly I have been struggling finding nice example python code bases, that allow some understanding to the beginner, which I certainly still am, but also show enough complexity to see the concept in action. Any hints / links to github or similar highly welcome. If the list is not the appropriate place, I am happy if you email me directly. Cheers, Andreas > -Original Message- > From: Python-list > On Behalf Of Diego Souza via Python-list > Sent: Friday, June 23, 2023 4:14 AM > To: aapost > Cc: python-list > Subject: Re: TKinter in Python - advanced notions > > Have you considered improving the architecture itself, not your GUI library > skills? > > I recommend you look at the Model View ViewModel (MVVM) concept and > implement something similar (this is largely used in the Android framework > nowadays). This would separate your program logic from the rendering and > visualization. It would also make your program more reactive, decoupled, > and easier to maintain. When you mentioned threads I immediately thought of > this because it is much easier to implement parallel jobs and present > results back in the GUI, as everything becomes reactive. This is overkill > for a small project such as the code you showed, but I recommend it for > larger projects. > > > > > > On Wed, Jun 21, 2023 at 7:20 PM aapost via Python-list < > python-list@python.org> wrote: > > > On 6/21/23 09:47, Dan Kolis wrote: > > > I've write a huge biotech program ( an IDE for synthetic biology ), and > > am slowly outgrowing TKINTER. > > > > > > Has anybody out there merged a little bit of TCL direct calls from > > Python 3.X to get more freedom then TKINTER for just some Windows ? > > > > > I wish it looked better, but its 'ok'. I believe X11 IO is considerably > > superior for serious work the HTML. I mean 'serious' work. with lots of > > multi media windows. I am not talking about fb "Oh ! There is a window it > > opened inthe corner !"... trivial functionality. > > > > > > I don't know if it would help, but you can extend/add tcl/tk packages > > > > I don't remember the full instructions right off, but quickly reverse > > engineering my old stuff I think you just need to drop them in > > /usr/share/tcltk/ or equivalent. > > > > (I needed to do that to replace the terrible looking default file dialog > > for unix/linux with fsdialog.) > > > > then running something like the following from your Tk object > > > > self.eval('package require fsdialog') > > > > (reverse engineering the python tkinter source you can likely find other > > ways of doing more tcl direct stuff) > > > > I have not researched if there are some better, more featured > > (non-buggy) Text widgets implemented in tcl that can be dropped in, (I > > know several of the tcl drop in widgets I tried were lacking in > > refinement). > > > > From what I can tell, once upon a time there were better, more > > interesting projects and tutorials on extending tkinter, such as WCK > > (tkinter3000), but the only remnants of those remain publicly available > > are outdated unmaintained archives. > > > > You might also consider looking at the Grail browser source for research > > purposes, as it does some interesting things with some of the widgets, > > (parsing html and such), even though it is 20 years old now (and written > > in python 1). > > The update attempts from 10+ years ago have disappeared. (it's license > > is considered questionable from what I understand, so not sure if that > > is an aspect of it, the other being one of it's main features, python > > applets, is unsafe and was not easily fixable) > > > > You might already be beyond some of these things though. > > > > I know what you mean as far is feeling like the little bit extra you > > need pushes beyond what tkinter can do / makes you feel like you have > > outgrown the module. > > > > (I had to take a break from one of my projects and send it to > > development hell until my UI knowledge/skills improve after I found > > myself considering using xml schema appinfo annotations to store json > > formatted widget specific information, lol.) > > > > I have felt that sense of lack with most of the UI modules I have tried > > though. > > > > I don't know of a clear better python-only solution though that fits my > > personal needs. >
Re: TKinter in Python - advanced notions
Have you considered improving the architecture itself, not your GUI library skills? I recommend you look at the Model View ViewModel (MVVM) concept and implement something similar (this is largely used in the Android framework nowadays). This would separate your program logic from the rendering and visualization. It would also make your program more reactive, decoupled, and easier to maintain. When you mentioned threads I immediately thought of this because it is much easier to implement parallel jobs and present results back in the GUI, as everything becomes reactive. This is overkill for a small project such as the code you showed, but I recommend it for larger projects. On Wed, Jun 21, 2023 at 7:20 PM aapost via Python-list < python-list@python.org> wrote: > On 6/21/23 09:47, Dan Kolis wrote: > > I've write a huge biotech program ( an IDE for synthetic biology ), and > am slowly outgrowing TKINTER. > > > > Has anybody out there merged a little bit of TCL direct calls from > Python 3.X to get more freedom then TKINTER for just some Windows ? > > > I wish it looked better, but its 'ok'. I believe X11 IO is considerably > superior for serious work the HTML. I mean 'serious' work. with lots of > multi media windows. I am not talking about fb "Oh ! There is a window it > opened inthe corner !"... trivial functionality. > > > I don't know if it would help, but you can extend/add tcl/tk packages > > I don't remember the full instructions right off, but quickly reverse > engineering my old stuff I think you just need to drop them in > /usr/share/tcltk/ or equivalent. > > (I needed to do that to replace the terrible looking default file dialog > for unix/linux with fsdialog.) > > then running something like the following from your Tk object > > self.eval('package require fsdialog') > > (reverse engineering the python tkinter source you can likely find other > ways of doing more tcl direct stuff) > > I have not researched if there are some better, more featured > (non-buggy) Text widgets implemented in tcl that can be dropped in, (I > know several of the tcl drop in widgets I tried were lacking in > refinement). > > From what I can tell, once upon a time there were better, more > interesting projects and tutorials on extending tkinter, such as WCK > (tkinter3000), but the only remnants of those remain publicly available > are outdated unmaintained archives. > > You might also consider looking at the Grail browser source for research > purposes, as it does some interesting things with some of the widgets, > (parsing html and such), even though it is 20 years old now (and written > in python 1). > The update attempts from 10+ years ago have disappeared. (it's license > is considered questionable from what I understand, so not sure if that > is an aspect of it, the other being one of it's main features, python > applets, is unsafe and was not easily fixable) > > You might already be beyond some of these things though. > > I know what you mean as far is feeling like the little bit extra you > need pushes beyond what tkinter can do / makes you feel like you have > outgrown the module. > > (I had to take a break from one of my projects and send it to > development hell until my UI knowledge/skills improve after I found > myself considering using xml schema appinfo annotations to store json > formatted widget specific information, lol.) > > I have felt that sense of lack with most of the UI modules I have tried > though. > > I don't know of a clear better python-only solution though that fits my > personal needs. > > So I have to lean toward improving my tcl / C in hopes that it might > help steer me toward that extra (which seems to be in the spirit of what > tcl/tk's intent is to begin with). That will be a while for me though if > I get there. > > > > > -- > https://mail.python.org/mailman/listinfo/python-list > -- Diego Souza Wespa Intelligent Systems Rio de Janeiro - Brasil -- https://mail.python.org/mailman/listinfo/python-list
Re: TKinter in Python - advanced notions
On 6/21/23 09:47, Dan Kolis wrote: I've write a huge biotech program ( an IDE for synthetic biology ), and am slowly outgrowing TKINTER. Has anybody out there merged a little bit of TCL direct calls from Python 3.X to get more freedom then TKINTER for just some Windows ? I wish it looked better, but its 'ok'. I believe X11 IO is considerably superior for serious work the HTML. I mean 'serious' work. with lots of multi media windows. I am not talking about fb "Oh ! There is a window it opened inthe corner !"... trivial functionality. I don't know if it would help, but you can extend/add tcl/tk packages I don't remember the full instructions right off, but quickly reverse engineering my old stuff I think you just need to drop them in /usr/share/tcltk/ or equivalent. (I needed to do that to replace the terrible looking default file dialog for unix/linux with fsdialog.) then running something like the following from your Tk object self.eval('package require fsdialog') (reverse engineering the python tkinter source you can likely find other ways of doing more tcl direct stuff) I have not researched if there are some better, more featured (non-buggy) Text widgets implemented in tcl that can be dropped in, (I know several of the tcl drop in widgets I tried were lacking in refinement). From what I can tell, once upon a time there were better, more interesting projects and tutorials on extending tkinter, such as WCK (tkinter3000), but the only remnants of those remain publicly available are outdated unmaintained archives. You might also consider looking at the Grail browser source for research purposes, as it does some interesting things with some of the widgets, (parsing html and such), even though it is 20 years old now (and written in python 1). The update attempts from 10+ years ago have disappeared. (it's license is considered questionable from what I understand, so not sure if that is an aspect of it, the other being one of it's main features, python applets, is unsafe and was not easily fixable) You might already be beyond some of these things though. I know what you mean as far is feeling like the little bit extra you need pushes beyond what tkinter can do / makes you feel like you have outgrown the module. (I had to take a break from one of my projects and send it to development hell until my UI knowledge/skills improve after I found myself considering using xml schema appinfo annotations to store json formatted widget specific information, lol.) I have felt that sense of lack with most of the UI modules I have tried though. I don't know of a clear better python-only solution though that fits my personal needs. So I have to lean toward improving my tcl / C in hopes that it might help steer me toward that extra (which seems to be in the spirit of what tcl/tk's intent is to begin with). That will be a while for me though if I get there. -- https://mail.python.org/mailman/listinfo/python-list
TKinter in Python - advanced notions
Hi, I've write a huge biotech program ( an IDE for synthetic biology ), and am slowly outgrowing TKINTER. Has anybody out there merged a little bit of TCL direct calls from Python 3.X to get more freedom then TKINTER for just some Windows ? How about bold stories of successes ( yours, not mine ) on porting to stupid MS Windows from linux ? Adding threading makes TKinter hard ( but not impossible ) to manage. Also, a little bit here and there obviously exceeds TKINTERs goals. I wish it looked better, but its 'ok'. I believe X11 IO is considerably superior for serious work the HTML. I mean 'serious' work. with lots of multi media windows. I am not talking about fb "Oh ! There is a window it opened inthe corner !"... trivial functionality. Must be a uber expert out there. Is it you ? As attached. and little code. Coloring text makes me realise; some of this is pretty indirect, though this is quite well thought out, like all of TKINTER. Regards, Daniel B. Kolis """ An important worked example of text color and other look dynamic changes. This is the righ way to do this for fast changes ! 20 Jun 2023 22:11 """ import tkinter as tk from tkinter.font import Font class Pad( tk.Frame ): def __init__( self, parent, *args, **kwargs ): tk.Frame.__init__( self, parent, *args, **kwargs ) self.toolbar = tk.Frame( self, bg="#eee" ) self.toolbar.pack( side="top", fill="x" ) self.bold_btn = tk.Button( self.toolbar, text="CHANGE highlighted", command=self.make_Change_Highlighted ) self.bold_btn.pack( side="left" ) self.bold_btn = tk.Button( self.toolbar, text="CHANGE H.B.", command=self.make_Change_Hb ) self.bold_btn.pack( side="left" ) self.bold_btn = tk.Button( self.toolbar, text="Delete a char", command=self.make_Change_Delete ) self.bold_btn.pack( side="left" ) self.clear_btn = tk.Button( self.toolbar, text="Clear", command=self.clear_Some ) self.clear_btn.pack( side="left" ) # Applies this font self.bold_font = Font( family="Helvetica", size=14, weight="bold" ) self.da_Text = tk.Text( self ) self.da_Text.insert( "end", "Selectable parts of text is fun.\nSo is a happy birthday, right ?" ) self.da_Text.focus( ) self.da_Text.pack( fill="both", expand=True ) # configuring a tag called dingo-something self.da_Text.tag_configure( "reddingo", font=self.bold_font, foreground = "Red" ) self.da_Text.tag_configure( "bluedingo", font=self.bold_font, background = "Yellow", foreground = "Blue" ) # Button CB def make_Change_Delete( self ): self.da_Text.delete( '1.0', '1.1' ) # Button CB def make_Change_Highlighted( self ): # tk.TclError exception is raised if not text is selected try: self.da_Text.tag_add( "reddingo", "sel.first", "sel.last" ) except tk.TclError: tt = 569 # Button CB def make_Change_Hb( self ): try: lin_Idx = 2; col_Idx = 8 self.da_Text.tag_add( "bluedingo", f"{ lin_Idx }.{ col_Idx }", f"{ lin_Idx }.{ col_Idx + len( 'happy birthday' ) }" ) except: gg = 457 # Button CB def clear_Some( self ): self.da_Text.tag_remove( "reddingo", "1.0", 'end' ) self.da_Text.tag_remove( "bluedingo", "1.0", 'end' ) # Main body really def is_Main(): root = tk.Tk() Pad( root ).pack( expand=1, fill="both" ) root.mainloop() # Go if __name__ == "__main__": is_Main() Document end my ref: 21 Jun 2023, https://groups.google.com/g/comp.lang.python, Daniel B. Kolis, nafl -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
On 2023-05-26, Rob Cliffe via Python-list wrote: > Grant, I may well buy one of the books you suggested. I haven't had look at either of the newer books, but I got a lot of good out of the Grayson book (20 years ago). I also had a Tcl/Tk book that I found useful even when usng tkinter, but it's even older than the Grayson one... -- https://mail.python.org/mailman/listinfo/python-list
Tkinter Redo's
On Tuesday, May 30, 2023 at 1:28:04 PM UTC-4, Rob Cliffe wrote: > Thanks to everyone who replied. All replies were constructive, none > were telling me to stop belly-aching. Hi, Dan says: When you get your style ideas sort of frozen, maybe you can poke up a sample here. Aworked example for yourself is useful anyway. My stuffs all in Ubuntu so seeing what works and doesn't in MS products interests me a lot. I usually avoid the tkk variations almost completely. I have all the things I use each wrapped in a call that does what I want both aesthetically and so on. My app is only medium sensitive to art look and feel, productivity to maintain it is more important then super fancy looking. Regards, Dan -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
Thanks to everyone who replied. All replies were constructive, none were telling me to stop belly-aching. I forgot/omitted to state that it was I who wrote the original project (in a completely different language), making the task of re-writing it much less formidable. And meaning that I am familiar with the general concepts of building a GUI. Still, it will be a lot of work. Grant, I may well buy one of the books you suggested. I find the topic of themes and styles the hardest one to get my head around (if anyone knows a good introduction that would be fantastic). All the other stuff is OK provided I can find something on the net to give me the necessary information, which so far I usually can. Christian, I am adopting your suggestion of using ttk widgets, except for Button objects, because The colour of tk.Button objects can be set directly (bg=... fg=...) On my platform (Windows10) the shadowing of tk.Button objects is more conspicuous (without using styles or whatever). Best wishes Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
On 24May2023 02:18, Rob Cliffe wrote: There doesn't seem to be any decent documentation for it anywhere. Already mentioned in the replies, I use this: https://tkdocs.com/shipman/index.html quite a lot. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
Am 24.05.23 um 03:18 schrieb Rob Cliffe: I have recently started converting a large project to tkinter, starting with zero knowledge of tkinter. (You are free to think: BAD IDEA. ) Welcome to the awesome world of GUI development. I was writing a subclass of the Checkbutton class (tkinter's name for what I call a checkbox). I needed to be able to (1) set (2) clear (3) interrogate the checked state. This is easy to do if you associate a "variable" with each Checkbutton instance, as seems to be usual tkinter practice. ("variable" is not a variable in the usual sense, but an object provided by tkinter that is linked to a GUI object (such as a Checkbutton), so that when the GUI object changes, the value of the "variable" changes, and vice versa.) However, I decided that I wanted to dispense with the variable, if possible. As you found out the hard way, it is possible, but then you dive into the internals of how the widgets work - usually you don't want to know that. Also, this bit differs between Tk and Ttk widgets. [...] lengthe description of Checkbutton internals In GUI programming, you will meet a bag of concepts that you haven't seen in sequential programming before. To make it worse, every GUI toolkit brings its own new set of concepts to the table. Maybe it is helpful to work through a Tk tutorial first. This is a good one: http://tkdocs.com/tutorial/index.html Similarly to the tutorial I would suggest to stick with the ttk widgets. Those are an "update" (> 10 years ago) to the tk widgets and are supposed to provide sensible defaults matching the users experience with native GUI elements. There are only 3 widgets where you must use a Tk widget, this is Text (for multiline formatted text entry), Canvas (for 2D drawings), and Toplevel (for new windows/ popups etc.) Christian -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
On Wed, 24 May 2023 at 13:11, Rob Cliffe via Python-list wrote: > > I have recently started converting a large project to tkinter, starting > with zero knowledge of tkinter. (You are free to think: BAD IDEA. ) > I am well aware that adopting a new tool always involves a learning > curve, and that one is prone to think that things are more difficult > than they are/should be, and to belly-ache about it, and that in a year > from now I'll probably wonder what I'm fussing about. Yes, I do think this is a bad idea, though not an abysmal one. I would recommend first playing with tkinter in a dedicated UI-only project before converting the main project to it. Your code in the scratch project can be as messy as it likes, and then you learn from it before tackling the big one :) But your concerns about tkinter's documentation are, sadly, well-founded. Since it's this weird system of thin wrappers around Tcl/Tk, a lot of things are basically just "go read the Tk docs". There are a few key concepts you'll need to get your head around, and I can't go into details because I never truly got *my* head around them... but mostly, the way that variables are used and what happens when events fire. Good luck with it. I'll be frank, building a GUI can be pretty hard... I'm still unsure whether the best way is to use something like tkinter, or to build a web app, pop up a browser window, and establish a websocket to communicate between your JavaScript front end and your Python back end. Yeah, that's how bad GUI building can be sometimes - it is potentially *easier* to build two halves of your app in two different languages than to make your GUI work the way you want it. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
On 5/23/23 21:18, Rob Cliffe wrote: Comments, anyone? Better yet (holds breath ...) can anyone point me towards some decent tkinter documentation? The variables are slightly more integrated when using tcl/tk directly, python has to have the object so you can track/use them easier. And the variables are more of what is intended to track a widgets purpose, vs state stuff that is more the state of the displaying of the widget. occasionally giving tcl/tk a try directly helps, and using the official tcl/tk docs in addition to a couple other decent docs below. https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html https://tkdocs.com/tutorial/styles.html https://www.tcl.tk/man/tcl8.6/ https://www.tcl.tk/man/tcl8.6/TkCmd/contents.html https://www.tcl.tk/man/tcl8.6/TkLib/contents.html (this used to be some documentation that I only discovered existed recently, but most of it doesn't load and I don't know that anyone backed it up for rehosting..) https://web.archive.org/web/20200227170827/http://effbot.org/tkinterbook tk is decent for what it can do, (and it could do potentially more if you had a lifetime to dedicate to it, lol) and it's reasonably stable and not being perpetually hacked about and broken like gtk. A couple additional pointers in case these haven't been figured out yet: Running it interactively and using tab complete helps. If you are running an app you can comment out the mytk.mainloop() statement then run python -i yourtk.py to give you access to all widgets live. For navigating them, just come up with a widget naming convention that works for you in a similar vein to how tk does (like .frame.frame.label to start), i.e. main = tk.Tk() main.frame = tk.Frame() That way if you have anchored your widgets to something at the root level you can navigate down to whatever you are looking for easily. (you can also use winfo_children() iteratively to travel the way tcl structures them, but that is tedious). -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter docs?
On 2023-05-24, Rob Cliffe via Python-list wrote: > I have recently started converting a large project to tkinter, starting > with zero knowledge of tkinter. (You are free to think: BAD IDEA. ) Well, you could be translating them to Tcl/Tk -- so on the scale of bad ideas, your's barely registers. > I am well aware that adopting a new tool always involves a learning > curve, and that one is prone to think that things are more difficult > than they are/should be, and to belly-ache about it, and that in a year > from now I'll probably wonder what I'm fussing about. > Nonetheless ISTM that there is a particular problem with tkinter: > > There doesn't seem to be any decent documentation for it anywhere. Back in the day, the Grayson book was the definitive reference: https://www.amazon.com/Python-Tkinter-Programming-John-Grayson/dp/1884777813/ It's 20+ years old now, so the version of Python it uses is pretty ancient, and I presume Tk has also changed a bit over the years, so... There are a couple recent books, but I haven't looked at them: https://www.amazon.com/Modern-Tkinter-Busy-Python-Developers-dp-1999149564/dp/1999149564/ https://www.amazon.com/Python-GUI-Programming-Tkinter-user-friendly/dp/1801815925/ -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Tkinter docs?
I have recently started converting a large project to tkinter, starting with zero knowledge of tkinter. (You are free to think: BAD IDEA. ) I am well aware that adopting a new tool always involves a learning curve, and that one is prone to think that things are more difficult than they are/should be, and to belly-ache about it, and that in a year from now I'll probably wonder what I'm fussing about. Nonetheless ISTM that there is a particular problem with tkinter: There doesn't seem to be any decent documentation for it anywhere. I seem to have spent al least 95% (feels more like 99%) of my time in research, only the rest available for coding. Everything I've learned has come from scouring the Internet for Stack Overflow pages, videos, and other articles. And while I'm VERY grateful for these resources, most of them cover very basic use, and if I want information on some more obscure technical point, I can only go on looking and looking and hope I eventually stumble upon what I'm looking for, or some acceptable substitute. FWIW: The tkinter error messages are sometimes helpful, sometimes not, occasionally very helpful (as when I pass an invalid option parameter to a function and it tells me what the valid ones are). I feel there is plenty of room for improvement. One example for those familiar with tkinter (I assure you there are others) of how I struggle without adequate documentation: I had learned very early on that tkinter provides two versions of some classes: the original, or "tk" versions, and a later generation, the "ttk" versions (and I have to say that that was a turn-off, as it seemed that the learning curve has just got steeper). It was surely not appropriate for me to delve deeply into this issue at that stage, as there were so many other things I didn't know (like, practically everything). I decide to go with the "tk" versions pro tem, and to investigate the "ttk" versions later if it seemed like a good idea. One annoyance is that some webpages are relevant to one version, some to the other, almost always without being explicit about which. (Can't blame the "tk" ones, as they were probably written before "ttk" was invented.) I was writing a subclass of the Checkbutton class (tkinter's name for what I call a checkbox). I needed to be able to (1) set (2) clear (3) interrogate the checked state. This is easy to do if you associate a "variable" with each Checkbutton instance, as seems to be usual tkinter practice. ("variable" is not a variable in the usual sense, but an object provided by tkinter that is linked to a GUI object (such as a Checkbutton), so that when the GUI object changes, the value of the "variable" changes, and vice versa.) However, I decided that I wanted to dispense with the variable, if possible. (My motivation? Simpler code. Shorter code. Avoiding using up resources by creating unnecessary objects. You are free to think that I was misguided. You are free to think that I should have been happy with something that worked.) I didn't care whether I used a tk.Checkbutton or a ttk.Checkbutton. From various Internet articles I discovered (slowly, after wading through many articles that DID use a "variable"): A way of GETting the state of a tk.CheckButton (but not a ttk.CheckButton) A way of SETting the state of a ttk.CheckButton (but not a tk.CheckButton) Or the other way round. Or something else. I can no longer remember, and I didn't keep a record of all my trials and tribulations, and I can no longer trace which articles I read when. EVENTUALLY I discovered: For a ttk.CheckButton (only), where cb is the checkbox cb.state() returns a tuple of strings which contains, or doesn't, "selected", according to the checked state cb.state(["selected"]) sets the checked state cb.state(["!selected"]) clears the checked state "Aha!" I thought. "Problem solved". Gleefully I wrote my code and tested it. Er, well, not quite. When the Checkbutton object was instantiated, it showed neither a checked nor an unchecked box, but a solid black box. This was the third or so-called "alternate" state provided by tkinter. (Gee, thanks. Oh sorry, it's probably not your fault; as I understand it, tkinter, you're really just a wrapper.) Further research revealed that I could get past this by writing cb.state(["!alternate", "!selected"]) when the object was instantiated. Phew! Finally got my code working. But the story is not quite over. To get the checked state I was using "selected" in cb.state() While this works, later (in fact while composing this e-mail) I stumbled across cb.instate(["selected"]) which does the same thing
Re: Tkinter (related)~
On 5/18/23 21:11, Grant Edwards wrote: On 2023-05-19, Cameron Simpson wrote: On 18May2023 12:06, Jack Dangler wrote: I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - pip install tkinter Defaulting to user installation because normal site-packages is not writeable ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none) ERROR: No matching distribution found for tkinter Is there an alternate path to installing this? Usually tkinter ships with Python because it is part of the stdlib. On some platforms eg Ubuntu Linux the stdlib doesn't come in completely unless you ask - a lot of stdlib packages are apt things you need to ask for. On my Ubunut here tkinter comes from python3-tk. So: $ sudo apt-get install python3-tk And in general, on Linux systems, you'll be better off in the long run if you use the distro's package manager to install Python packages instead of using pip. If there is no distro package, you're usually also better off using 'pip install --user' so that pip isn't messing about with directories that are normally managed by the distro's package manager. When I do have to resort to using pip in install something, I always do a --dry-run first and make a note of any dependancies that pip is going to try to install -- so I can install those using the package manager if possible. -- Grant Grant Great suggestion! I didn't know that --dry-run was available... I'll have to look at that arg... Jack -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter (related)~
On 2023-05-19, Cameron Simpson wrote: > On 18May2023 12:06, Jack Dangler wrote: >>I thought the OP of the tkinter thread currently running may have >>needed to install the tkinter package (since I had the same missing >>component error message), so I tried to install the package on to my >>Ubu laptop - >> >>pip install tkinter >>Defaulting to user installation because normal site-packages is not >>writeable >>ERROR: Could not find a version that satisfies the requirement tkinter >>(from versions: none) >>ERROR: No matching distribution found for tkinter >> >>Is there an alternate path to installing this? > > Usually tkinter ships with Python because it is part of the stdlib. > > On some platforms eg Ubuntu Linux the stdlib doesn't come in completely > unless you ask - a lot of stdlib packages are apt things you need to ask > for. On my Ubunut here tkinter comes from python3-tk. So: > > $ sudo apt-get install python3-tk And in general, on Linux systems, you'll be better off in the long run if you use the distro's package manager to install Python packages instead of using pip. If there is no distro package, you're usually also better off using 'pip install --user' so that pip isn't messing about with directories that are normally managed by the distro's package manager. When I do have to resort to using pip in install something, I always do a --dry-run first and make a note of any dependancies that pip is going to try to install -- so I can install those using the package manager if possible. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter (related)~
On 18May2023 12:06, Jack Dangler wrote: I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - pip install tkinter Defaulting to user installation because normal site-packages is not writeable ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none) ERROR: No matching distribution found for tkinter Is there an alternate path to installing this? Usually tkinter ships with Python because it is part of the stdlib. On some platforms eg Ubuntu Linux the stdlib doesn't come in completely unless you ask - a lot of stdlib packages are apt things you need to ask for. On my Ubunut here tkinter comes from python3-tk. So: $ sudo apt-get install python3-tk Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On 2023-05-12 09:55, Rob Cliffe via Python-list wrote: I am trying to learn tkinter. Several examples on the internet refer to a messagebox class (tkinter.messagebox). But: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> tkinter.messagebox Traceback (most recent call last): File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' >>> Why is this? It's a submodule of tkinter: >>> import tkinter.messagebox as mb >>> mb.showinfo -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter (related)~
On 5/18/23 12:33, Mats Wichmann wrote: On 5/18/23 10:06, Jack Dangler wrote: I didn't want to hijack another thread... I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - install python3-tk to get the distro package. Thanks, Mats! apt worked... I'll have another run at the original thread and see where that takes me. -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On 5/18/23 08:50, Jim Schwartz wrote: This works for me. Hope it helps. from tkinter import messagebox messagebox.showerror("Hi", f"Hello World") It's probably instructive that IDLE always brings it in this way. Lib/idlelib/config_key.py:from tkinter import messagebox Lib/idlelib/configdialog.py:from tkinter import messagebox Lib/idlelib/editor.py:from tkinter import messagebox ... etc -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter (related)~
On 5/18/23 10:06, Jack Dangler wrote: I didn't want to hijack another thread... I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - install python3-tk to get the distro package. -- https://mail.python.org/mailman/listinfo/python-list
Tkinter (related)~
I didn't want to hijack another thread... I thought the OP of the tkinter thread currently running may have needed to install the tkinter package (since I had the same missing component error message), so I tried to install the package on to my Ubu laptop - pip install tkinter Defaulting to user installation because normal site-packages is not writeable ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none) ERROR: No matching distribution found for tkinter Is there an alternate path to installing this? Thanks for any help you can provide... Jack -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On 5/18/2023 9:13 AM, Grant Edwards wrote: On 2023-05-12, Rob Cliffe via Python-list wrote: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. import tkinter tkinter.messagebox Traceback (most recent call last): File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' $ python Python 3.11.3 (main, May 8 2023, 09:00:54) [GCC 12.2.1 20230428] on linux Type "help", "copyright", "credits" or "license" for more information. import tkinter from tkinter import messagebox messagebox Why is this? Dunno. tkinter is a package, messagebox is a module within the tkinter package. the messagebox module has some functions, such as showinfo(). You *can* import those functions using "dot" expressions: >>> from tkinter.messagebox import showinfo You can also import the entire module using the "dot" syntax: >>> import tkinter.messagebox >>> messagebox.showinfo Whether you can directly ask for tkinter.messagebox depends on whether it's been defined or imported in tkinter/__init__.py. -- https://mail.python.org/mailman/listinfo/python-list
RE: Learning tkinter
This works for me. Hope it helps. from tkinter import messagebox messagebox.showerror("Hi", f"Hello World") -Original Message- From: Python-list On Behalf Of Rob Cliffe via Python-list Sent: Friday, May 12, 2023 3:55 AM To: Python Subject: Learning tkinter I am trying to learn tkinter. Several examples on the internet refer to a messagebox class (tkinter.messagebox). But: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> tkinter.messagebox Traceback (most recent call last): File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' >>> Why is this? TIA Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On Thu, 18 May 2023 at 19:15, Rob Cliffe via Python-list wrote: > > I am trying to learn tkinter. > Several examples on the internet refer to a messagebox class > (tkinter.messagebox). > But: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): >File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> > > Why is this? Is it possible that you've created a tkinter.py for your own tinkering? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On Thu, 18 May 2023 at 10:16, Rob Cliffe via Python-list wrote: > > I am trying to learn tkinter. > Several examples on the internet refer to a messagebox class > (tkinter.messagebox). > But: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): >File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> > > Why is this? Do you have a file called tkinter.py in the current directory? -- Oscar -- https://mail.python.org/mailman/listinfo/python-list
Re: Learning tkinter
On 2023-05-12, Rob Cliffe via Python-list wrote: > > Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import tkinter > >>> tkinter.messagebox > Traceback (most recent call last): > File "", line 1, in > AttributeError: module 'tkinter' has no attribute 'messagebox' > >>> $ python Python 3.11.3 (main, May 8 2023, 09:00:54) [GCC 12.2.1 20230428] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> from tkinter import messagebox >>> messagebox >>> > Why is this? Dunno. -- https://mail.python.org/mailman/listinfo/python-list
Learning tkinter
I am trying to learn tkinter. Several examples on the internet refer to a messagebox class (tkinter.messagebox). But: Python 3.8.3 (tags/v3.8.3:6f8c832, May 13 2020, 22:20:19) [MSC v.1925 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tkinter >>> tkinter.messagebox Traceback (most recent call last): File "", line 1, in AttributeError: module 'tkinter' has no attribute 'messagebox' >>> Why is this? TIA Rob Cliffe -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On Tue, 2023-03-14 at 21:54 +1100, John O'Hagan wrote: [...] > Here is minimal code that demonstrates the problem in the subject > line: > > import cv2 > from tkinter import * > > images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths > > cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) > cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, > cv2.WINDOW_FULLSCREEN) > counter=[0] > def show(): >cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) >cv2.waitKey(1) >counter[0] += 1 > > root=Tk() > root.wm_attributes("-topmost", 1) > Button(root, text=' Show ', command=show).pack() > mainloop() > > It works up to a point - I can cycle through the images by clicking > the button - but if I mouse-click on the displayed image (e.g. to use > the zooming and panning features of cv2), nothing happens, and a few > seconds later the image greys out and a popup appears saying > "'Unknown' is not responding" and giving the option of waiting or > forcing close (but sometimes these options are greyed out too). > Clicking "wait", if available, closes the popup but it comes back a > few seconds later. If I then click on the tkinter window titlebar, > the popup changes to "'Tk' is not responding". Clicking on the button > still works and after a few clicks the popup closes. > [...] For anyone interested (and there are a lot of questions about this type of issue out there), here's the nearest I came to a satisfactory solution. In the real code I put a method like: def window_thread(): cv2.namedWindow('W') #window properties omited while 1: # really a flag for clean exit cv2.imshow('W', self.image) cv2.waitKey(40) and call this as a thread from __init__. This updates the image every 40 ms regardless of whether it has been changed or not, in the manner of a video feed. Seems unnecessary, but surprisingly it doesn't seem to use any significant resources and seems to be the only way to keep both the tkinter GUI and the cv2 window responsive. What I'd really like is cv2.wait(until_i_say_so()) - i.e. to wait for a flag that can be set programatically, but it doesn't seem to be available in cv2. Thanks to those who replied. > -- > > John > > -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On Thu, 2023-03-16 at 04:21 -0400, aapost wrote: > On 3/15/23 07:37, John O'Hagan wrote: > > On Tue, 2023-03-14 at 16:22 -0400, aapost wrote: > > > On 3/14/23 06:54, John O'Hagan wrote: > > > > [...] > > > > > > > Read an alternative description of the waitKey behavior > > >For example, waitKey(0) will display the window infinitely until > any > keypress (it is suitable for image display). waitKey(25) will display > a > frame and wait approximately 25 ms for a key press (suitable for > displaying a video frame-by-frame). To remove the window, use > cv::destroyWindow. > > I went back to double check and I stand corrected on the "any > keypress" > part. Any keypress on the 'keyboard' does break the wait (as I > incorrectly concluded and assumed only ESC did). > > It is still slightly ambiguous in explaining that when using 25ms, > keypress or not, the wait breaks at 25ms (or before that if you press > a > keyboard key). For my setup the window is stale at that point, no > controls, just a stale frame behind the tkinter window that needs to > be > destroyed or reused. > > Whether that is the exact behavior on all set-ups isn't clear, the > note > further uses the ambiguous phrasing "might". > > >Note: This function should be followed by a call to cv::waitKey or > cv::pollKey to perform GUI housekeeping tasks that are necessary to > actually show the given image and make the window respond to mouse > and > keyboard events. Otherwise, it won’t display the image and the window > might lock up. > > It seems with the several variations, behavior varies between them, > like > one comment saying startWindowThread when using c++ and gtk allows > you > to not use waitKey (not the case here.. it seems -- changing my > language > to not misspeak, lol). > > I haven't come across any examples beyond imshow running stand-alone > as > in my solution suggestion 2. But waitKey does return a keyvalue for > the > keypess to allow extending the functionality, so you can grab it, do > something, and go right back to waiting, I haven't seen any use of > this > though. > > You can also leave out reference to tkinter all together when using > startWindowThread: > > import sys > import cv2 > > cv2.startWindowThread() > cv2.namedWindow("W", cv2.WND_PROP_FULLSCREEN) > cv2.setWindowProperty("W", cv2.WND_PROP_FULLSCREEN, > cv2.WINDOW_FULLSCREEN) > cv2.imshow("W", cv2.imread(sys.argv[1])) > while(1): > a = cv2.waitKey(0) > if a == 27:#ESC > break > #elif a == something else, do something > cv2.destroyAllWindows() > exit() > > But it still blocks if integrated in to the main tkinter thread, and > appears to use tkinter under the hood. And as tkinter is considered > thread-unsafe, the startWindowThread would only be ok when spawned as > a > separate process like the subprocess example. > Thanks for this and your other detailed replies, which I won't go into because your comment above led me to a simple workaround using threading, with a caveat. This may be controversial, but AIUI it's fine to use threads in tkinter as long as you don't touch the same widget from different threads. I do it all the time! So I tried opening and waiting for the window in a thread like this: def window_thread(): cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) cv2.waitKey(0) threading.Thread(target=window_thread, daemon=True).start() This works - the images can be displayed by calling imshow() via tkinter buttons in the main thread, and all the cv2 panning and zooming works too. But the fly in the ointment is that any keypress while the focus is on the cv2 window exits the thread. I think this would apply to your subprocess example too. I tried: - putting the waitKey call in a while loop as in your example above, hoping it would just keep waiting, but the second call to waitKey doesn't respond to keypresses - putting the whole window_thread code in a while loop with a call to destroyAllWindows, hoping that this would re-create the window, but it doesn't - restarting the window thread after waitKey, which has the same results as above and - using a new name for the namedWindow each time In all cases, any subsequent calls to imshow block. I have no idea why. For now it looks like I'll have to tell my users not to touch the keyboard while the image is in focus! Not ideal. If there is another nice fast pythonic way to display an image from a very large array _programatically_, I'd love to know about it. -- John -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On 3/15/23 07:37, John O'Hagan wrote: On Tue, 2023-03-14 at 16:22 -0400, aapost wrote: On 3/14/23 06:54, John O'Hagan wrote: [...] Read an alternative description of the waitKey behavior >For example, waitKey(0) will display the window infinitely until any keypress (it is suitable for image display). waitKey(25) will display a frame and wait approximately 25 ms for a key press (suitable for displaying a video frame-by-frame). To remove the window, use cv::destroyWindow. I went back to double check and I stand corrected on the "any keypress" part. Any keypress on the 'keyboard' does break the wait (as I incorrectly concluded and assumed only ESC did). It is still slightly ambiguous in explaining that when using 25ms, keypress or not, the wait breaks at 25ms (or before that if you press a keyboard key). For my setup the window is stale at that point, no controls, just a stale frame behind the tkinter window that needs to be destroyed or reused. Whether that is the exact behavior on all set-ups isn't clear, the note further uses the ambiguous phrasing "might". >Note: This function should be followed by a call to cv::waitKey or cv::pollKey to perform GUI housekeeping tasks that are necessary to actually show the given image and make the window respond to mouse and keyboard events. Otherwise, it won’t display the image and the window might lock up. It seems with the several variations, behavior varies between them, like one comment saying startWindowThread when using c++ and gtk allows you to not use waitKey (not the case here.. it seems -- changing my language to not misspeak, lol). I haven't come across any examples beyond imshow running stand-alone as in my solution suggestion 2. But waitKey does return a keyvalue for the keypess to allow extending the functionality, so you can grab it, do something, and go right back to waiting, I haven't seen any use of this though. You can also leave out reference to tkinter all together when using startWindowThread: import sys import cv2 cv2.startWindowThread() cv2.namedWindow("W", cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty("W", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) cv2.imshow("W", cv2.imread(sys.argv[1])) while(1): a = cv2.waitKey(0) if a == 27:#ESC break #elif a == something else, do something cv2.destroyAllWindows() exit() But it still blocks if integrated in to the main tkinter thread, and appears to use tkinter under the hood. And as tkinter is considered thread-unsafe, the startWindowThread would only be ok when spawned as a separate process like the subprocess example. Anyway, apologies for the mistake on the any key part. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On 3/15/23 07:37, John O'Hagan wrote: On Tue, 2023-03-14 at 16:22 -0400, aapost wrote: On 3/14/23 06:54, John O'Hagan wrote: Doing a quick read, tkinter is not threadsafe, so diving in to a threading solution is probably not the best approach. But just to throw out another possible solution to see if you can find a "good enough" work around that fits your desired behavior. You could spawn the imshow as it's own program: file2: sp.py import sys import cv2 import tkinter as tk def show(img, root): cv2.namedWindow(str(root), cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty(str(root), cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) cv2.imshow(str(root), cv2.imread(img)) cv2.waitKey(0) cv2.destroyAllWindows() exit() root=tk.Tk() show(sys.argv[1], root) tk.mainloop() file1:main.py import cv2 import tkinter as tk import subprocess images=['c.jpg', 'b.jpg', 'c.jpg'] control = { "counter" : 0, "pid": None } def show(control): if control["pid"]: control["pid"].kill() control["pid"] = subprocess.Popen(["python", "sp.py", images[control["counter"] % len(images)]]) control["counter"] += 1 root=tk.Tk() root.wm_attributes("-topmost", 1) tk.Button(root, text=' Show ', command=lambda: show(control)).pack() tk.mainloop() refactor/design as needed, you track the pid, kill the existing on each subsequent show press. caveats would be that since it is an entirely separate program, if you close the main window, the other window will still linger until it is also closed. You could try to catch the close to run a .kill() on the subprocess if you want right before the exit, etc. But this gives control back to the main GUI since they are now independent of each other and not within the same thread. If they need to talk to each other in some way more than that, I am sure deeper design solutions could be thought up. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On 3/15/23 07:37, John O'Hagan wrote: On Tue, 2023-03-14 at 16:22 -0400, aapost wrote: On 3/14/23 06:54, John O'Hagan wrote: It works up to a point - I can cycle through the images by clicking the button - but if I mouse-click on the displayed image (e.g. to use the zooming and panning features of cv2), nothing happens, and a few seconds later the image greys out and a popup appears saying "'Unknown' is not responding" and giving the option of waiting or forcing close (but sometimes these options are greyed out too). Clicking "wait", if available, closes the popup but it comes back a few seconds later. If I then click on the tkinter window titlebar, the popup changes to "'Tk' is not responding". Clicking on the button still works and after a few clicks the popup closes. [...] I think this particular popup is a Gnome thing, but AIUI most DEs have something similar to detect stuck apps. But the app is not stuck. I suspect this is some kind of interaction between the call to cv2.waitKey (which is necessary but I've never understood why!) and the tkinter event loop, but it's beyond my knowledge. Any suggestions about causes or workarounds? Thanks -- John I don't get any of the zoom/panning behavior with waitKey(1). But a couple notes from the web: https://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html Note This function should be followed by waitKey function which displays the image for specified milliseconds. Otherwise, it won’t display the image. For example, waitKey(0) will display the window infinitely until any keypress (it is suitable for image display). waitKey(25) will display a frame for 25 ms, after which display will be automatically closed. (If you put it in a loop to read videos, it will display the video frame-by-frame) https://pythonexamples.org/python-opencv-imshow/ cv2.waitKey(0) is important for holding the execution of the python program at this statement, so that the image window stays visible. If you do not provide this statement, cv2.imshow() executes in fraction of a second and the program closes all the windows it opened, which makes it almost impossible to see the image on the window. if I change waitKey to 0, I get the ability to zoom/pan, but it places the tk window in a blocked state because it is waiting on cv2 to return. If I hit the ESC key, it releases the wait and gives control back to the tk window, allowing me to press show again to continue to the next image. I can try to change waitKey to a high ms like 1000 and have zoom/pan for that amount of time before it gives control back to tk (not a sensical approach). The fact that you can still see the image after tk takes back control is I believe just a matter of design, some examples show cv2.destroyAllWindows() after waitKey(0) to clean that up, but of course if you are reusing the same window, that destroys the target. You can resolve that if you move cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) to inside the show, and destroy it after the wait, and make waitKey 0, this allows creation/cleanup of that window per image Hitting ESC when done zooming/panning on each image to get back to tk. Thanks for your reply. I'm afraid in the real app it won't be practical to have no gui control while viewing images. But your suggestions have made me realise that my issue has nothing to do with tkinter, it seems to be the way imshow is supposed to work. This code gives the same behaviour described above: cv2.imshow('W', array) cv2.waitKey(100) time.sleep(20) I've seen the docs you mention that say the window will close if no keypress happens within the waitKey time, but that doesn't seem to be what happens as you say. After waitKey returns, the image remains and everything works, but for some reason the desktop complains about an unresponsive app. You can use cv2 to display video with: while 1: frame = camera.read() #pseudocode cv2.imshow('W', frame) cv2.waitKey(1) (In fact this used to work without waitKey if you called cv2.startWindowThread() after creating the window, but that stopped working at some point.) The fact that this works, presumably because the image is being replaced often enough, suggested the following workaround to my problem, using a call to after() to re-display the current image before the desktop starts complaining: images=[cv2.imread(i) for i in ('a.jpg', 'b.jpg', 'c.jpg')] cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) counter=[0] image = [None] def show(): im = images[counter[0] % 3] cv2.imshow('W', im) cv2.waitKey(1) image[:] = [im] counter[0] += 1 root=Tk() root.wm_attributes("-topmost", 1) b=Button(root, text=' Show ', command=show) b.pack() def update(): if image[0] is not None: cv2.imshow('W', image[0]) cv2.w
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On Tue, 2023-03-14 at 16:22 -0400, aapost wrote: > On 3/14/23 06:54, John O'Hagan wrote: [...] > > > > Here is minimal code that demonstrates the problem in the subject > > line: > > > > import cv2 > > from tkinter import * > > > > images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths > > > > cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) > > cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, > > cv2.WINDOW_FULLSCREEN) > > counter=[0] > > def show(): > > cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) > > cv2.waitKey(1) > > counter[0] += 1 > > > > root=Tk() > > root.wm_attributes("-topmost", 1) > > Button(root, text=' Show ', command=show).pack() > > mainloop() > > > > It works up to a point - I can cycle through the images by clicking > > the > > button - but if I mouse-click on the displayed image (e.g. to use > > the > > zooming and panning features of cv2), nothing happens, and a few > > seconds later the image greys out and a popup appears saying > > "'Unknown' > > is not responding" and giving the option of waiting or forcing > > close > > (but sometimes these options are greyed out too). Clicking "wait", > > if > > available, closes the popup but it comes back a few seconds later. > > If I > > then click on the tkinter window titlebar, the popup changes > > to "'Tk' > > is not responding". Clicking on the button still works and after a > > few > > clicks the popup closes. [...] > > I think this particular popup is a Gnome thing, but AIUI most DEs > > have > > something similar to detect stuck apps. But the app is not stuck. > > > > I suspect this is some kind of interaction between the call to > > cv2.waitKey (which is necessary but I've never understood why!) and > > the > > tkinter event loop, but it's beyond my knowledge. > > > > Any suggestions about causes or workarounds? > > > > Thanks > > > > -- > > > > John > > > > > > > I don't get any of the zoom/panning behavior with waitKey(1). But a > couple notes from the web: > > > https://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html > > Note > > This function should be followed by waitKey function which displays > the > image for specified milliseconds. Otherwise, it won’t display the > image. > For example, waitKey(0) will display the window infinitely until any > keypress (it is suitable for image display). waitKey(25) will display > a > frame for 25 ms, after which display will be automatically closed. > (If > you put it in a loop to read videos, it will display the video > frame-by-frame) > > https://pythonexamples.org/python-opencv-imshow/ > > cv2.waitKey(0) is important for holding the execution of the python > program at this statement, so that the image window stays visible. If > you do not provide this statement, cv2.imshow() executes in fraction > of > a second and the program closes all the windows it opened, which > makes > it almost impossible to see the image on the window. > > if I change waitKey to 0, I get the ability to zoom/pan, but it > places > the tk window in a blocked state because it is waiting on cv2 to > return. > If I hit the ESC key, it releases the wait and gives control back to > the > tk window, allowing me to press show again to continue to the next > image. > > I can try to change waitKey to a high ms like 1000 and have > zoom/pan > for that amount of time before it gives control back to tk (not a > sensical approach). > > The fact that you can still see the image after tk takes back control > is > I believe just a matter of design, some examples show > cv2.destroyAllWindows() after waitKey(0) to clean that up, but of > course > if you are reusing the same window, that destroys the target. > > You can resolve that if you move > cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) > cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, > cv2.WINDOW_FULLSCREEN) > > to inside the show, and destroy it after the wait, and make waitKey > 0, > this allows creation/cleanup of that window per image > > Hitting ESC when done zooming/panning on each image to get back to > tk. Thanks for your reply. I'm afraid in the real app it won't be practical to have no gui control while viewing images. But your suggestions have made me realise that my issue has nothing to do with tkinter, it seems to be the way imshow is supposed to work. This code gives the same be
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On 3/14/23 06:54, John O'Hagan wrote: Hi list I'm trying to use cv2 to display images created as numpy arrays, from within a tkinter app (which does other things with the arrays before they are displayed as images). The arrays are colour-coded visualisations of genomes and can be over a billion elements in size, and I've found the PIL methods to display images in tkinter are too slow and memory-heavy. Here is minimal code that demonstrates the problem in the subject line: import cv2 from tkinter import * images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) counter=[0] def show(): cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) cv2.waitKey(1) counter[0] += 1 root=Tk() root.wm_attributes("-topmost", 1) Button(root, text=' Show ', command=show).pack() mainloop() It works up to a point - I can cycle through the images by clicking the button - but if I mouse-click on the displayed image (e.g. to use the zooming and panning features of cv2), nothing happens, and a few seconds later the image greys out and a popup appears saying "'Unknown' is not responding" and giving the option of waiting or forcing close (but sometimes these options are greyed out too). Clicking "wait", if available, closes the popup but it comes back a few seconds later. If I then click on the tkinter window titlebar, the popup changes to "'Tk' is not responding". Clicking on the button still works and after a few clicks the popup closes. This happens under both x11 and wayland, but under wayland, I also get this error: "QSocketNotifier: Can only be used with threads started with QThread qt.qpa.wayland: Wayland does not support QWindow::requestActivate()" and only every second button press displays a new image ,with only every second image displayed. I think this particular popup is a Gnome thing, but AIUI most DEs have something similar to detect stuck apps. But the app is not stuck. I suspect this is some kind of interaction between the call to cv2.waitKey (which is necessary but I've never understood why!) and the tkinter event loop, but it's beyond my knowledge. Any suggestions about causes or workarounds? Thanks -- John I don't get any of the zoom/panning behavior with waitKey(1). But a couple notes from the web: https://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html Note This function should be followed by waitKey function which displays the image for specified milliseconds. Otherwise, it won’t display the image. For example, waitKey(0) will display the window infinitely until any keypress (it is suitable for image display). waitKey(25) will display a frame for 25 ms, after which display will be automatically closed. (If you put it in a loop to read videos, it will display the video frame-by-frame) https://pythonexamples.org/python-opencv-imshow/ cv2.waitKey(0) is important for holding the execution of the python program at this statement, so that the image window stays visible. If you do not provide this statement, cv2.imshow() executes in fraction of a second and the program closes all the windows it opened, which makes it almost impossible to see the image on the window. if I change waitKey to 0, I get the ability to zoom/pan, but it places the tk window in a blocked state because it is waiting on cv2 to return. If I hit the ESC key, it releases the wait and gives control back to the tk window, allowing me to press show again to continue to the next image. I can try to change waitKey to a high ms like 1000 and have zoom/pan for that amount of time before it gives control back to tk (not a sensical approach). The fact that you can still see the image after tk takes back control is I believe just a matter of design, some examples show cv2.destroyAllWindows() after waitKey(0) to clean that up, but of course if you are reusing the same window, that destroys the target. You can resolve that if you move cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) to inside the show, and destroy it after the wait, and make waitKey 0, this allows creation/cleanup of that window per image Hitting ESC when done zooming/panning on each image to get back to tk. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On Tue, 2023-03-14 at 13:52 +, Weatherby,Gerard wrote: > Assuming you’re using opencv-python, I’d post query at > https://github.com/opencv/opencv-python/issues. Thanks Gerard I'm using the python3-opencv package from Debian testing. Is that github the appropriate place for this query? Thanks -- John > -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On Tue, 2023-03-14 at 08:07 -0400, Thomas Passin wrote: > On 3/14/2023 6:54 AM, John O'Hagan wrote: > > Hi list > > > > I'm trying to use cv2 to display images created as numpy arrays, > > from > > within a tkinter app (which does other things with the arrays > > before > > they are displayed as images). The arrays are colour-coded > > visualisations of genomes and can be over a billion elements in > > size, > > and I've found the PIL methods to display images in tkinter are too > > slow and memory-heavy. > > > > Here is minimal code that demonstrates the problem in the subject > > line: > > > > import cv2 > > from tkinter import * > > > > images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths > > > > cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) > > cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, > > cv2.WINDOW_FULLSCREEN) > > counter=[0] > > def show(): > > cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) > > cv2.waitKey(1) > > counter[0] += 1 > > > > root=Tk() > > root.wm_attributes("-topmost", 1) > > Button(root, text=' Show ', command=show).pack() > > mainloop() > > > > It works up to a point - I can cycle through the images by clicking > > the > > button - but if I mouse-click on the displayed image (e.g. to use > > the > > zooming and panning features of cv2), nothing happens, and a few > > seconds later the image greys out and a popup appears saying > > "'Unknown' > > is not responding" and giving the option of waiting or forcing > > close > > (but sometimes these options are greyed out too). Clicking "wait", > > if > > available, closes the popup but it comes back a few seconds later. > > If I > > then click on the tkinter window titlebar, the popup changes > > to "'Tk' > > is not responding". Clicking on the button still works and after a > > few > > clicks the popup closes. [...] > I don't know anything about the specifics here, but with billions of > elements you will not be able to show more than a small fraction on > the > screen. Hi Thomas Thanks for your reply. In the real app I use interpolating methods to fit the whole image on the screen. In cv2: cv2.imshow('W', cv2.resize(array, (width, height)) It's very quick, fractions of a second even for a billion+ sized array. The PIL/Tk equivalent: im = ImageTk.PhotoImage(Image.fromarray(array).resize((width, height))) canvas.create_image(width/2, height/2, image=im) did the same thing but was very, very slow for such large arrays (15 minutes or more per image, with memory heavily swapped out). Having said all that, the specific problem I'm having isn't related to the size of the arrays. The code I posted above triggers the problem even with small images. > So I think that a progressive disclosure approach would pay > off. Sample the arrays down to a more workable size before creating > the > screen images. If you want to zoom in, resample them and recreate > new > images that only cover the zoomed in region in more detail. > > It would also be useful to cache the generated images so they can be > re-displayed without needing to be regenerated each time. This is exactly the approach I took in the first draft (except the caching idea)! I wasn't using interpolating methods and was limited to a minimum of one pixel per array element, and therefore limited in how much of the array could be displayed. Even this got pretty slow in tkinter if fully zoomed out, although the caching would have helped with that. But the project brief requires the whole genome to be visible by default. Thanks -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
Assuming you’re using opencv-python, I’d post query at https://github.com/opencv/opencv-python/issues. From: Python-list on behalf of John O'Hagan Date: Tuesday, March 14, 2023 at 6:56 AM To: Python list Subject: Tkinter and cv2: "not responding" popup when imshow launched from tk app *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. *** Hi list I'm trying to use cv2 to display images created as numpy arrays, from within a tkinter app (which does other things with the arrays before they are displayed as images). The arrays are colour-coded visualisations of genomes and can be over a billion elements in size, and I've found the PIL methods to display images in tkinter are too slow and memory-heavy. Here is minimal code that demonstrates the problem in the subject line: import cv2 from tkinter import * images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) counter=[0] def show(): cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) cv2.waitKey(1) counter[0] += 1 root=Tk() root.wm_attributes("-topmost", 1) Button(root, text=' Show ', command=show).pack() mainloop() It works up to a point - I can cycle through the images by clicking the button - but if I mouse-click on the displayed image (e.g. to use the zooming and panning features of cv2), nothing happens, and a few seconds later the image greys out and a popup appears saying "'Unknown' is not responding" and giving the option of waiting or forcing close (but sometimes these options are greyed out too). Clicking "wait", if available, closes the popup but it comes back a few seconds later. If I then click on the tkinter window titlebar, the popup changes to "'Tk' is not responding". Clicking on the button still works and after a few clicks the popup closes. This happens under both x11 and wayland, but under wayland, I also get this error: "QSocketNotifier: Can only be used with threads started with QThread qt.qpa.wayland: Wayland does not support QWindow::requestActivate()" and only every second button press displays a new image ,with only every second image displayed. I think this particular popup is a Gnome thing, but AIUI most DEs have something similar to detect stuck apps. But the app is not stuck. I suspect this is some kind of interaction between the call to cv2.waitKey (which is necessary but I've never understood why!) and the tkinter event loop, but it's beyond my knowledge. Any suggestions about causes or workarounds? Thanks -- John -- https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iHFg1AtgcwsfEeHXaH_Nasebf9SGreVlDs-DevEIQbFiwUQThx-_rah1QkSHRJEotJFyd-d6OCQ3GuQa1MxvsnGA$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iHFg1AtgcwsfEeHXaH_Nasebf9SGreVlDs-DevEIQbFiwUQThx-_rah1QkSHRJEotJFyd-d6OCQ3GuQa1MxvsnGA$> -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter and cv2: "not responding" popup when imshow launched from tk app
On 3/14/2023 6:54 AM, John O'Hagan wrote: Hi list I'm trying to use cv2 to display images created as numpy arrays, from within a tkinter app (which does other things with the arrays before they are displayed as images). The arrays are colour-coded visualisations of genomes and can be over a billion elements in size, and I've found the PIL methods to display images in tkinter are too slow and memory-heavy. Here is minimal code that demonstrates the problem in the subject line: import cv2 from tkinter import * images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) counter=[0] def show(): cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) cv2.waitKey(1) counter[0] += 1 root=Tk() root.wm_attributes("-topmost", 1) Button(root, text=' Show ', command=show).pack() mainloop() It works up to a point - I can cycle through the images by clicking the button - but if I mouse-click on the displayed image (e.g. to use the zooming and panning features of cv2), nothing happens, and a few seconds later the image greys out and a popup appears saying "'Unknown' is not responding" and giving the option of waiting or forcing close (but sometimes these options are greyed out too). Clicking "wait", if available, closes the popup but it comes back a few seconds later. If I then click on the tkinter window titlebar, the popup changes to "'Tk' is not responding". Clicking on the button still works and after a few clicks the popup closes. This happens under both x11 and wayland, but under wayland, I also get this error: "QSocketNotifier: Can only be used with threads started with QThread qt.qpa.wayland: Wayland does not support QWindow::requestActivate()" and only every second button press displays a new image ,with only every second image displayed. I think this particular popup is a Gnome thing, but AIUI most DEs have something similar to detect stuck apps. But the app is not stuck. I suspect this is some kind of interaction between the call to cv2.waitKey (which is necessary but I've never understood why!) and the tkinter event loop, but it's beyond my knowledge. Any suggestions about causes or workarounds? I don't know anything about the specifics here, but with billions of elements you will not be able to show more than a small fraction on the screen. So I think that a progressive disclosure approach would pay off. Sample the arrays down to a more workable size before creating the screen images. If you want to zoom in, resample them and recreate new images that only cover the zoomed in region in more detail. It would also be useful to cache the generated images so they can be re-displayed without needing to be regenerated each time. -- https://mail.python.org/mailman/listinfo/python-list
Tkinter and cv2: "not responding" popup when imshow launched from tk app
Hi list I'm trying to use cv2 to display images created as numpy arrays, from within a tkinter app (which does other things with the arrays before they are displayed as images). The arrays are colour-coded visualisations of genomes and can be over a billion elements in size, and I've found the PIL methods to display images in tkinter are too slow and memory-heavy. Here is minimal code that demonstrates the problem in the subject line: import cv2 from tkinter import * images=['a.jpg', 'b.jpg', 'c.jpg'] #change to image paths cv2.namedWindow('W', cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty('W', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) counter=[0] def show(): cv2.imshow('W', cv2.imread(images[counter[0] % len(images)])) cv2.waitKey(1) counter[0] += 1 root=Tk() root.wm_attributes("-topmost", 1) Button(root, text=' Show ', command=show).pack() mainloop() It works up to a point - I can cycle through the images by clicking the button - but if I mouse-click on the displayed image (e.g. to use the zooming and panning features of cv2), nothing happens, and a few seconds later the image greys out and a popup appears saying "'Unknown' is not responding" and giving the option of waiting or forcing close (but sometimes these options are greyed out too). Clicking "wait", if available, closes the popup but it comes back a few seconds later. If I then click on the tkinter window titlebar, the popup changes to "'Tk' is not responding". Clicking on the button still works and after a few clicks the popup closes. This happens under both x11 and wayland, but under wayland, I also get this error: "QSocketNotifier: Can only be used with threads started with QThread qt.qpa.wayland: Wayland does not support QWindow::requestActivate()" and only every second button press displays a new image ,with only every second image displayed. I think this particular popup is a Gnome thing, but AIUI most DEs have something similar to detect stuck apps. But the app is not stuck. I suspect this is some kind of interaction between the call to cv2.waitKey (which is necessary but I've never understood why!) and the tkinter event loop, but it's beyond my knowledge. Any suggestions about causes or workarounds? Thanks -- John -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
Il 12/02/23 12:10, John O'Hagan ha scritto: > My goal was to be able to change the colour of an individual item > regardless of whether it is selected or not. To do that, it is > necessary to be able to change the colour of an individual selected > item, without changing the selection or changing the colour of other > selected items. It seems this isn't possible. ok sorry. As another alternative I had thought of this: from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() style = Style() styleDefault = (style.map("Treeview")) def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) itemselected = t.selection() for x in itemselected: if (x == 'item1'): style.configure('Treeview', selectbackground='red') style.map('Treeview', background=[('disabled', 'white')], foreground=[('disabled', 'red')]) else: style.map('Treeview', background=[('selected', styleDefault['background'][1][1])], foreground=[('selected', styleDefault['background'][0][1])]) flash() mainloop() Maybe it can be useful for other situations. Bye bye -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
On Sun, 2023-02-12 at 08:59 -0500, Thomas Passin wrote: [...] > On 2/12/2023 6:10 AM, John O'Hagan wrote: [...] > > > > My goal was to be able to change the colour of an individual item > > regardless of whether it is selected or not. To do that, it is > > necessary to be able to change the colour of an individual selected > > item, without changing the selection or changing the colour of > > other > > selected items. It seems this isn't possible. > > I haven't worked with ttk objects or Treeviews, but judging from old > style objects, I think you have to re-apply your color and flashing > when > the item becomes selected and possibly again when it becomes > unselected. > > Depending on exactly what effect you want, you may also need to apply > color and flashing when the mouse moves over the item and again when > it > leaves. When I make changes in e.g. color, I like to save the > previous > value(s) in the object itself. That way I can easily restore say a > background color without having to work out what it used to be, which > may be some color that Tk applies based on the desktop theme and who > know what else. > > Here's an example (simplified) for changing color on mouse hover and > leave events: > > BG_KEY = 'bg' if platform.lower().startswith('win') \ > else 'activebackground' # Different for Linux! > > def on_enter(event): > w = event.widget > w.old_bg = w.cget('bg') > w[BG_KEY] = BUTTON_HOVER # Color you have chosen > > def on_leave(event): > w = event.widget > _bg = w.old_bg > w[BG_KEY] = _bg > > Thank you again for your reply, Thomas. I didn't know tkinter configuration keys have different names on different platforms, that seems unneccesary! I also like the idea of storing the original settings on the object itself. However, because of the nature of ttk widgets, I think I'm stuck with my original issue. Unlike classic tkinter widgets, a lot of the ttk configuration options are not available on individual widgets, but must be done through styles or tags. On Treeviews (and possibly other ttk widgets), the colours for selected items can only be set using style.map (AFAIK). The colours for individual items can (only?) be set using tags, but this is evidently overridden when the item is selected by the selection colour dictated by the style. Treeview tags do not have a 'selectbackground' option like many tkinter widgets do. (Fonts _can_ be set this way, so I could flash, say, the font size, but that's ugly!) As as aside, IMO ttk looks great (and Treeview is really useful) but this approach to configuration is a double-edged sword. On one hand it's super-easy to change the whole look, but on the other, it can be overly restrictive if you want to control the look of individual widgets. I might try to put forward a feature request to add a 'selectbackground' option to ttk tags to see if there's any interest. Thanks -- John -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
On 2/12/2023 6:10 AM, John O'Hagan wrote: On Mon, 2023-02-06 at 10:19 -0800, stefalem wrote: Il giorno sabato 4 febbraio 2023 alle 11:43:29 UTC+1 John O'Hagan ha scritto: ... Is there another way to do what I want? from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) itemselected = t.selection() for x in itemselected: if (x == 'item1'): t.selection_remove(t.get_children()) flash() Thank you for your reply. Unfortunately that's not quite what I'm after, because it unselects the flashing item. My goal was to be able to change the colour of an individual item regardless of whether it is selected or not. To do that, it is necessary to be able to change the colour of an individual selected item, without changing the selection or changing the colour of other selected items. It seems this isn't possible. I haven't worked with ttk objects or Treeviews, but judging from old style objects, I think you have to re-apply your color and flashing when the item becomes selected and possibly again when it becomes unselected. Depending on exactly what effect you want, you may also need to apply color and flashing when the mouse moves over the item and again when it leaves. When I make changes in e.g. color, I like to save the previous value(s) in the object itself. That way I can easily restore say a background color without having to work out what it used to be, which may be some color that Tk applies based on the desktop theme and who know what else. Here's an example (simplified) for changing color on mouse hover and leave events: BG_KEY = 'bg' if platform.lower().startswith('win') \ else 'activebackground' # Different for Linux! def on_enter(event): w = event.widget w.old_bg = w.cget('bg') w[BG_KEY] = BUTTON_HOVER # Color you have chosen def on_leave(event): w = event.widget _bg = w.old_bg w[BG_KEY] = _bg -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
On Mon, 2023-02-06 at 10:19 -0800, stefalem wrote: > Il giorno sabato 4 febbraio 2023 alle 11:43:29 UTC+1 John O'Hagan ha > scritto: > ... > > > Is there another way to do what I want? > > from tkinter import * > from tkinter.ttk import * > > root = Tk() > t = Treeview(root) > > t.insert('', 0, iid='item1', text='item1') > t.insert('', 1, text='item2') > t.tag_configure('flashtag', background='red') > t.pack() > > def flash(): > tags = t.item('item1', 'tags') > t.item('item1', tags='' if tags else 'flashtag') > t.after(500, flash) > itemselected = t.selection() > for x in itemselected: > if (x == 'item1'): > t.selection_remove(t.get_children()) > > flash() Thank you for your reply. Unfortunately that's not quite what I'm after, because it unselects the flashing item. My goal was to be able to change the colour of an individual item regardless of whether it is selected or not. To do that, it is necessary to be able to change the colour of an individual selected item, without changing the selection or changing the colour of other selected items. It seems this isn't possible. Thanks John -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
I apologize for the 3 messages sent, I could not access the usual news server and with Google Groups I messed up :) -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
> Is there another way to do what I want? try this: from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) itemselected = t.selection() for x in itemselected: if (x == 'item1'): t.selection_remove(t.get_children()) flash() mainloop() -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
Il giorno sabato 4 febbraio 2023 alle 11:43:29 UTC+1 John O'Hagan ha scritto: ... > Is there another way to do what I want? from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) itemselected = t.selection() for x in itemselected: if (x == 'item1'): t.selection_remove(t.get_children()) flash() > Thanks > > -- > > John -- https://mail.python.org/mailman/listinfo/python-list
Re: tkinter ttk.Treeview: changing background colour of single item when selected
I haven't worked specifically with a Treeview, but I think you need to detect the onClick event (or an onSelect event if there is one) and have that trigger the flashing. Otherwise the selection probably overwrites styling that you added. That's what I do for classic Tk buttons to make them flash when selected. (I only flash once, though; I don't keep them flashing). On 2/4/2023 5:42 AM, John O'Hagan wrote: Hi list I'm using a ttk Treeview to display a hierarchical data structure. When an error condition arises in a node, I want the corresponding item in the Treeview to flash its background color. Using a tag to flash the item background works, except when the item is selected, when the tag has no effect. I want the item to keep flashing even when selected. The code below is a minimal example of the issue. It displays a Treeview containing two items with the first one flashing. If you select it, you don't see the flashing anymore. from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) flash() mainloop() Other than tags, the only other way I've found to dynamically change Treeview backgrounds is using styles, in particular Style.map to configure the background of a selected item, but they apply to all items in the Treeview and would flash all selected items, not just the one I want to keep flashing. Is there another way to do what I want? Thanks -- John -- https://mail.python.org/mailman/listinfo/python-list
tkinter ttk.Treeview: changing background colour of single item when selected
Hi list I'm using a ttk Treeview to display a hierarchical data structure. When an error condition arises in a node, I want the corresponding item in the Treeview to flash its background color. Using a tag to flash the item background works, except when the item is selected, when the tag has no effect. I want the item to keep flashing even when selected. The code below is a minimal example of the issue. It displays a Treeview containing two items with the first one flashing. If you select it, you don't see the flashing anymore. from tkinter import * from tkinter.ttk import * root = Tk() t = Treeview(root) t.insert('', 0, iid='item1', text='item1') t.insert('', 1, text='item2') t.tag_configure('flashtag', background='red') t.pack() def flash(): tags = t.item('item1', 'tags') t.item('item1', tags='' if tags else 'flashtag') t.after(500, flash) flash() mainloop() Other than tags, the only other way I've found to dynamically change Treeview backgrounds is using styles, in particular Style.map to configure the background of a selected item, but they apply to all items in the Treeview and would flash all selected items, not just the one I want to keep flashing. Is there another way to do what I want? Thanks -- John -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
On 1/19/2023 10:21 AM, Dan Kolis wrote: Hello ! Works fine on my work machine. (Ubuntu 20.04 / 32 G / 32 CPUS). Scalene (https://github.com/plasma-umass/scalene) shows it using 9 MB of memory. I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. Thanks a lot These reports are very helpful ! I seemed to have 'fixed it' by changing one line, really. I used: # Do each thing ..for aWs in workWsL: aWs.update() TO: # Do each thing ..for aWs in workWsL: aWs.update_idletasks() I was going to suggest update_idletasks(), but I forgot to scan your code to see it it was already being done. Dan says: Thanks a lot ! This helps me visualise this is managed as a problem in a technical sense. I mean, there is always a requirement for real integration testing of all sorts for an attempt to release a program on a larger scale. Now I know it works without stopping on 4 computers. Better then yesterday hugely. Thank you. Regs Daniel B. Kolis my ref: nafl, 19 Jan 2023, https://groups.google.com/g/comp.lang.python/c/FNlXg0Od39o/m/9stiUtLSAQAJ -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
Hello ! > Works fine on my work machine. (Ubuntu 20.04 / 32 G / 32 CPUS). Scalene > (https://github.com/plasma-umass/scalene) shows it using 9 MB of memory. > I ran your test program here and it generates 25 windows on my machine, > and I can click "run" at least half a dozen times. I tried closing the > font windows before clicking run again, and also just leaving the > windows up and generating many more windows. 300 windows. No hangs here > at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. Thanks a lot These reports are very helpful ! I seemed to have 'fixed it' by changing one line, really. I used: # Do each thing ..for aWs in workWsL: aWs.update() TO: # Do each thing ..for aWs in workWsL: aWs.update_idletasks() Dan says: Thanks a lot ! This helps me visualise this is managed as a problem in a technical sense. I mean, there is always a requirement for real integration testing of all sorts for an attempt to release a program on a larger scale. Now I know it works without stopping on 4 computers. Better then yesterday hugely. Thank you. Regs Daniel B. Kolis my ref: nafl, 19 Jan 2023, https://groups.google.com/g/comp.lang.python/c/FNlXg0Od39o/m/9stiUtLSAQAJ -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
Works through 20 presses of the "go" button on a Linux Mint VM. Because of limited RAM allocated for the VM, after some iterations the program slowed down because the VM had to start using swap memory. But there did not seem to be any glitches or failures. Python 3.9.5 Linux Mint 20 Ulyana /Cinnamon 3.07 GB Linux kernel 5.4.0-137-generic tk: 0.1.0 On 1/19/2023 10:06 AM, Thomas Passin wrote: Works fine through 10 "go" button presses on my Windows 10 machine. You might want to run pylint and pyflakes on it On 1/19/2023 7:34 AM, Weatherby,Gerard wrote: Works fine on my work machine. (Ubuntu 20.04 / 32 G / 32 CPUS). Scalene (https://github.com/plasma-umass/scalene) shows it using 9 MB of memory. From: Python-list on behalf of Michael Torrie Date: Wednesday, January 18, 2023 at 8:58 PM To: python-list@python.org Subject: Re: A natural magnet for the craziest TKinter lovers out there *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. *** On 1/18/23 18:01, Dan Kolis wrote: Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under Ubuntu starts it up again. Click go rewrites al the fonts the thing can find in a few windows Repeated. Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. -- https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$> -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
Works fine through 10 "go" button presses on my Windows 10 machine. You might want to run pylint and pyflakes on it On 1/19/2023 7:34 AM, Weatherby,Gerard wrote: Works fine on my work machine. (Ubuntu 20.04 / 32 G / 32 CPUS). Scalene (https://github.com/plasma-umass/scalene) shows it using 9 MB of memory. From: Python-list on behalf of Michael Torrie Date: Wednesday, January 18, 2023 at 8:58 PM To: python-list@python.org Subject: Re: A natural magnet for the craziest TKinter lovers out there *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. *** On 1/18/23 18:01, Dan Kolis wrote: Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under Ubuntu starts it up again. Click go rewrites al the fonts the thing can find in a few windows Repeated. Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. -- https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$> -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
Works fine on my work machine. (Ubuntu 20.04 / 32 G / 32 CPUS). Scalene (https://github.com/plasma-umass/scalene) shows it using 9 MB of memory. From: Python-list on behalf of Michael Torrie Date: Wednesday, January 18, 2023 at 8:58 PM To: python-list@python.org Subject: Re: A natural magnet for the craziest TKinter lovers out there *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. *** On 1/18/23 18:01, Dan Kolis wrote: > Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under > Ubuntu starts it up again. Click go rewrites al the fonts the thing can find > in a few windows Repeated. > Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. -- https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iGQaGdd9t2QPVQJDhyDTQmXgCwx4YG7m8jFbRd11dF1BweJHCd0wC4UyZUfQGQjqxeulMYagnDqInfA81A$> -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
On 1/18/2023 11:46 PM, Thomas Passin wrote: On 1/18/2023 8:56 PM, Michael Torrie wrote: On 1/18/23 18:01, Dan Kolis wrote: Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under Ubuntu starts it up again. Click go rewrites al the fonts the thing can find in a few windows Repeated. Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. It could be using up some system resource. tk could have some memory or resource leak, possibly specific to the OP's machine. Try looking at system memory with the system monitor as the program goes through its paces. Maybe you will notice something suspicious. Also reduce the number of windows that get opened to a small number. If there are no freezes, increase the number little by little. This may give you some bounds on what's going on, or at least let your ultimate program work by keeping the resource use under control. -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
On 1/18/2023 8:56 PM, Michael Torrie wrote: On 1/18/23 18:01, Dan Kolis wrote: Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under Ubuntu starts it up again. Click go rewrites al the fonts the thing can find in a few windows Repeated. Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. It could be using up some system resource. tk could have some memory or resource leak, possibly specific to the OP's machine. Try looking at system memory with the system monitor as the program goes through its paces. Maybe you will notice something suspicious. -- https://mail.python.org/mailman/listinfo/python-list
Re: A natural magnet for the craziest TKinter lovers out there
On 1/18/23 18:01, Dan Kolis wrote: > Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under > Ubuntu starts it up again. Click go rewrites al the fonts the thing can find > in a few windows Repeated. > Not sure what you mean by "screen rewrites." I ran your test program here and it generates 25 windows on my machine, and I can click "run" at least half a dozen times. I tried closing the font windows before clicking run again, and also just leaving the windows up and generating many more windows. 300 windows. No hangs here at all. Fedora 35 with Mate Desktop on X11 with compositing enabled. -- https://mail.python.org/mailman/listinfo/python-list
A natural magnet for the craziest TKinter lovers out there
Hangs after maybe between 4 and 50 screen rewrites. sometimes CTRL C under Ubuntu starts it up again. Click go rewrites al the fonts the thing can find in a few windows Repeated. TKinter has a cult following. I don''t really expect others to fix my problems, but you know, es since its a cult thing to love TCL ( or something ) Here is is. Same on two different computers in Python 3.6 and 3.8 Plus I suppose you get to see for sure all your finest fonts as rendered in a real TK thing, not that this changes the worlds so much. Thanks for the advice so far... Regards, Dan Kolis # Code version 18Jan2023 19:48 EST Dan Kolis # Click 'go' on main page. when run over and over after a while it freezes import tkinter as tk from tkinter import ttk from tkinter import fontas luFont # Empty object maker ( M T ) ... get it say it ! class MT(): pass # Module level variables mod = MT() mod.itsPlaces = MT() mod.itsPlaces = [] # Apply XY Size to things like windows, variable place 31Jul22 def apply_Width_Height_Position( toThis, aWidth, aHeight, *argsPlace ): # Width and height is expected # Argument overflow is quite variable size is it its usual hint for me aLen = len( argsPlace ) # Sometimes, just width and height are given ( not that + position ) wAndH = str( int( aWidth ) ) +'x' + str( int( aHeight ) ) # Size has a funny text line interface toThis.geometry( wAndH ) # Apply # Sometimes position too if aLen == 2: eP = "+" + str( argsPlace[ 0 ] ) + "+" + str( argsPlace[ 1 ] ) param4 = wAndH + eP # Combine size and position toThis.geometry( param4 ) # Apply jj = 560 # Create local toplevel to whoever calls me 11Dec22 bc-endive def make_Tk_Window( sReason, *attribKc ): # Top level window maker and rememberer # Kc = 'Kind code' aCode = "na" # Not available if attribKc: aCode = attribKc [ 0 ] # Better code then 'na' # Make window ansWin = tk.Toplevel() # Keep track of this creation step newEntry = {} newEntry[ 'tkaddress' ] = ansWin # Real TK window accessor newEntry[ 'ideanamed' ] = sReason # Casual description newEntry[ 'kindcode' ] = aCode # So can be worked with together mod.itsPlaces.append( newEntry ) return ansWin # Idle time rewrite def justRedisplayNow( wThings, *argsR ): # Redisplay a named tj thing # Dont use this frivolously, if it's needed its here you have to study it wThings.update() # Look at fonts possible 6Oct22 def showAllFonts(): # Show fonts possible mod.lines_In_Window = 30; mod.window_Seq_Number = 1 # What we want to see mod.seeFonts = list( luFont.families() ) mod.seeFonts.sort() # Alpha order is nice # Fill windows as a look at me report try: populateW() except: tt = 456 rr = 245 # Show fonts regarding avoiding BAD ones that crash, etc size limits in buffers too 19Dec22 def populateW(): # Put in the fonts aLen = len( mod.seeFonts ) # Fun to know, debug really last_considered_name = "gghfjhljfl" # Don't show doubles # Loop through all fonts the system named thisPassMakeWindow = True; a_Line_Count = 0; list_Number = 0 for item in mod.seeFonts: # Multiple windows ( Python has funny ideas on this, ok like this ) if thisPassMakeWindow: winTk_Now = winMakerFontsW(); thisPassMakeWindow = False; a_Line_Count = 0 # We gots one now if a_Line_Count < mod.lines_In_Window: # Will a window we made list_Number += 1 # Counts aN = str( list_Number ) + " "; name_In_lower = item.lower() # Various reasons to not render this one isOk = True if name_In_lower == last_considered_name: isOk = False a_Bad_Thing = name_In_lower.find( 'emoji' ) > -1 if a_Bad_Thing: isOk = False a_Bad_Thing = item.find( 'Noto Sans Mono CJK' ) > -1 if a_Bad_Thing: isOk = False # Good good if i
Re: Tkinter GUI freezing, used Thread then encountered RuntimeError: threads can only be started once
On 2023-01-11 00:13, Cameron Simpson wrote: On 10Jan2023 18:32, MRAB wrote: I don't like how you're passing Thread...start as an argument. IMHO, it would be better/cleaner to pass a plain function, even if the only thing that function does is to start the thread. Yes, and this is likely the thing causing the cited exception "threads can only be started once". Your setup of the button with the action defined as: Thread().start creates a _single_ new Thread _when you define the button_, and makes hte button callback try to start it. On the second and following callback, you're trying to start the _same_ single Thread again. You're right! I missed that detail. :-( Do as MRAB suggests and have the callback create-and-start a Thread instead of just starting an _existing_ Thread. Also, for simple quick things there's no need to use a Thread at all. If the final version of the programme is going to do something long running at that point, then sure. I can't tell what 'change_flag' is doing because of the formatting issue. Is it doing GUI stuff? In a thread? If yes, don't do that. The GUI doesn't like that. Only the main thread should do GUI stuff. Aye. This is very important in almost all GUI toolkits. Bit me very badly with Qt once, badly in that the segfaults (yes! segfaults! in a Python app!) were erratic and very timing dependent, making them hard to reproduce and understand. It wasn't until I _realised_ it was thread/concurrency related that I could fix it. Note that in Tk you can have a callback do GUI work, just not in a separate thread. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter GUI freezing, used Thread then encountered RuntimeError: threads can only be started once
On 10Jan2023 18:32, MRAB wrote: I don't like how you're passing Thread...start as an argument. IMHO, it would be better/cleaner to pass a plain function, even if the only thing that function does is to start the thread. Yes, and this is likely the thing causing the cited exception "threads can only be started once". Your setup of the button with the action defined as: Thread().start creates a _single_ new Thread _when you define the button_, and makes hte button callback try to start it. On the second and following callback, you're trying to start the _same_ single Thread again. Do as MRAB suggests and have the callback create-and-start a Thread instead of just starting an _existing_ Thread. Also, for simple quick things there's no need to use a Thread at all. If the final version of the programme is going to do something long running at that point, then sure. I can't tell what 'change_flag' is doing because of the formatting issue. Is it doing GUI stuff? In a thread? If yes, don't do that. The GUI doesn't like that. Only the main thread should do GUI stuff. Aye. This is very important in almost all GUI toolkits. Bit me very badly with Qt once, badly in that the segfaults (yes! segfaults! in a Python app!) were erratic and very timing dependent, making them hard to reproduce and understand. It wasn't until I _realised_ it was thread/concurrency related that I could fix it. Note that in Tk you can have a callback do GUI work, just not in a separate thread. Cheers, Cameron Simpson -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter GUI freezing, used Thread then encountered RuntimeError: threads can only be started once
On 2023-01-10 14:57, Abhay Singh wrote: Here is the entire code snippet of the same. Please help def change_flag(top_frame, bottom_frame, button1, button2, button3, button4, controller): global counter, canvas, my_image, chosen, flag, directory canvas.delete('all') button5['state'] = DISABLED counter += 1 chosen, options_text = function_options() right_answer_flag = get_right_answer_flag(chosen, options_text) #pdb.set_trace() try: location = directory + chosen + format_image except: controller.show_frame(PlayAgainExit) my_image = PhotoImage(file=location) canvas.create_image(160, 100, anchor=CENTER, image=my_image) button1["text"] = options_text[0] button2["text"] = options_text[1] button3["text"] = options_text[2] button4["text"] = options_text[3] button1['state'] = NORMAL button2['state'] = NORMAL button3['state'] = NORMAL button4['state'] = NORMAL ## button5 = Button( next_frame, width=20, text="next", fg="black", #command=lambda: change_flag(top_frame,bottom_frame,button1,button2,button3,button4,controller)) command=Thread(target=change_flag, args =(top_frame,bottom_frame,button1,button2,button3,button4,controller)).start) button5.pack(side=RIGHT, padx=5, pady=5) The formatting is messed up, which doesn't help. Some points: You have a 'bare' except, i.e. "except:". Don't do that. It swallows _all_ exceptions and can hide bugs. I don't like how you're passing Thread...start as an argument. IMHO, it would be better/cleaner to pass a plain function, even if the only thing that function does is to start the thread. I can't tell what 'change_flag' is doing because of the formatting issue. Is it doing GUI stuff? In a thread? If yes, don't do that. The GUI doesn't like that. Only the main thread should do GUI stuff. -- https://mail.python.org/mailman/listinfo/python-list
Tkinter GUI freezing, used Thread then encountered RuntimeError: threads can only be started once
Here is the entire code snippet of the same. Please help def change_flag(top_frame, bottom_frame, button1, button2, button3, button4, controller): global counter, canvas, my_image, chosen, flag, directory canvas.delete('all') button5['state'] = DISABLED counter += 1 chosen, options_text = function_options() right_answer_flag = get_right_answer_flag(chosen, options_text) #pdb.set_trace() try: location = directory + chosen + format_image except: controller.show_frame(PlayAgainExit) my_image = PhotoImage(file=location) canvas.create_image(160, 100, anchor=CENTER, image=my_image) button1["text"] = options_text[0] button2["text"] = options_text[1] button3["text"] = options_text[2] button4["text"] = options_text[3] button1['state'] = NORMAL button2['state'] = NORMAL button3['state'] = NORMAL button4['state'] = NORMAL ## button5 = Button( next_frame, width=20, text="next", fg="black", #command=lambda: change_flag(top_frame,bottom_frame,button1,button2,button3,button4,controller)) command=Thread(target=change_flag, args =(top_frame,bottom_frame,button1,button2,button3,button4,controller)).start) button5.pack(side=RIGHT, padx=5, pady=5) Thanks, Abhay -- https://mail.python.org/mailman/listinfo/python-list
Re: asyncio and tkinter (was: What should go to stdout/stderr and why Python logging write everything to stderr?)
On 1/5/2023 7:52 PM, Stefan Ram wrote: Thomas Passin writes: On 1/5/2023 4:24 PM, Stefan Ram wrote: You often can replace threads in tkinter by coroutines using asyncio when you write a replacement for the mainloop of tkinter that uses asyncio. Now, try to read only the official documentation of asyncio and tkinter and figure out only from this how to get such a program to work! Cool! Can we have a link, please? I do not post links, but tried to create a minimal example app. Thanks! That's not exactly obvious, is it? Congratulations on getting it working. import asyncio import logging import tkinter # This program was tested on Windows, it is experimental. # It should open a tkinter root window. # Ctrl-E should create a task. You should be able to create # a new task even while one task is already running. # Each task will end after about 10 seconds. # Ctrl-X should exit the process. # Or, use the menu "Action". # I (Stefan Ram) designed and wrote the program, but especially # the code in "app_async_mainloop" and "terminate_tasks" was # written following educational material from the World-Wide Web. class app_class( tkinter.Tk ): def __init__( self, *args, **kwargs ): self.is_running = 1_000_000 super().__init__( *args, **kwargs ) root = self root.protocol( "WM_DELETE_WINDOW", self.app_exit_macro ) async def app_example_task( self, example_label ): try: for i in range( 10 ): example_label[ 'text' ]=str( i ) await asyncio.sleep( 1 ) except asyncio.CancelledError: pass example_label.destroy() def app_example_macro( self ): root = self example_label=tkinter.Label( root ) example_label.pack() asyncio.get_running_loop().create_task\ ( self.app_example_task( example_label )) root = self def terminate_tasks( self ): loop = asyncio.get_running_loop() pending = asyncio.all_tasks( loop=loop ) label_tasks = [] for task in pending: if 'app_example_task' in str( task ): label_tasks.append( task ) task.cancel() group = asyncio.gather( *label_tasks, return_exceptions=True ) try: loop.run_until_complete( group ) except AssertionError: # ignoring an assertion error on Windows I do not understand pass def app_exit_macro( self ): self.terminate_tasks() self.is_running = 99 root = self root.destroy() def app_add_basemenu( self, example=False ): root = self menubar = tkinter.Menu( root ) menu = tkinter.Menu( menubar, tearoff=0 ) name = "Actions"; menu = tkinter.Menu( menubar, tearoff=0 ) if example: text = "Example"; callback = self.app_example_macro; menu.add_command\ ( label=text, underline=0, command=callback, accelerator="Control-e" ); root.bind\ ( "", lambda event, callback=callback:callback() ) text = "Exit"; callback = self.app_exit_macro menu.add_command\ ( label=text, underline=1, command=callback, accelerator="Control-x" ) root.bind\ ( "", lambda event,callback=callback: callback() ) menubar.add_cascade( label=name, underline=0, menu=menu ) root.config( menu=menubar ) async def app_async_mainloop( self ): root = self root.willdispatch() root.tk.dooneevent( tkinter._tkinter.DONT_WAIT ) while self.is_running > 0: if self.is_running < 1_000_000: self.is_running -= 1 try: await asyncio.sleep\ ( tkinter._tkinter.getbusywaitinterval() / 10_000 ) root.tk.dooneevent( tkinter._tkinter.DONT_WAIT ) root.update() except tkinter.TclError: break async def app_async_main( self ): try: await self.app_async_mainloop() except asyncio.CancelledError: logging.debug( f'asyncio.CancelledError' ) def app_async_run( self ): asyncio.run( self.app_async_main() ) app = app_class() app.app_add_basemenu(example=True) app.app_async_run() -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
> > I want learn python for 4 weeks and have problems, installing Tkinter. If > I installed 3.11.0 for my windows 8.1 from python.org and type > > >>> import _tkinter > > Traceback (most recent call last): > >File "", line 1, in > > ImportError: DLL load failed while importing _tkinter: Das angegebene > > Modul wurde nicht gefunden. > > > So I it is a tkinter Problem and I tried this: > > > >>> import _tkinter > > Traceback (most recent call last): > >File "", line 1, in > > ImportError: DLL load failed while importing _tkinter: Das angegebene > > Modul wurde nicht gefunden. > > How can I fix this and make it work? > Have a look at https://stackoverflow.com/questions/25905540/importerror-no-module-named-tkinter . Most of the answers are for Linux/Mac, but there are Windows answers there, too. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
> On 23 Nov 2022, at 06:31, Stefan Ram wrote: > > darkst...@o2online.de writes: >> I want learn python for 4 weeks and have problems, installing Tkinter. If I= >> installed 3.11.0 for my windows 8.1 from python.org and type > > Ok, so you already installed from python.org. I wonder a > little about the wording "installing Tkinter". Here, > I installed /Python/ from python.org, and this /included/ tkinter. > If you have really attempted a separate installation of tkinter, > it may help to uninstall and instead install Python /including/ > tkinter. > >>> ImportError: DLL load failed while importing _tkinter: Das angegebene >>> Modul wurde nicht gefunden. > > Another possibility of analysis is to watch the Python > process using "Process Monitor" (formerly from Sysinternals) > under Microsoft® Windows (not to be confused with "Process > Explorer"). This program requires some familiarization, > but then it can show you in which directories a process is > searching for which DLLs. This might help you to find the > name of the DLL missing and in which directory it should be. I think the depends.exe tool from sysintenals will do this as well. There is a mode where you run a program and it collects the data for all the DLLs that are used either statically linked or dynamicall loaded, that is the case for _tkinter. I have not used in in a very long time but I recall it shows errors from DLLs that failed to load. Barry > > > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
> On 22 Nov 2022, at 16:09, r...@zedat.fu-berlin.de wrote: > > darkst...@o2online.de writes: >>> ImportError: DLL load failed while importing _tkinter: Das angegebene >>> Modul wurde nicht gefunden. > > If you have not already done so, make sure that you install > Python from python.org. > > Then, after the installation, you also should make sure that > you actually use this installed version. > > import sys > sys.version_info > import tkinter > > It is possible that you have installed a different version > of Python before and accidentally have opened that version, > which may not include tkinter. In which case the error is module not found. The error reported suggests that a dll that _tkinter needs is missing. Barry > > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
On 11/21/22 14:41, Thomas Passin wrote: On 11/21/2022 1:24 PM, Stefan Ram wrote: darkst...@o2online.de writes: import _tkinter I don't know why you get this error message. Here, I do not get an error message from that line. However, the normal way to use tkinter, as far as I know, is without the underscore! You can import both tkinter and _tkinter, though I'm not sure why you would do the latter for any normal programming. No, but it's often the advice given when things are not working - see if the underlying tkinter module can be imported, to verify it's actually findable, so not surprised to see someone trying it. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
On 11/21/2022 12:59 PM, darkst...@o2online.de wrote: Dear list, I want learn python for 4 weeks and have problems, installing Tkinter. If I installed 3.11.0 for my windows 8.1 from python.org and type >>> import _tkinter > Traceback (most recent call last): > File "", line 1, in > ImportError: DLL load failed while importing _tkinter: Das angegebene > Modul wurde nicht gefunden. > So I it is a tkinter Problem and I tried this: > >>> import _tkinter > Traceback (most recent call last): > File "", line 1, in > ImportError: DLL load failed while importing _tkinter: Das angegebene > Modul wurde nicht gefunden. How can I fix this and make it work? When installing Python 3.11.0 did you check the box "tcl/tk and IDLE"? (it's an option on the Python Windows installer). I made sure to do that, and then this worked: import tkinter from tkinter import filedialog as fd from tkinter.filedialog import askopenfilename filename = fd.askopenfilename() print(filename) foldername = fd.askdirectory() print(foldername) time.sleep(3) -- https://mail.python.org/mailman/listinfo/python-list
Re: Python 3.11.0 installation and Tkinter does not work
On 11/21/2022 1:24 PM, Stefan Ram wrote: darkst...@o2online.de writes: import _tkinter I don't know why you get this error message. Here, I do not get an error message from that line. However, the normal way to use tkinter, as far as I know, is without the underscore! You can import both tkinter and _tkinter, though I'm not sure why you would do the latter for any normal programming. I think it might be best if you make sure that a recent Visual C++ Redistributable Runtime from Microsoft® is installed before you install Python. That's a worthwhile thought. If you have no such Runtime, I have no idea how to proceed! Maybe uninstall Python, install the Runtime, and then install Python again? python.org says: "Note that Python 3.11.0 cannot be used on Windows 7 or earlier" But maybe there's something about their compilation settings or runtime support versions that doesn't work with the OP's version of Python 8.1. Or, since Python itself seems to be running, maybe the way the tkinter binary was compiled isn't compatible even though Python 3.11 itself is. Maybe this is a bug waiting to be filed... I would try installing a lower version, maybe an older version of Python 3.10, and seeing if that works. If you have chosen any unusual settings during the installation of Python, it might help to try an installation with the suggested settings. I am trying to learn tkinter myself and I am very surprised how well it offers exactly what I am looking for! I hope they never will remove tkinter from the standard distribution! -- https://mail.python.org/mailman/listinfo/python-list
Python 3.11.0 installation and Tkinter does not work
Dear list, I want learn python for 4 weeks and have problems, installing Tkinter. If I installed 3.11.0 for my windows 8.1 from python.org and type >>> import _tkinter > Traceback (most recent call last): > File "", line 1, in > ImportError: DLL load failed while importing _tkinter: Das angegebene > Modul wurde nicht gefunden. > So I it is a tkinter Problem and I tried this: > >>> import _tkinter > Traceback (most recent call last): > File "", line 1, in > ImportError: DLL load failed while importing _tkinter: Das angegebene > Modul wurde nicht gefunden. How can I fix this and make it work? -- https://mail.python.org/mailman/listinfo/python-list
Re: What's tkinter doing in \Lib\site-packages\future\moves ?
On 11/7/2022 10:48 PM, DFS wrote: 3.9.13 Never mind. User error - I didn't install it in the first place. -- https://mail.python.org/mailman/listinfo/python-list
Re: What's tkinter doing in \Lib\site-packages\future\moves ?
On Tue, 8 Nov 2022 at 15:12, DFS wrote: > > 3.9.13 > My guess? Because you can "import tkinter" in Py3 but "import Tkinter" in Py2. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
What's tkinter doing in \Lib\site-packages\future\moves ?
3.9.13 -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3.6 tkinter bug?
On Wednesday, February 1, 2017 at 11:55:35 AM UTC, Terry Reedy wrote: > On 2/1/2017 1:37 AM, Christian Gollwitzer wrote: > > Am 01.02.17 um 00:02 schrieb MRAB: > >> On 2017-01-31 22:34, Christian Gollwitzer wrote: > >>>> .!frame.!checkbutton > >>>> .!frame.!checkbutton2 > >>>> .!frame2.!checkbutton > >>>> .!frame2.!checkbutton2 > >>> > >>> > >> Perhaps someone who knows Tcl and tk can tell me, but I notice that in > >> the first example, the second part of the widget names are unique, > >> whereas in the second example, the second part of the widget names are > >> the reused (both "!checkbutton" and "!checkbutton2" occur twice). > > > > It is indeed the reason, but it has some strange legacy cause: the > > default name for the checkbutton-linked variable is the name of the > > button inside the parent. Therefore creating a checkbutton has the side > > effect of creating a variable with the button's name. > > > > In this case, the first buttons in the frames are linked to a variable > > called "!checkbutton" and the other two are linked to "!checkbutton2". > > (a variable name in Tcl can be anything apart from the empty string). > > This can also be demonstrated by this Tcl script: > > > > package require Tk > > > > pack [frame .f1] > > pack [frame .f2] > > > > pack [checkbutton .f1.c1 -text "A" ] > > pack [checkbutton .f1.c2 -text "B" ] > > > > pack [checkbutton .f2.c1 -text "C" ] > > pack [checkbutton .f2.c2 -text "D" ] > > > > which is equivalent to the Python code above. > > > > Note that this surprising behaviour was corrected for the (modern) ttk > > widgets, so if "checkbutton" is replaced by "ttk::checkbutton", they are > > not any longer linked. In Python, that would be > > > > from tkinter import ttk > > ... > > w = ttk.Checkbutton() > > > > (Personally, I'm not using the legacy widgets any longer) > Christian, could you repeat any relevant parts of your comments on the > tracker, especially any ideas on how we might fix tkinter? > https://bugs.python.org/issue29402 > >> Do the names need to be: > >> > >> .!frame.!checkbutton > >> .!frame.!checkbutton2 > >> .!frame2.!checkbutton3 > >> .!frame2.!checkbutton4 > Serhiy considered that but, not knowing that this would cause a > regression, we both liked numbering within parent better. > > There is a similar issue with radiobuttons on ttk.OptionMenus that > existed *before* the 3.6 name changes. > https://bugs.python.org/issue25684 > So there seems to be a systematic issue with tk or how we are (mis)using it. > > Good question. Maybe there should be unique variable names? I.e., if the > > script is changed into package require Tk > > > > pack [frame .f1] > > pack [frame .f2] > > > > pack [checkbutton .f1.c1 -text "A" -variable v1] > > pack [checkbutton .f1.c2 -text "B" -variable v2] > > > > pack [checkbutton .f2.c1 -text "C" -variable v3] > > pack [checkbutton .f2.c2 -text "D" -variable v4] > > > > then they are also not linked. > -- > Terry Jan Reedy It looks as if the issue is indeed that the expression to the right of CheckButton(... variable= must be an expression. This works for me global checkbix, checkbuttons checkbix += 1 b = tk.Checkbutton(frame, text=text, variable=checkbuttons[checkbix], ...) -- https://mail.python.org/mailman/listinfo/python-list
Re: Python3.6 tkinter bug?
On Wednesday, February 1, 2017 at 11:55:35 AM UTC, Terry Reedy wrote: > On 2/1/2017 1:37 AM, Christian Gollwitzer wrote: > > Am 01.02.17 um 00:02 schrieb MRAB: > >> On 2017-01-31 22:34, Christian Gollwitzer wrote: > >>>> .!frame.!checkbutton > >>>> .!frame.!checkbutton2 > >>>> .!frame2.!checkbutton > >>>> .!frame2.!checkbutton2 > >>> > >>> > >> Perhaps someone who knows Tcl and tk can tell me, but I notice that in > >> the first example, the second part of the widget names are unique, > >> whereas in the second example, the second part of the widget names are > >> the reused (both "!checkbutton" and "!checkbutton2" occur twice). > > > > It is indeed the reason, but it has some strange legacy cause: the > > default name for the checkbutton-linked variable is the name of the > > button inside the parent. Therefore creating a checkbutton has the side > > effect of creating a variable with the button's name. > > > > In this case, the first buttons in the frames are linked to a variable > > called "!checkbutton" and the other two are linked to "!checkbutton2". > > (a variable name in Tcl can be anything apart from the empty string). > > This can also be demonstrated by this Tcl script: > > > > package require Tk > > > > pack [frame .f1] > > pack [frame .f2] > > > > pack [checkbutton .f1.c1 -text "A" ] > > pack [checkbutton .f1.c2 -text "B" ] > > > > pack [checkbutton .f2.c1 -text "C" ] > > pack [checkbutton .f2.c2 -text "D" ] > > > > which is equivalent to the Python code above. > > > > Note that this surprising behaviour was corrected for the (modern) ttk > > widgets, so if "checkbutton" is replaced by "ttk::checkbutton", they are > > not any longer linked. In Python, that would be > > > > from tkinter import ttk > > ... > > w = ttk.Checkbutton() > > > > (Personally, I'm not using the legacy widgets any longer) > Christian, could you repeat any relevant parts of your comments on the > tracker, especially any ideas on how we might fix tkinter? > https://bugs.python.org/issue29402 > >> Do the names need to be: > >> > >> .!frame.!checkbutton > >> .!frame.!checkbutton2 > >> .!frame2.!checkbutton3 > >> .!frame2.!checkbutton4 > Serhiy considered that but, not knowing that this would cause a > regression, we both liked numbering within parent better. > > There is a similar issue with radiobuttons on ttk.OptionMenus that > existed *before* the 3.6 name changes. > https://bugs.python.org/issue25684 > So there seems to be a systematic issue with tk or how we are (mis)using it. > > Good question. Maybe there should be unique variable names? I.e., if the > > script is changed into package require Tk > > > > pack [frame .f1] > > pack [frame .f2] > > > > pack [checkbutton .f1.c1 -text "A" -variable v1] > > pack [checkbutton .f1.c2 -text "B" -variable v2] > > > > pack [checkbutton .f2.c1 -text "C" -variable v3] > > pack [checkbutton .f2.c2 -text "D" -variable v4] > > > > then they are also not linked. > -- > Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter not working
On 2022-08-01 at 18:53:47 +0100, Matthew Barnett wrote: > On 01/08/2022 13:17, Daniel Lee wrote: > > Hello, I my code with tkinter was working before, and now, it has many > > errors in it. I’m not sure what has happened. The results after running are > > below: > > > > "D:\Python Projects\tes\venv\Scripts\python.exe" "D:/Python > > Projects/tes/main.py" > > Traceback (most recent call last): > >File "D:\Python Projects\tes\main.py", line 1, in > > import tkinter as tk > >File > > "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", > > line 3, in > > import tkinter.messagebox > >File > > "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\messagebox.py", > > line 25, in > > from tkinter.commondialog import Dialog > >File > > "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\commondialog.py", > > line 13, in > > from tkinter import Frame, _get_temp_root, _destroy_temp_root > > ImportError: cannot import name 'Frame' from partially initialized module > > 'tkinter' (most likely due to a circular import) > > (C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py) > > > > Process finished with exit code 1 > > The entry: > > File > "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", > line 3, in > import tkinter.messagebox > > in the traceback does not look right to me. On my PC that file starts with a > long docstring. My tkinter/__init__.py, too. Do you have (and did you create since the last time your code worked) your own module called tkinter? Is line 3 "import tkinter.messagebox"? -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter not working
On 01/08/2022 13:17, Daniel Lee wrote: Hello, I my code with tkinter was working before, and now, it has many errors in it. I’m not sure what has happened. The results after running are below: "D:\Python Projects\tes\venv\Scripts\python.exe" "D:/Python Projects/tes/main.py" Traceback (most recent call last): File "D:\Python Projects\tes\main.py", line 1, in import tkinter as tk File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3, in import tkinter.messagebox File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\messagebox.py", line 25, in from tkinter.commondialog import Dialog File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\commondialog.py", line 13, in from tkinter import Frame, _get_temp_root, _destroy_temp_root ImportError: cannot import name 'Frame' from partially initialized module 'tkinter' (most likely due to a circular import) (C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py) Process finished with exit code 1 The entry: File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3, in import tkinter.messagebox in the traceback does not look right to me. On my PC that file starts with a long docstring. -- https://mail.python.org/mailman/listinfo/python-list
Tkinter not working
Hello, I my code with tkinter was working before, and now, it has many errors in it. I’m not sure what has happened. The results after running are below: "D:\Python Projects\tes\venv\Scripts\python.exe" "D:/Python Projects/tes/main.py" Traceback (most recent call last): File "D:\Python Projects\tes\main.py", line 1, in import tkinter as tk File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3, in import tkinter.messagebox File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\messagebox.py", line 25, in from tkinter.commondialog import Dialog File "C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\commondialog.py", line 13, in from tkinter import Frame, _get_temp_root, _destroy_temp_root ImportError: cannot import name 'Frame' from partially initialized module 'tkinter' (most likely due to a circular import) (C:\Users\Daniel.LAPTOP-6U1MQ9CR\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py) Process finished with exit code 1 -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter - cannot import tklib
On Tue, 21 Jun 2022 at 09:22, Wolfgang Grafen wrote: > I am an experienced Python user and struggle with following statement: > > >>> from tklib import * > Traceback (most recent call last): > File "", line 1, in > ModuleNotFoundError: No module named 'tklib' [...] > I did not find a python module called tklib to install. Ok, see below for how to find that file. [...] > I assume it should be installed by default with every python installation It appears that your assumption is wrong. It appears to me that the missing file is part of the tk-tutorial project. > https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html?highlight=app# > First time that I cannot help myself. Please help, what do I do wrong? Hi, here is a description how I found the file you seek: Go to https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html At the top right of the page, see hyperlink "Edit on GitHub". Click hyperlink takes you to https://github.com/rasql/tk-tutorial/blob/master/docs/intro/intro.rst which is the same content rendered from 'rst' format I assume. At top left of that page, see hyperlinks "tk-tutorial"/"docs"/"intro" and "rasql"/"tk-tutorial". Click one of the "tk-tutorial" hyperlinks to go to the top directory of the project at: https://github.com/rasql/tk-tutorial On that page near the very top, see a list of hyperlinks to directories and files of the project. One of those hyperlinks is labelled "tklib.py". Click that link to see the file at https://github.com/rasql/tk-tutorial/blob/master/tklib.py On that page, click the "Raw" button. Then you can use "save as" in your browser. Or you can just download it by some other method from the link given in the previous paragraph. -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter - cannot import tklib
On Mon, 20 Jun 2022 15:43:26 -0700 (PDT), Wolfgang Grafen declaimed the following: > >There are numerous examples using "from tklib import *" so I assume it works >for most. In the tk-tutorial below tklib is used without special explanation, >so I assume it should be installed by default with every python installation >which has Tkinter integrated. > >https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html?highlight=app# > >First time that I cannot help myself. Please help, what do I do wrong? > From what I can see, you haven't /written/ a tklib module. That tutorial assumes you will create a module containing a number of simplified interfaces to tk widgets. cf: https://tk-tutorial.readthedocs.io/en/latest/radio/radio.html#a-better-radiobutton-class tklib.py will contain the definition of the Radiobutton class. The same probably applies everywhere that you see tklib imported -- whatever classes are used to create widgets need to be defined in that file. https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html?highlight=app# """ In the following section we are going to redefine the tk and ttk objects. To make it easier to use them, we follow these design principles: we keep the excact same class names the parent object is chosen automatically all keyword arguments are forwarded The first widget to consider is the Label which just places static text. Where it makes sense, a label will be combined with a button or entry widget. """ https://tk-tutorial.readthedocs.io/en/latest/check/check.html#a-better-checkbutton-class etc. -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Tkinter - cannot import tklib
On 2022-06-20 23:43, Wolfgang Grafen wrote: Hello all, I am an experienced Python user and struggle with following statement: from tklib import * Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'tklib' I tried to import tklib as shown above on following of my Python installations: Anaconda Python 3.8.3, Portable Python 3.9, Python 3.10.1, Python 2.7.10 with the same negative result. I also tried to find help by googling - without success. Also I did not find a python module called tklib to install. Tkinter, ttk is working fine. There are numerous examples using "from tklib import *" so I assume it works for most. In the tk-tutorial below tklib is used without special explanation, so I assume it should be installed by default with every python installation which has Tkinter integrated. https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html?highlight=app# First time that I cannot help myself. Please help, what do I do wrong? I'm thinking that maybe that tutorial is about writing a module (called "tklib") to make it easier to write tkinter applications. The tkinter "Text" widget, for example, doesn't have its own scrollbars (you have to add them separately and link them to the widget), so writing a module that defines a text-with-scrollbars widget is a good idea. -- https://mail.python.org/mailman/listinfo/python-list
Tkinter - cannot import tklib
Hello all, I am an experienced Python user and struggle with following statement: >>> from tklib import * Traceback (most recent call last): File "", line 1, in ModuleNotFoundError: No module named 'tklib' I tried to import tklib as shown above on following of my Python installations: Anaconda Python 3.8.3, Portable Python 3.9, Python 3.10.1, Python 2.7.10 with the same negative result. I also tried to find help by googling - without success. Also I did not find a python module called tklib to install. Tkinter, ttk is working fine. There are numerous examples using "from tklib import *" so I assume it works for most. In the tk-tutorial below tklib is used without special explanation, so I assume it should be installed by default with every python installation which has Tkinter integrated. https://tk-tutorial.readthedocs.io/en/latest/intro/intro.html?highlight=app# First time that I cannot help myself. Please help, what do I do wrong? Greetings Wolfgang -- https://mail.python.org/mailman/listinfo/python-list