Идея состоит в том, чтобы контролировать вторичный экран без необходимости физического монитора. Изображение переходит к проектору в другой комнате.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>
Код, который работает без ошибок, и без участия в классе: < /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>
Код, который дает ошибку, используя класс app (): < /p>
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}
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>
Изменить: Мне удалось сделать адаптацию для перезапуска захвата, но было бы интересно избежать ошибки захвата MSS. Таким образом, захват не застрял.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()
Подробнее здесь: https://stackoverflow.com/questions/794 ... -tk-window
Как избежать ошибки экрана с использованием MSS при использовании класса для окна TK? ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как установить TCP MSS только для соединений с TCP MSS больше 1410 с помощью iptables?
Anonymous » » в форуме Linux - 0 Ответы
- 20 Просмотры
-
Последнее сообщение Anonymous
-