gpt4 book ai didi

python - Kivy:弹出窗口被主线程阻塞

转载 作者:太空宇宙 更新时间:2023-11-04 05:15:38 25 4
gpt4 key购买 nike

我的 Kivy 应用程序有一个按钮,其回调涉及 UrlRequest .我想提供一个弹出窗口,要求用户在请求完成时等待。问题是执行请求本身会阻止弹出窗口出现。我试过放置 open()在不同地方弹出窗口的方法没有运气。在以下示例中,弹出窗口在 on_progress() 中打开UrlRequest 的回调:

from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.garden.navigationdrawer import NavigationDrawer
from kivy.network.urlrequest import UrlRequest
from kivy.uix.popup import Popup
from kivy.uix.label import Label
import urllib

kv = '''
<ScreenTemplate@SignUpScreen>:
canvas:
Color:
rgb: (0.09,0.65,0.8)
Rectangle:
pos: self.pos
size: self.size

Button:
size_hint: .3, .2
pos_hint: {'center_x': .5,'center_y': .25}
text: 'Call Request'
# on_press: app.p.open()
on_release: app.callback1()
Label:
text: 'This is ' + root.name
font_size: '50sp'

<MyNavDrawer>:
BoxLayout:
orientation: 'vertical'
size_hint_y: .25
pos_hint: {'center_y':.5}
Button:
text: 'Screen 1'
on_press: app.callback2( 'screen1')
Button:
text: 'Screen 2'
on_press: app.callback2('screen2')
SMRoot:

<SMRoot>:
ScreenTemplate:
name: 'screen1'

ScreenTemplate:
name: 'screen2'
'''

Builder.load_string(kv)
class SMRoot(ScreenManager):
pass

class SignUpScreen(Screen):
pass

class myNavDrawer(NavigationDrawer):
pass

class myApp(App):

popup_opened = False
p=Popup(title="Posting request...",
content=Label(text="... Please wait"),
size=(100, 100),
size_hint=(0.5, 0.5),
auto_dismiss = False)
def build(self):
self.mynavdrawer = myNavDrawer()
return self.mynavdrawer

def on_success(self, req, results):
print 'In on_success: '+ results
self.p.title = 'Success'
self.p.content = Label(text=results)
self.p.auto_dismiss = True
popup_opened = False


def on_failure(self, req, results):
self.p.title = 'Failure'
self.p.content = Label(text=results)
print 'In on_failure: '+ results
self.p.auto_dismiss = True

def on_error(self, req, results):
self.p.title = 'Error'
self.p.content = Label(text=results.strerror)
print 'In on_error: '+ results.strerror
self.p.auto_dismiss = True

def on_progress (self, req, results, chunk):
if not self.popup_opened:
print 'In on_progress: '+ str(results)
self.p.open()
self.popup_opened = True


def callback1(self):
params={'show_env':'1'}
params = urllib.urlencode(params)
headers = {'Content-type': 'application/x-www-form-urlencoded',
'Accept': 'text/plain'}
url = 'https://httpbin.org/get'
req = UrlRequest(url,
self.on_success,
req_body = params,
req_headers = headers,
on_failure=self.on_failure,
on_error=self.on_error,
on_progress=self.on_progress,
timeout=4)
req.wait()
print 'After UrlRequest'


if __name__ == '__main__':
myApp().run()

运行此命令会导致弹出窗口在请求完成后出现,这违背了目的。

注意注释 on_press: app.p.open()<ScreenTemplate@SignUpScreen>下的Button中绑定(bind).这非常有效,除了它是一种远非理想的解决方法。我希望在 UrlRequest 时随时打开弹出窗口已发送;上述解决方法必须应用于每个按钮。

任何关于如何在回调运行时从主线程打开按钮的想法将不胜感激。我试过使用 Clock.schedule_once()以及。来自docs ,似乎EventDispatcher.dispatch()可能会成功,但我不知道要发送什么事件。

最佳答案

我认为这一行:

  req.wait()

在主线程上阻塞你。去掉它。您还可以更快地打开弹出窗口 - 而不是 req.wait()

也就是说,您可以使用 delayable(来自 kivyoav)复制此行为

@delayable
def callback1(self):
...
while not reg.is_finished:
yield 0.02 # sleep for 20 ms...

... #req is ready now...

免责声明:我是kivyoav的作者

关于python - Kivy:弹出窗口被主线程阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41777106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com