2016-10-12 9 views
0

Webshopから最新の収入を得る小さなプログラムを作っています。前回の音量よりも音が大きい場合、Pygletを使用していますが、メインスレッドから呼び出されていないためエラーが発生します。私はメインスレッド上でメソッドを呼び出す方法を知りたいです。それは特に不思議ではないのですGUIスレッド上でメソッドを呼び出す方法は?

'thread that imports pyglet.app' RuntimeError: EventLoop.run() must be called from the same thread that imports pyglet.app

def work(): 
     threading.Timer(5, work).start() 
     file_Name = "save.txt" 
     lastRevenue = 0 
     data = json.load(urllib2.urlopen('')) 
     newRevenue = data["revenue"] 
     if (os.path.getsize(file_Name) <= 0): 
      with open(file_Name, "wb") as f: 
       f.write('%d' % newRevenue) 
       f.flush() 
     with open(file_Name, "rb") as f: 
      lastRevenue = float(f.readline().strip()) 
      print lastRevenue 
      print newRevenue 
      f.close() 
      if newRevenue > lastRevenue: 
       with open(file_Name, "wb") as f: 
        f.write('%f' % newRevenue) 
        f.flush() 
        playsound() 


    def playsound(): 
     music = pyglet.resource.media('cash.wav') 
     music.play() 
     pyglet.app.run()  

    work() 

答えて

0

:次のエラーを参照してください。 workは、pygletがインポートされた場所とは別のスレッドとして実行されています。

pyglet.appインポートすると、多くのコンテキスト変数が設定されます。実際に何が設定されているかを実際に確認することに実際に煩わされていないからではありません。

OpenGLはそれ自身のコンテキスト(存在するメインスレッド)からは実行できません。あなたのために、隣のスレッドからOpenGLを突き飛ばすことは許されません。それが意味をなさないならば。

しかし、独自の.run()関数を作成し、Pygletを起動するクラスベースのメソッドを使用すると、スレッドからGUIを起動できます。あなたはまだスレッド内から実際のGUIコードを開始する必要が

import pyglet 
from pyglet.gl import * 
from threading import * 

# REQUIRES: AVBin 
pyglet.options['audio'] = ('alsa', 'openal', 'silent') 

class main(pyglet.window.Window): 
    def __init__ (self): 
     super(main, self).__init__(300, 300, fullscreen = False) 
     self.x, self.y = 0, 0 

     self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg')) 
     self.music = pyglet.resource.media('cash.wav') 
     self.music.play() 
     self.alive = 1 

    def on_draw(self): 
     self.render() 

    def on_close(self): 
     self.alive = 0 

    def render(self): 
     self.clear() 
     self.bg.draw() 
     self.flip() 

    def run(self): 
     while self.alive == 1: 
      self.render() 

      if not self.music.playing: 
       self.alive = 0 
      # -----------> This is key <---------- 
      # This is what replaces pyglet.app.run() 
      # but is required for the GUI to not freeze 
      # 
      event = self.dispatch_events() 

class ThreadExample(Thread): 
    def __init__(self): 
     Thread.__init__(self) 
     self.start() 

    def run(self): 
     x = main() 
     x.run() 

Test_One = ThreadExample() 

注:

これは、あなたがそれを設定できるかの実施例です。

私は強くあなたの代わりにこれを行う勧め

がスレッドを混合として見て、GUIが滑りやすい斜面さ呼び出すカントー、私はあなたがより慎重なパスで行くことをお勧め。

from threading import * 
from time import sleep 

def is_main_alive(): 
    for t in enumerate(): 
     if t.name == 'MainThread': 
      return t.isAlive() 

class worker(Thread): 
    def __init__(self, shared_dictionary): 
     Thread.__init__(self) 
     self.shared_dictionary 
     self.start() 

    def run(self): 
     while is_main_alive(): 
      file_Name = "save.txt" 
      lastRevenue = 0 
      data = json.load(urllib2.urlopen('')) 
      newRevenue = data["revenue"] 
      if (os.path.getsize(file_Name) <= 0): 
       with open(file_Name, "wb") as f: 
        f.write('%d' % newRevenue) 
        f.flush() 
      with open(file_Name, "rb") as f: 
       lastRevenue = float(f.readline().strip()) 
       print lastRevenue 
       print newRevenue 
       f.close() 
       if newRevenue > lastRevenue: 
        with open(file_Name, "wb") as f: 
         f.write('%f' % newRevenue) 
         f.flush() 
         #playsound() 
         # Instead of calling playsound() here, 
         # set a flag in the shared dictionary. 
         self.shared_dictionary['Play_Sound'] = True 
      sleep(5) 

def playsound(): 
    music = pyglet.resource.media('cash.wav') 
    music.play() 
    pyglet.app.run()  

shared_dictionary = {'Play_Sound' : False} 
work_handle = worker(shared_dictionary) 

while 1: 
    if shared_dictionary['Play_Sound']: 
     playsound() 
     shared_dictionary['Play_Sound'] = False 
    sleep(0.025) 

あなたが探しているものの概略です。
基本的には、スレッドとGUIが互いに通信するために使用できるイベント/フラグ駆動のバックエンドです。

基本的には、以前と同じようにワーカースレッドがあり、5秒ごとに必要なファイルをチェックし、newRevenue > lastRevenueが検出された場合は特定のフラグをTrueに設定します。メインループはこの変更を検出し、サウンドを再生し、フラグをFalseに戻します。

ここではエラー処理を目的に含まないことはありませんが、ここではソリューション全体を作成するのではなく、役立つようにしています。私はこれが正しい方向にあなたを助けることを願っています。

+0

これはPythonでマルチスレッドを処理する方法についての素晴らしい洞察です。私は専門家ではありませんが、C#で同様のことをしました。今これを実装する。 – Youngdev

+0

thxこれはPythonでマルチスレッドを処理する方法に関する素晴らしい洞察です。私は専門家ではありませんが、C#と同様のことをしました。今これを実装することです。おかげで – Youngdev

+0

@ Youngdevあなたは歓迎します、あなたが十分な助けをしたと私が思っている、またはelsesの回答があれば、適切な解決策としてマークすることを忘れないでください!良い一日と最高の運を持っている:) – Torxed

関連する問題