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