使用Kivy创建输入对话框

2024-07-03 07:01:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个函数,只返回它的值一旦用户输入文本到一个文本输入和点击一个确定按钮。例如

n = PopupInput("What number should I add?")
print 5+n

我不知道如何编写kivy对话框来暂停执行并等待用户关闭它。在其他GUI工具包中,我会使用类似

^{pr2}$

允许我的代码只停留在一个位置,同时允许GUI框架完成它的工作。但是,我找不到Kivy的等效方法。在

编辑:

这是我失败的尝试(它很混乱)

def PopupOk(text, title='', btn_text='Continue'):
    btnclose = Button(text=btn_text, size_hint_y=None, height='50sp')
    content = BoxLayout(orientation='vertical')
    p = Popup(title=title, content=content, size=('300dp', '300dp'),
                size_hint=(None, None))
    content.add_widget(Label(text=text))
    ti = TextInput(height='50sp', font_size='50sp', input_type='number')
    content.add_widget(ti)
    def _on_d(*args):
        p.is_visable = False
    p.bind(on_dismiss=_on_d)
    p.is_visable = True

    content.add_widget(btnclose)

    btnclose.bind(on_release=p.dismiss)
    p.open()
    while not p.is_visable:
        EventLoop.idle()
   return ti.text

Tags: text用户文本noneaddnumbersizetitle
3条回答

Kivy实际上是围绕事件和异步回调的原则构建的。因为它使用OpenGL并且依赖于在GPU上呈现的帧,而不是CPU,所以您永远不想使用块代码。所以kivy使用事件绑定来规避这个问题。在

这里有一种方法。在

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput


class MainApp(App):
    def build(self):
        self.button = Button(text="Click",
                             on_release=self.get_caption)
        return self.button

    def get_caption(self, btn):
        Popup(title="Enter text here",
              content=TextInput(focus=True),
              size_hint=(0.6, 0.6),
              on_dismiss=self.set_caption).open()

    def set_caption(self, popup):
        self.button.text = popup.content.text

MainApp().run()

你把内容放在一个弹出窗口中,给它一个“set_caption”函数,当它被关闭时调用。你对变化有了回应。不要阻塞。不要等待。在使用线程来阻止wxWidgets中的GUI阻塞之后,我真的认为这是一个更好的方法…;-)

干杯

您所要寻找的可以通过以下代码实现。您需要在主程序中指定例程作为方法:

import kivy
kivy.require('1.5.0') # replace with your current kivy version !
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.app import App
from kivy.clock import Clock

class YourApp(App):

    def build(self):
        return Button(text='Press for popup!', on_press=self.callpopup)

    def callpopup(self, event):
        dlg = MessageBox(titleheader="Titel Header", message="Any Message", options={"YES": "printyes()", "NO": "printno()"})
        print "Messagebox shows as kivy popup and we wait for the \nuser action and callback to go to either routine"

    def printyes(self):
        # routine for going yes
        print "You chose the Yes routine"

    def printno(self):
        # routine for going no
        print "You chose the No routine"

class MessageBox(YourApp):
    def __init__(self, titleheader="Title", message="Message", options={"OK": "self.ok()", "NO": "self.no()"}):

        def popup_callback(instance):
            "callback for button press"
            # print('Popup returns:', instance.text)
            self.retvalue = instance.text
            self.popup.dismiss()

        self.retvalue = None
        self.options = options
        box = BoxLayout(orientation='vertical')
        box.add_widget(Label(text=message, font_size=20))
        b_list =  []
        buttonbox = BoxLayout(orientation='horizontal')
        for b in options:
            b_list.append(Button(text=b, size_hint=(1,.35), font_size=20))
            b_list[-1].bind(on_press=popup_callback)
            buttonbox.add_widget(b_list[-1])
        box.add_widget(buttonbox)
        self.popup = Popup(title=titleheader, content=box, size_hint=(None, None), size=(400, 400))
        self.popup.open()
        self.popup.bind(on_dismiss=self.OnClose)

    def OnClose(self, event):
        self.popup.unbind(on_dismiss=self.OnClose)
        self.popup.dismiss()
        if self.retvalue != None:
            command = "super(MessageBox, self)."+self.options[self.retvalue]
            # print "command", command
            exec command

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

我会从另一个角度来考虑这个问题-你真正想做的是在弹出窗口关闭时打印数字。在

假设您有一个带有textinput的弹出窗口供用户写入,那么您可以执行popup.bind(on_dismiss=some_function)在弹出窗口关闭时运行some_function。这意味着您只需编写一个函数,该函数接受一个弹出窗口,检索文本框文本,并打印出您想要的任何答案。在

我不确定这与你真正想做的事情有多直接契合,但这是一种更自然的方式来配合Kivy的事件系统。如果你有强烈不同的要求,我也许可以用不同的方式回答。在

编辑:看到你的编辑,这几乎就是你要做的,但是我认为尝试用这种方式击败eventloop而不是随波逐流是个坏主意。我将创建一个新函数(正如我上面所说的),它接受textinput并执行您真正想要的任何操作。通过将on_dismiss绑定到该函数,您可以让kivy在以后用户有空关闭弹出窗口时开始计算。在

相关问题 更多 >