2016-09-22 9 views
0

Пытается поэкспериментировать и построить класс, разрешающий использование UrlRequest, чтобы проверить, действительно ли данный URL. Оказывается, это немного сложнее, чем предполагалось!Kivy UrlRequest называется классом - методы не выполняются?

Проблема в том, что методы on_success и on_failure/errors, определенные как часть класса, никогда не вызываются. Сценарий бросает следующий вывод (на основе команд печати):

http://www.google.com 
request sent 
URL doesn't work 

Теперь мое подозрение, что I'm получает код возврата («Нет») из метода test_connection, а не connectionSuccess или connectionFailure. Как я могу позвонить, чтобы один из последних дал ответ? Любое предложение приветствуется. Благодарю.

from kivy.app import App 
from kivy.uix.floatlayout import FloatLayout 
from kivy.network.urlrequest import UrlRequest 

class WebExplorer():  
    def test_connection(self, path): 
     self.path = path 
     print (self.path) 
     req = UrlRequest(self.path,on_failure=self.connectionFailure,on_error=self.connectionFailure,on_success=self.connectionSuccess) 
     print ("request sent") 

    def connectionSuccess(self,*args): 
     print ("connectionSuccess") 
     return 0 

    def connectionFailure(self,*args): 
     print ("connectionFailure") 
     return 1 


class MainScreen(FloatLayout): 
    def __init__(self, **kwargs): 
     super(MainScreen, self).__init__(**kwargs) 
     self.address = 'http://www.google.com' 

     if WebExplorer().test_connection(self.address) == 0: 
      print ("URL works") 
     else: 
      print ("URL doesn't work") 

class App(App): 
    def build(self): 
     return MainScreen() 


if __name__ == "__main__": 
    App().run() 

UPDATE 2016-09-27 Я изменил код, и я потратили часы на попытки выяснить проблему. Сначала введите код:

from kivy.app import App 
from kivy.uix.floatlayout import FloatLayout 
from kivy.network.urlrequest import UrlRequest 

class WebExplorer(): 

    def test_connection(self, path): 
     self.path = path 
     req = UrlRequest(self.path,on_failure=self.connectionFailure,on_error=self.connectionFailure,on_success=self.connectionSuccess) 
     req.wait() 
     return (self._return_value) 

    def connectionSuccess(self, req, results): 
     print ("Success") 
     self._return_value = [0,results] 

    def connectionFailure(self, req, results): 
     print ("Failure") 
     self._return_value = [1,results] 


class MainScreen(FloatLayout): 
    def __init__(self, **kwargs): 
     super(MainScreen, self).__init__(**kwargs) 
     self.URLtest = ['http://www.ikea.com/','https://www.google.com','https://www.sdfwrgaeh.com'] 
     for URL in self.URLtest: 
      self.returnCode = WebExplorer().test_connection(URL) 
      if self.returnCode[0] == 0: 
       print ("Correct URL") 
      else: 
       print ("Wrong URL") 

class App(App): 
    def build(self): 
     return MainScreen() 

if __name__ == "__main__": 
    App().run() 

Почему 3 URL? Поскольку один из них «правильный» (IKEA), один из них является перенаправлением (Google), и один из них полностью фиктивный. Оказывается, код работает только для первого. req.wait не работает, когда результат является ошибкой/ошибкой (кстати, у меня нет идеи, какая разница между этими двумя).

Итак, вопрос заключается в том, как сделать процесс req.wait сбоем, альтернативно, как выйти из класса с правильным кодом ошибки. Я считал Clock.schedule_interval периодически проверять статус, ut, поскольку методы события даже не выполняются, когда URL-адрес неверен, мне негде установить мои variales -_-

ответ

0

UrlRequest - это асинхронный, что означает, что фактический запрос обрабатывается в фоновом режиме, пока ваше приложение продолжается. Функции on_failure и т. Д. Являются обратными вызовами, то есть они будут вызываться, когда запрос будет выполнен, но это означает, что возвращаемое значение «потеряно». Возвращаемое значение, которое вы получаете, действительно зависит от функции test_connection.

Вы упомянули в списке рассылки, в котором хотите позвонить корневому URL-адресу, выполните некоторую обработку по тому, что вы вернетесь, а затем выполните новые запросы к субагрузам в зависимости от содержимого и взаимодействия с пользователем.

Следующее должно предоставить скелет для того, что вы пытаетесь сделать.

class WebExplorer 

    def __init__(self, gui): 
     self._visited_urls = [] # to prevent endless redirect loops 
     self._visiting = set() # to check if we are still doing something 
     self.gui = gui # used to display buttons in process_result 

    def get_url(self, url): 
     self._visited_urls.append(url) 
     self._visiting.add(url) 
     UrlRequest(url, 
      on_success=self.process_result, 
      on_failure=self.failure, 
      on_error=self.failure, # what is the difference between failure and error? 
      on_redirect=self.redirect) 

    def redirect(self, req): 
     self._visiting.discard(req.url) 
     self.get_url(req.req_headers["Location"]) # check if correct handling of 3xx 

    def process_result(self, req): 
     self._visiting.discard(req.url) 
     #TODO process the body to extract urls you want to visit 

     box = BoxLayout() 
     for url in urls_you_want_to_visit: 
      button = Button() 
      button.text = url 
      # I'm not sure if the following works due to some scoping oddities 
      # if - no matter which button is pressed - the same url is called 
      # this line is probably at fault 
      button.bind(on_press=lambda: self.get_url(url)) 
      box.add_widget(button) 

     gui.add_widget(box) 

Конечно, еще многое предстоит улучшить. Он также не тестируется, поэтому может содержать ошибки.

+0

Спасибо за ваше время и за предложение использовать req.wait(). Он по-прежнему возвращает «Нет», хотя, как если бы я не ввел код. Я применил изменения, как вы предлагали, и добавил «print (« возвращаемое значение », self._return_value)« прямо перед «return self» ._return_value "метода test_connection. Он возвращает «Нет» –

+0

(не удалось добавить к моему предыдущему комментарию). Я также попытался ввести команду sleep после req.wait(). Он по-прежнему возвращает «Нет». Документация для wait() заключается в том, что процесс возвращается к основному потоку «Этот метод предназначен для использования в основном потоке, и обратный вызов будет отправлен из того же потока, из которого вы звоните», поэтому в теории нет причин, по которым метод on_success не будет вызван, тем самым соответствующим образом устанавливая код возврата. Ошибка? –

+0

Что такое 'req.result'? – syntonym

 Смежные вопросы

  • Нет связанных вопросов^_^