通过onclick调用方法

问题描述 投票:0回答:1

我已经尝试了很多,希望得到任何帮助。

我使用 pytransitions 构建了一个状态机仪表板,并使用 pywebio 构建了一个仪表板。现在我尝试有两个按钮:


def btn_click(btn_val):
    global Lang
    if btn_val=='English':
        Lang=1
        Dashboard.to_Start()

    if btn_val=='German':
        Lang=2
        Dashboard.to_Start()

while True:
    match Dashboard.state:
        case 'Start':
            clear()
            put_buttons(['German', 'English'], onclick=btn_click)
            
            match Lang:
                case 1:
                    put_text("some english text")
                case 2:
                    put_text("some german text")
            Dashboard.ok()
        case 'State2':
            #do this and that
            Dashboard.ok()
        case 'State3':
            #do this and that
            match Lang:
                case 1:
                    name = input("What's your name")
                case 2:
                    name = input("Wie heisst du?")
            

它调用一个函数,可以在其中设置仪表板不同语言的变量。我还希望仪表板在语言更改时完全刷新,也就是我希望状态机将其状态更改为初始状态“开始”。当仪表板像状态 3 一样等待人工文本输入时,也应该发生这种情况。即使在状态 2 和状态 3 下,按钮始终保持在屏幕上。

  1. 不幸的是,当我尝试在函数中执行此操作(方法 to_Start())时,它不起作用。有趣的是,当我在函数中打印状态机状态时,它会在“开始”状态下打印它,但在我们离开该函数后就不再打印了。我理解这与函数中仅处理本地内容有关(定义全局变量时除外)。

  2. 我也尝试过 onclick=Dashboard.to_Start(),但它不起作用,我会遇到下一个问题,那就是我的变量 Lang 需要更改。

我想如果我可以从 onclick 调用函数 btn_click AND Dashboard.to_Start() 那就最好了。或者也许我的整个方法很糟糕,我很乐意听到一些建议。

有人可以解释一下我在这里缺少什么吗?

编辑:我根本没有收到错误消息,或者 pywebio 在仪表板上告诉我“发生了内部错误”。在评论中,我的代码示例受到批评,我尽力改进。

我对此很生气,请帮忙。干杯和问候

python onclick dashboard state-machine pytransitions
1个回答
0
投票

欢迎来到 Stack Overflow,Toben。

由于我无法直接测试您的代码,所以我自己创建了一个 MRE。但首先,一些评论:

A) Switch/match case 语句和状态机

状态机的一个论点是摆脱复杂的 switch/case 语句。如果您使用(轮询)switch/case 语句跟踪机器状态,则机器或 switch/case 可能不是正确的选择。

B) 状态机和 GUI/交互式应用程序:

许多网络和 GUI 框架异步处理用户或网络输入(例如在线程中),并使用/阻止主线程来更改 GUI。此外,大多数状态机实现(包括转换)都不是线程安全的。转换功能

Machine
用于线程,
LockedMachine
用于异步/等待用例。
对于我的最小示例,我将忽略 B),因为线程或异步事件处理是否是更合适的方法取决于所选的框架。但现在让我们面对 A):我们不使用轮询机器的状态,而是使用事件驱动的方法,创建一个控制器来根据用户输入处理 GUI 更改,并将其作为状态模型传递给状态机。机器模型和有状态模型的分离是处理转换的推荐方法。机器可以被视为可用于多个有状态对象的规则手册。

AsyncMachine

当用户单击按钮时,
from pywebio.output import put_text, put_buttons, clear from pywebio import start_server from transitions import Machine # Our GUI controller/stateful model contains all methods that will # alter the GUI and process input events. Each method may receive # input information. class WebIOModel: def on_enter_Start(self, inp=None): # We bind the button's onclick callback to a yet # to be defined "clicked" method. put_buttons(["German", "English"], onclick=self.clicked) put_text("Choose a language") def on_enter_Clicked(self, inp=None): put_text(f"You chose {inp}") def clear_canvas(self, inp=None): clear() # Our simple machine has three states # Pay attention to the state names and the method names of our # WebIOModel: transitions will automatically bind methods to # state events that match the pattern "on_enter_<state>" # and "on_exit_<state>". states = ["Init", "Start", "Clicked"] # We create a transition event named "clicked". # When the state machine is # in state "Start" and "clicked" happens, the machine will transition # to state "Clicked" and also execute callbacks associated with # exiting "Start" and entering "Clicked". transitions = [["clicked", "Start", "Clicked"]] model = WebIOModel() # We tell our machine that it should always execute the model's # callback "clear_canvas" before a state transition. # We use this callback to clear the GUI and reduce redundant code. # Note that for "enter_<state>" callbacks to be called, a state # must be actually entered. However, an "initial" state is not # entered. We create a dummy "Init" state to deal with this. machine = Machine( model, states=states, transitions=transitions, before_state_change="clear_canvas", initial="Init", ) def main(): # Note that events and trigger functions are bound to the model # not the machine! 'to_Start' will enter this state and draw the # buttons model.to_Start() start_server(main, 80)

回调将转发到我们模型的

onclick
事件。由于
clicked
返回一个值,我们的回调链需要能够处理输入。这样
onclick
中的每个回调都有一个可选的
WebIOModel
参数。传递给
input
的值将被转发到处理链中的所有回调。可以在转换/事件处理链的任何状态下调用回调。完整的列表及其执行顺序可以在
文档
中找到。 这不是生产代码,因为它忽略了前面提到的 B)。是否在主线程中对用户输入事件和处理状态更改进行排队,或者是否使用线程安全

clicked

或通过异步/等待对 GUI 事件进行排队,取决于您的架构和

LockedMachine
    

© www.soinside.com 2019 - 2024. All rights reserved.