2017-11-30 18 views
0

私のコードをSpyder3 IPythonコンソール内で実行しているときにいくつか問題があります。今私はこれについて掘り下げて、結論として に行きました。ドライバかX11のグラフィックに関する問題があったか、 転送か何か。python tkinter windows/pygame windowsをクリーンアップする方法はありますか?

または私は単に が同様 BadWindowsなど

に起因するエラーが発生する可能性がありますカーネルの再起動を必要とする、適切に第二の実行が常に問題となる理由である私のコードをクリーンアップしないの問題を持っています

これらXCBエラーやGTKの警告のいずれかに対処することは

私の質問はあまりにも複雑であるので、私は、適切に十分であろうクリーンアップを願っています:どのように私は適切にクリーンアップTkinterの風オブジェクト、パイゲームの表面、マルチスレッド? 期待:ウィンドウが閉じた後のすべてを削除します。これは、その時点ではもはや必ずしも必要ではないため、またはそれが続く場合は単にエラーが発生するためです。

私はPython Deconstructor 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() 
+1

常に置いエラーを行うことができ、スクリーンショットではありません。スクリーンショットからテキストをコピーして使用することはできません。 – furas

+0

私はSpyder3 IPythonでなぜそれを実行するのか分かりません。 Naturalメソッドは、teminal/consoleを 'python scriptname.py'として実行します。 – furas

+0

問題の継ぎ目は' thread' - 'tkinter'で、' pygame'はスレッドセーフではないので、同時に2つのスレッドで使用しないでください。メインスレッドで 'pygame'を開始しますが、後で新しいスレッドを使用します。 'pg.display.init()'から始まる新しいスレッドですべて実行するかもしれない – furas

答えて

1

私はプログラムを閉じる前にスレッドを停止しなければ、この問題を抱えています。

私はボタンXを閉じるにコードを追加した場合、私はそれを停止しようとする前に、スレッドが実行されているかどうかを確認するためにいくつかのコードを追加する必要が全く問題

def on_closing(): 
    print("stoping") 
    setup.stop() 
    print('destroy') 
    root.destroy() 

root.protocol("WM_DELETE_WINDOW", on_closing) 

root.mainloop() 

を持っていません。

def stop(self): 
    if self.thread: 
     self.thread = False 
     self.t.join() 
     self.cam.stop() 

それはところで__init__

self.thread = False 

全コード

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) 

     self.thread = False 

    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): 
     if self.thread: 
      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=setup.stop) 
    camStop.grid(row=4, columnspan=2) 

    def on_closing(): 
     print('stoping') 
     setup.stop() 
     print('destroy') 
     root.destroy() 

    root.protocol("WM_DELETE_WINDOW", on_closing) 

    root.mainloop() 

に必要があります。代わりにcommand=lambda:self.stop()のテキストとしてcommand=self.stop

+0

ああ。ラムダを逃して、修正されます。私は完全なコードを調べます。 – HackXIt

+0

start、feed、stopのif文を追加/調整しました。これで、スレッドがstart、feed、stopですでに実行されているかどうかを確認するので、ボタンを繰り返し押すとエラーが最小限に抑えられます。私はまだspyder3の中でこれをテストする必要がありますが、しばらくあなたの助けに感謝します。 – HackXIt

+0

spyder3には依然として問題があります。失敗した要求の 'Xエラー:BadWindow(無効ウィンドウパラメータ)失敗した要求の 主要オペコード:2(X_ChangeWindowAttributes)失敗した要求に リソースID:失敗した要求の0xe00008 シリアル番号:出力ストリーム75 現在のシリアル番号:76' – HackXIt

関連する問題