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

Reply via email to