Anonymous
Wie vermeiden Sie einen Screenshot -Fehler mit MSS, wenn Sie eine Klasse für TK -Fenster verwenden?
Post
by Anonymous » 02 Mar 2025, 14:18
Die Idee ist, den Sekundärbildschirm zu überwachen, ohne einen physischen Monitor zu benötigen. Das Bild geht an einen Projektor in einem anderen Raum. < /P>
Dieser Fehler tritt auf
Code: Select all
root2: You clicked at 295 284
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.12/tkinter/__init__.py", line 1967, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/tkinter/__init__.py", line 861, in callit
func(*args)
File "/media/rh/Win11/Python/cv2-player/cv2_mss2.py", line 65, in after_capture
im_brg = self.sct.grab(self.bounding_box)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/rh/.local/lib/python3.12/site-packages/mss/base.py", line 101, in grab
screenshot = self._grab_impl(monitor)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/rh/.local/lib/python3.12/site-packages/mss/linux.py", line 428, in _grab_impl
ximage = self.xlib.XGetImage(
^^^^^^^^^^^^^^^^^^^^
File "/home/rh/.local/lib/python3.12/site-packages/mss/linux.py", line 230, in _validate
raise ScreenShotError(msg, details=details)
mss.exception.ScreenShotError: XGetImage() failed
< /code>
Der Code, der ohne Fehler funktioniert, und ohne in einer Klasse zu sein: < /p>
from mss import mss
from PIL import Image
from PIL import ImageTk
import tkinter as tk
root2 = None
root2_is_splash = False
# screen 2: 1366x768
def root2_init(is_splash=False):
global root2
root2 = tk.Toplevel( root )
root2.transient( root )
root2.title( "Screen 2" )
root2.configure(background="blue")
root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0
root2.bind("", on_root2_click)
if is_splash == True:
root2.wm_attributes('-type', 'splash') # splash: hide title bar
def on_root_click(event):
print("root: You clicked at", event.x, event.y)
root.destroy()
def on_root2_click(event):
global root2_is_splash
print("root2: You clicked at", event.x, event.y)
root2.destroy()
if root2_is_splash == False:
root2_init(True)
root2_is_splash = True
else:
root2_init(False)
root2_is_splash = False
def after_capture():
global label1
im_brg = sct.grab(bounding_box)
im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX')
im_rgb2 = im_rgb.resize((640, 480))
photo1 = ImageTk.PhotoImage(im_rgb2)
label1.configure(image=photo1)
label1.image = photo1
root.after(10, after_capture)
bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768}
sct = mss(with_cursor=True)
# screen 1: 1920x1080
root = tk.Tk()
root.title("Tk Example")
root.minsize(200, 200)
root.maxsize(500, 500)
root.geometry("800x600+50+50")
root.bind("", on_root_click)
canvas1 = tk.Canvas(root)
canvas1.pack(fill='both', expand=True)
photo1 = tk.PhotoImage(width=64, height=64)
label1 = tk.Label(canvas1, image=photo1)
label1.pack()
label1.image = photo1
canvas1.create_window((0, 0), anchor='nw', window=label1, tags='label1_tag')
root2_init()
after_capture()
if __name__ == "__main__":
root.mainloop()
< /code>
Der Code, der den Fehler unter Verwendung einer Klasse -App (): < /p>
angibtfrom mss import mss
from PIL import Image
from PIL import ImageTk
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768}
self.sct = mss(with_cursor=True)
# screen 1: 1920x1080
self.title("Tk Example")
self.geometry("800x600+50+50")
self.canvas1 = tk.Canvas(self)
self.canvas1.pack(fill='both', expand=True)
photo1 = tk.PhotoImage(width=64, height=64)
self.label1 = tk.Label(self.canvas1, image=photo1)
self.label1.pack()
self.label1.image = photo1
self.canvas1.create_window((0, 0), anchor='nw', window=self.label1, tags='label1_tag')
self.bind("", self.on_root_click)
self.root2_is_splash = False
self.root2_init()
self.after_capture()
# screen 2: 1366x768
def root2_init(self, is_splash=False):
# global root2
self.root2 = tk.Toplevel( self )
self.root2.transient( self )
self.root2.title( "Screen 2" )
self.root2.configure(background="blue")
self.root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0
self.root2.bind("", self.on_root2_click)
if is_splash == True:
self.root2.wm_attributes('-type', 'splash') # splash: hide title bar
def on_root_click(self, event):
print("root: You clicked at", event.x, event.y)
self.destroy()
def on_root2_click(self, event):
print("root2: You clicked at", event.x, event.y)
self.root2.destroy()
if self.root2_is_splash == False:
self.root2_init(True)
self.root2_is_splash = True
else:
self.root2_init(False)
self.root2_is_splash = False
def after_capture(self):
im_brg = self.sct.grab(self.bounding_box)
im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX')
im_rgb2 = im_rgb.resize((640, 480))
photo1 = ImageTk.PhotoImage(im_rgb2)
self.label1.configure(image=photo1)
self.label1.image = photo1
self.after(10, self.after_capture)
if __name__ == "__main__":
App().mainloop()
< /code>
Bearbeiten: Ich habe es geschafft, eine Anpassung vorzubereiten, um die Erfassung neu zu starten, aber es wäre interessant, den MSS -Erfassungsfehler zu vermeiden. Auf diese Weise bleibt die Erfassung nicht hängen.from mss import mss
from PIL import Image
from PIL import ImageTk
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768}
# screen 1: 1920x1080
self.title("Tk Example")
self.geometry("800x600+50+50")
self.canvas1 = tk.Canvas(self)
self.canvas1.pack(fill='both', expand=True)
photo1 = tk.PhotoImage(width=64, height=64)
self.label1 = tk.Label(self.canvas1, image=photo1)
self.label1.pack()
self.label1.image = photo1
self.canvas1.create_window((0, 0), anchor='nw', window=self.label1, tags='label1_tag')
self.bind("", self.on_root_click)
self.root2_is_splash = False
self.root2_init()
self.after_capture()
# screen 2: 1366x768
def root2_init(self, is_splash=False):
# global root2
self.sct = mss(with_cursor=True)
self.root2 = tk.Toplevel( self )
self.root2.transient( self )
self.root2.title( "Screen 2" )
self.root2.configure(background="blue")
self.root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0
self.root2.bind("", self.on_root2_click)
if is_splash == True:
self.root2.wm_attributes('-type', 'splash') # splash: hide title bar
def on_root_click(self, event):
print("root: You clicked at", event.x, event.y)
self.destroy()
def on_root2_click(self, event):
print("root2: You clicked at", event.x, event.y)
self.root2.destroy()
if self.root2_is_splash == False:
self.root2_init(True)
self.root2_is_splash = True
else:
self.root2_init(False)
self.root2_is_splash = False
self.after_capture()
def after_capture(self):
try:
im_brg = self.sct.grab(self.bounding_box)
im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX')
im_rgb2 = im_rgb.resize((640, 480))
photo1 = ImageTk.PhotoImage(im_rgb2)
self.label1.configure(image=photo1)
self.label1.image = photo1
self.after(10, self.after_capture)
except:
print('after_capture() finished')
if __name__ == "__main__":
App().mainloop()
1740921506
Anonymous
Die Idee ist, den Sekundärbildschirm zu überwachen, ohne einen physischen Monitor zu benötigen. Das Bild geht an einen Projektor in einem anderen Raum. < /P> Dieser Fehler tritt auf[code]root2: You clicked at 295 284 Exception in Tkinter callback Traceback (most recent call last): File "/usr/lib/python3.12/tkinter/__init__.py", line 1967, in __call__ return self.func(*args) ^^^^^^^^^^^^^^^^ File "/usr/lib/python3.12/tkinter/__init__.py", line 861, in callit func(*args) File "/media/rh/Win11/Python/cv2-player/cv2_mss2.py", line 65, in after_capture im_brg = self.sct.grab(self.bounding_box) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/rh/.local/lib/python3.12/site-packages/mss/base.py", line 101, in grab screenshot = self._grab_impl(monitor) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/rh/.local/lib/python3.12/site-packages/mss/linux.py", line 428, in _grab_impl ximage = self.xlib.XGetImage( ^^^^^^^^^^^^^^^^^^^^ File "/home/rh/.local/lib/python3.12/site-packages/mss/linux.py", line 230, in _validate raise ScreenShotError(msg, details=details) mss.exception.ScreenShotError: XGetImage() failed < /code> Der Code, der ohne Fehler funktioniert, und ohne in einer Klasse zu sein: < /p> from mss import mss from PIL import Image from PIL import ImageTk import tkinter as tk root2 = None root2_is_splash = False # screen 2: 1366x768 def root2_init(is_splash=False): global root2 root2 = tk.Toplevel( root ) root2.transient( root ) root2.title( "Screen 2" ) root2.configure(background="blue") root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0 root2.bind("", on_root2_click) if is_splash == True: root2.wm_attributes('-type', 'splash') # splash: hide title bar def on_root_click(event): print("root: You clicked at", event.x, event.y) root.destroy() def on_root2_click(event): global root2_is_splash print("root2: You clicked at", event.x, event.y) root2.destroy() if root2_is_splash == False: root2_init(True) root2_is_splash = True else: root2_init(False) root2_is_splash = False def after_capture(): global label1 im_brg = sct.grab(bounding_box) im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX') im_rgb2 = im_rgb.resize((640, 480)) photo1 = ImageTk.PhotoImage(im_rgb2) label1.configure(image=photo1) label1.image = photo1 root.after(10, after_capture) bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768} sct = mss(with_cursor=True) # screen 1: 1920x1080 root = tk.Tk() root.title("Tk Example") root.minsize(200, 200) root.maxsize(500, 500) root.geometry("800x600+50+50") root.bind("", on_root_click) canvas1 = tk.Canvas(root) canvas1.pack(fill='both', expand=True) photo1 = tk.PhotoImage(width=64, height=64) label1 = tk.Label(canvas1, image=photo1) label1.pack() label1.image = photo1 canvas1.create_window((0, 0), anchor='nw', window=label1, tags='label1_tag') root2_init() after_capture() if __name__ == "__main__": root.mainloop() < /code> Der Code, der den Fehler unter Verwendung einer Klasse -App (): < /p> angibtfrom mss import mss from PIL import Image from PIL import ImageTk import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() self.bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768} self.sct = mss(with_cursor=True) # screen 1: 1920x1080 self.title("Tk Example") self.geometry("800x600+50+50") self.canvas1 = tk.Canvas(self) self.canvas1.pack(fill='both', expand=True) photo1 = tk.PhotoImage(width=64, height=64) self.label1 = tk.Label(self.canvas1, image=photo1) self.label1.pack() self.label1.image = photo1 self.canvas1.create_window((0, 0), anchor='nw', window=self.label1, tags='label1_tag') self.bind("", self.on_root_click) self.root2_is_splash = False self.root2_init() self.after_capture() # screen 2: 1366x768 def root2_init(self, is_splash=False): # global root2 self.root2 = tk.Toplevel( self ) self.root2.transient( self ) self.root2.title( "Screen 2" ) self.root2.configure(background="blue") self.root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0 self.root2.bind("", self.on_root2_click) if is_splash == True: self.root2.wm_attributes('-type', 'splash') # splash: hide title bar def on_root_click(self, event): print("root: You clicked at", event.x, event.y) self.destroy() def on_root2_click(self, event): print("root2: You clicked at", event.x, event.y) self.root2.destroy() if self.root2_is_splash == False: self.root2_init(True) self.root2_is_splash = True else: self.root2_init(False) self.root2_is_splash = False def after_capture(self): im_brg = self.sct.grab(self.bounding_box) im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX') im_rgb2 = im_rgb.resize((640, 480)) photo1 = ImageTk.PhotoImage(im_rgb2) self.label1.configure(image=photo1) self.label1.image = photo1 self.after(10, self.after_capture) if __name__ == "__main__": App().mainloop() < /code> Bearbeiten: Ich habe es geschafft, eine Anpassung vorzubereiten, um die Erfassung neu zu starten, aber es wäre interessant, den MSS -Erfassungsfehler zu vermeiden. Auf diese Weise bleibt die Erfassung nicht hängen.from mss import mss from PIL import Image from PIL import ImageTk import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() self.bounding_box = {'top': 0, 'left': 1366, 'width': 1366, 'height': 768} # screen 1: 1920x1080 self.title("Tk Example") self.geometry("800x600+50+50") self.canvas1 = tk.Canvas(self) self.canvas1.pack(fill='both', expand=True) photo1 = tk.PhotoImage(width=64, height=64) self.label1 = tk.Label(self.canvas1, image=photo1) self.label1.pack() self.label1.image = photo1 self.canvas1.create_window((0, 0), anchor='nw', window=self.label1, tags='label1_tag') self.bind("", self.on_root_click) self.root2_is_splash = False self.root2_init() self.after_capture() # screen 2: 1366x768 def root2_init(self, is_splash=False): # global root2 self.sct = mss(with_cursor=True) self.root2 = tk.Toplevel( self ) self.root2.transient( self ) self.root2.title( "Screen 2" ) self.root2.configure(background="blue") self.root2.geometry("1366x768+1920+0") # left: 1920 (right of screen 1), top: 0 self.root2.bind("", self.on_root2_click) if is_splash == True: self.root2.wm_attributes('-type', 'splash') # splash: hide title bar def on_root_click(self, event): print("root: You clicked at", event.x, event.y) self.destroy() def on_root2_click(self, event): print("root2: You clicked at", event.x, event.y) self.root2.destroy() if self.root2_is_splash == False: self.root2_init(True) self.root2_is_splash = True else: self.root2_init(False) self.root2_is_splash = False self.after_capture() def after_capture(self): try: im_brg = self.sct.grab(self.bounding_box) im_rgb = Image.frombytes('RGB', im_brg.size, im_brg.bgra, 'raw', 'BGRX') im_rgb2 = im_rgb.resize((640, 480)) photo1 = ImageTk.PhotoImage(im_rgb2) self.label1.configure(image=photo1) self.label1.image = photo1 self.after(10, self.after_capture) except: print('after_capture() finished') if __name__ == "__main__": App().mainloop() [/code]