如何在使用Kivy UI时使用控制台输入? (与Kivy的Python)

时间:2018-03-09 05:10:14

标签: python input console kivy

问题:

如何在不导致Kivy UI冻结的情况下访问控制台进行输入?

或者,或者,如何轻松地将1,000个输入请求转换为Kivy UI格式? (我对这一点持怀疑态度很快就很容易)

为什么我要这样:

我有一个程序要求用户输入过多的响应。超过1,000个问题。理想情况下,我将所有用户输入嵌套在UI中,但似乎这需要花费太长时间来编程。所以我选择(暂时)让用户参考Python控制台来回答所有问题..

我方法的潜在替代方案:

找到一种简单的方法将控制台输入请求实现为Kivy UI格式......但是要问一千个问题,这种方法似乎相当令人生畏。

当前问题:

当我点击'开始'时,控制台会提示输入。但是,同时,kv应用程序停止响应。这是有道理的。但是,如果用户在没有响应控制台输入请求的情况下单击按钮时它没有崩溃,那就太好了。我不确定如何防止这种情况。

下面是一个可运行的例子......

Python代码:

from kivy.app import App
# kivy.require("1.10.0")
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty, ObjectProperty, NumericProperty

class ScrollableLabel(ScrollView):
    text = "blah blah blah"

class AnotherScreen(Screen):
    text = StringProperty("BEGIN")
    def new(self):
        text = "SEE CONSOLE!"      

class BackHomeWidget(Widget):
    pass

class MainScreen(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("Test_Running_Console.kv")

class MainApp(App):

    def goofytest(self):
        goofy = input("Enter something: ")

    def build(self):
        return presentation

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

Kv代码:

#: import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:
    transition: FadeTransition()
    MainScreen:
    AnotherScreen:

<SmallNavButton@Button>:    
    font_size: 32
    size: 125, 50    
    color: 0,1,0,1

<MedButton@Button>:
    font_size: 30
    size_hint: 0.25, 0.1
    color: 0,1,0,1

<BackHomeWidget>:
    SmallNavButton:
        on_release: app.root.current = "main"
        text: "Home"
        pos: root.x, root.top - self.height

<ScrollableLabel>:
    Label:
        id: dataentryinstructions
        text: root.text
        font_size: 20
        text_size: self.width, None
        size_hint_y: None
        height: self.texture_size[1]
        padding_y: 10
        padding_x: 200

<MainScreen>:
    name: "main"
    FloatLayout: 
        MedButton:
            on_release: app.root.current = "newgarage"
            text: "Create New"
            pos_hint: {"x":0.3728, "top": 0.4}

<AnotherScreen>:
    name: "newgarage"
    ScrollableLabel:
    BackHomeWidget:
    FloatLayout:
        MedButton:
            text: "Begin"
            pos_hint: {"right":1, "top": 1}
            on_release: 
                root.new()
                app.goofytest()
    FloatLayout:
        MedButton
            text: "1. Stuff"
            pos_hint: {"x":0, "top": 0.75}
        MedButton:
            text: "2. Stuff"
            pos_hint: {"x":0, "top": 0.6}
        MedButton:
            text: "3. Stuff"
            pos_hint: {"x":0, "top": 0.45}
        MedButton:
            text: "4. Stuff"
            pos_hint: {"x":0, "top": 0.3}
        MedButton:
            text: "5. Stuff"
            pos_hint: {"x":0, "top": 0.15}

1 个答案:

答案 0 :(得分:1)

input()是一个阻塞任务,由于这些任务阻塞了主线程,因此这些任务对GUI不友好,可能的解决方案是在另一个线程中执行它:

import threading

class MainApp(App):
    def goofytest(self):
        thread = threading.Thread(target=self.input_threading)
        thread.daemon = True
        thread.start()

    def input_threading(self):
        goofy = input("Enter something: ")
        print(goofy)

    def build(self):
        return presentation