2017-08-20 3 views
1

これは私がやろうとしていることの最小限のバージョンです。これは私のmain.pyファイルです:Kivy UrlRequestはコールバックを起動しません

class MainScreen(Screen): 
    def __init__(self): 
     super(MainScreen, self).__init__() 
     self.url_input = TextInput() 
     self.start = Button(text='Download') 

     self.start.bind(on_release=partial(self.on_start_press)) 
     self.add_widget(self.url_input) 
     self.add_widget(self.start) 

    def on_start_press(self, *args): 
     DownloadTask(self.url_input.text) 
     ... 

そして、これはDownloadTaskが含まれている私のtask.pyファイルです。

class DownloadTask(object): 
    def __init__(self, url): 
     self.url = url 
     self._get_headers() 

    def _get_headers(self): 
     UrlRequest(url=self.url, on_success=self._on_headers_fetched, method='HEAD') 

    def _on_headers_fetched(self, req, resp): 
     self.content_length = int(req.resp_headers.get('Content-Length')) 

ただし、on_successコールバックが呼び出されることはありません。 urlrequest.pyのライン439上:

if self.on_success: 
    func = self.on_success() 
     if func: 
      func(self, data) 

funcのでコールバックが呼び出されていないNoneです。またself.proxyにアクセスしようとするとweakmethod.pyの47行目がReferenceError: weakly-referenced object no longer existsになります。

try: 
    if self.proxy: 
     return getattr(self.proxy, self.method_name) 
except ReferenceError: 
    pass 
return self.method 

ここで問題は何ですか?私のDownloadTask()オブジェクトはガベージコレクトされていますか?

Environemnt:Pythonの3.5.3、Kivy 1.10.0、マックOS

答えて

2

編集:sourceが明らかにされた後、それはDownloadTaskオブジェクトがガベージコレクトされたように私には見えるのでThreadは走ったことにより、 UrlRequestcalledWeakProxy存在しないオブジェクトのメソッドのために - したがってクラッシュします。


は、それが、ゴミを収集したかどうか私はわからないかどうか、しかし要求は、したがって、あなたは(見つける気軽に)それほど気にはならない、デーモンThread作成します。それについてcommentがあるので、おそらくを収集されません。

しかし、UrlRequestはKivyに強く依存しており、それは表示されますhereです。それはKivy Clockを使用します。これは、Kivyアプリケーションが実行されていない限り、要求がさらに進まない、つまり、停止する必要があることを意味します。on this line。ちょうどprint('something')UrlRequest._dispatch_result()に追加しようとすると、Kivy Clockが点滅していないため、完全に無視されます(したがって、関数は呼び出されません)。

実際のKivyアプリケーションが実行されているこの例では、問題はありません。

from kivy.app import runTouchApp 
from kivy.uix.widget import Widget 
from kivy.network.urlrequest import UrlRequest 

class My(Widget): 
    def __init__(self, **kwargs): 
     super(My, self).__init__(**kwargs) 
     UrlRequest(
      url='http://lipsum.com/', 
      on_error=lambda *args: print('error:', args), 
      on_failure=lambda *args: print('fail:', args), 
      on_redirect=lambda *args: print('redir:', args), 
      on_success=lambda *args: print('success:', args) 
     ) 

runTouchApp(My()) 
+0

実際は 'UrlRequest._dispatch_result()'が呼び出されます。そして、このコードをkivyアプリコンテキストから呼び出さないあなたが見たいと思えばこれがソースです。 https://github.com/eteamin/Exmoore/blob/master/models/task.py これはメインファイルですhttps://github.com/eteamin/Exmoore/blob/master/main.py – Juggernaut

+0

。そして、[この場合](https://github.com/eteamin/Exmoore/blob/b01df0ce5bfab9d38849877f76e3e6e0b2127cab/main.py#L38)あなたの* DownloadTask' *オブジェクトが収集されたと思います。 – KeyWeeUsr

+0

また、コールバックとしてメソッドの代わりに関数を設定した場合、その関数は呼び出されます – Juggernaut

関連する問題