我已经考虑在tkinter窗口中嵌入一个pygame窗口(参考:Embed Pygame in Tkinter)
我想用它来嵌入pygame.camera模块制作的快照(一旦它可能是一个livefeed)
在评论中,当评论os.environ['SDL_VIDEODRIVER'] = 'windib'
时,代码应该与Linux(在raspbian上运行)一起使用
但是我不能让嵌入工作也不能用pygame制作快照,我无法弄清楚是什么导致了这个问题。这是我写的代码:
import pygame as pg
import pygame.camera
import tkinter as tk
import os
import threading as th
tk.Frame = tk.LabelFrame
def start():
root = tk.Tk()
run = Viewer(root)
return run
class Viewer(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.screen_width = parent.winfo_screenwidth()
self.screen_height = parent.winfo_screenheight()
self.startup(self.screen_width, self.screen_height)
def startup(self, width, height):
self.parent.protocol('WM_DELETE_WINDOW', self.parent.destroy)
Viewer.embed = tk.Frame(self.parent, width=650, height=490)
Viewer.embed.pack(side = tk.LEFT)
self.buttonFrame = tk.Frame(self.parent, width=100, height=490)
self.buttonFrame.pack(side = tk.RIGHT)
self.refresh = tk.Button(self.buttonFrame,
text='Refresh',
command=self.refresh)
self.refresh.pack()
def refresh(self):
self.c = Capture()
self.c.snap()
class Capture(Viewer):
def __init__(self):
os.environ['SDL_WINDOWID'] = str(Viewer.embed.winfo_id())
self.size = (640,480)
self.display = pg.display.set_mode(self.size)
self.clist = pg.camera.list_cameras()
if not self.clist:
raise ValueError("Sorry, no cameras detected.")
self.cam = pg.camera.Camera(self.clist[0], self.size)
self.cam.start()
self.snapshot = pg.surface.Surface(self.size, 0, self.display)
self.event = th.Thread(target=self.eventCatcher)
self.event.start()
def snap(self):
self.snapshot = self.cam.get_image(self.snapshot)
def eventCatcher(self):
closed = False
while not closed:
events = pg.event.get()
for e in events:
if e.type == pg.QUIT:
self.cam.stop()
closed = True
pg.init()
pg.camera.init()
main = start()
main.mainloop()
答案 0 :(得分:1)
设置pygame
os.environ['SDL_WINDOWID']
os.environ['SDL_WINDOWID'] = str(...)
pygame.init()
编辑:适用于Linux Mint 18.2
import pygame as pg
import pygame.camera
import tkinter as tk
import os
import threading as th
#tk.Frame = tk.LabelFrame
class Viewer(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent # there is self.master which keeps parent
self.parent.protocol('WM_DELETE_WINDOW', self.parent.destroy)
self.screen_width = parent.winfo_screenwidth()
self.screen_height = parent.winfo_screenheight()
self.embed = tk.Frame(self.parent, width=650, height=490)
self.embed.pack(side='left')
self.buttonFrame = tk.Frame(self.parent, width=100, height=490)
self.buttonFrame.pack(side='right')
self.parent.update() # need it to get embed.winfo_id() in Capture
self.c = Capture(self)
self.refreshButton = tk.Button(self.buttonFrame,
text='Refresh',
command=self.refresh)
self.refreshButton.pack()
def refresh(self):
self.c.snap()
class Capture():
def __init__(self, parent):
os.environ['SDL_WINDOWID'] = str(parent.embed.winfo_id())
pg.display.init()
pg.camera.init()
self.size = (640,480)
self.display = pg.display.set_mode(self.size)
self.display.fill(pg.Color(255,255,255))
pg.display.update()
self.clist = pg.camera.list_cameras()
if not self.clist:
raise ValueError("Sorry, no cameras detected.")
print('cameras:', self.clist)
self.cam = pg.camera.Camera(self.clist[0], self.size)
self.cam.start()
self.snapshot = pg.surface.Surface(self.size, 0, self.display)
self.event = th.Thread(target=self.eventCatcher)
self.event.start()
def snap(self):
print('snap ready:', self.cam.query_image())
self.cam.get_image(self.snapshot)
self.display.blit(self.snapshot, self.snapshot.get_rect())
pg.display.update()
def eventCatcher(self):
closed = False
while not closed:
events = pg.event.get()
for e in events:
if e.type == pg.QUIT:
self.cam.stop()
closed = True
root = tk.Tk()
run = Viewer(root)
root.mainloop()