У меня возникают проблемы при запуске кода в консоли Spyder3 IPython. Теперь я немного покопался в этом и пришел к выводу, что либо у меня проблемы с графикой, связанные с драйверами, либо с переадресацией X11, либо с чем-то еще.
Или у меня просто проблема с неправильной очисткой моего кода, поэтому второе выполнение всегда становится проблематичным, требуя перезапуска ядра, что также может вызвать ошибки из-за BadWindows и т. д.
Я надеюсь, что правильной очистки будет достаточно, потому что работа с любой из этих ошибок XCB или предупреждений GTK слишком сложна.
Мой вопрос: Как мне правильно очистить объекты окна tkinter, поверхности pygame и многопоточность? Ожидание: удалить все после закрытия окна, потому что это, безусловно, больше не требуется в этот момент или просто вызовет ошибки, если это сохраняется.
Я читал о деконструкторе python del, но прежде чем углубляться в это, я бы предпочел знать, какие вещи вообще требуют удаления.
Вот пример сообщения об ошибке, которое я получаю при втором выполнении моей программы (первое выполнение работает правильно)
An error ocurred while starting the kernel
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi‑threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python3: ../../src/xcb_io.c:259: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 2 (X_ChangeWindowAttributes)
Resource id in failed request: 0xe00008
Serial number of failed request: 75
Current serial number in output stream: 76
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 2 (X_ChangeWindowAttributes)
Resource id in failed request: 0xe00008
Serial number of failed request: 75
Current serial number in output stream: 76
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 2 (X_ChangeWindowAttributes)
Resource id in failed request: 0xe00008
Serial number of failed request: 75
Current serial number in output stream: 76
И вот код, который я тестирую:
import pygame as pg
import pygame.camera
import os
import threading as th
class Capture():
def __init__(self, parent):
os.environ['SDL_WINDOWID'] = parent
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.snapshot = pg.surface.Surface(self.size, 0, self.display)
def feed(self, number):
try:
self.cam = pg.camera.Camera(self.clist[number], self.size)
except IndexError:
print('Provided Camera not available.')
self.cam.start()
self.thread = True
self.t = th.Thread(name='Livefeed', target=self.live)
self.t.start()
def live(self):
while self.thread:
if self.cam.query_image():
self.cam.get_image(self.snapshot)
self.display.blit(self.snapshot, self.snapshot.get_rect())
pg.display.update()
def stop(self):
self.thread = False
self.t.join()
self.cam.stop()
#for Camera DEBUG
if __name__ == '__main__':
import tkinter as tk
root = tk.Tk()
embed = tk.LabelFrame(root, width=650, height=490)
embed.grid(row=0, column=0)
root.update()
setup = Capture(str(embed.winfo_id()))
buttons = tk.LabelFrame(root, width=100)
buttons.grid(row=0, column=1)
cam1 = tk.Button(buttons, text='Cam 1',
command=lambda: setup.feed(0), width=25)
cam2 = tk.Button(buttons, text='Cam 2',
command=lambda: setup.feed(1), width=25)
cam3 = tk.Button(buttons, text='Cam 3',
command=lambda: setup.feed(2), width=25)
cam4 = tk.Button(buttons, text='Cam 4',
command=lambda: setup.feed(3), width=25)
cam1.grid(row=0, columnspan=2)
cam2.grid(row=1, columnspan=2)
cam3.grid(row=2, columnspan=2)
cam4.grid(row=3, columnspan=2)
camStop = tk.Button(buttons, width=50, text='Feed Off',
command=lambda: setup.stop())
camStop.grid(row=4, columnspan=2)
root.mainloop()
python scriptname.py
- person furas   schedule 30.11.2017thread
-tkinter
иpygame
не являются потокобезопасными, поэтому не используйте их в двух потоках одновременно. Я вижу, вы начинаетеpygame
в основном потоке, но позже используете его в новом потоке. Возможно запустить все в новом потоке - начиная сpg.display.init()
- person furas   schedule 30.11.2017