python 中的计时器和烧瓶

Timer in python with flask

我正在尝试显示 5 分钟的计时器(例如)。我正在使用烧瓶。 我知道使用 javascript 可能很好,但我真的很想用 python.

我有两个问题:

  1. 第一个问题:计时器的显示 - 要覆盖的问题

我在 python 中为定时器写了一个函数,它应该显示(例如 50 秒): 00:50 然后删除 00:50 并有 00:49,依此类推... 但它正在显示:

00:50
00:49
00:48
...

这是我的代码:screen.py

from flask import Flask, Response, request, render_template, render_template_string, stream_with_context
import time

app = Flask(__name__)
timing=0
@app.route('/content', methods=['POST', 'GET']) # render the content a url differnt from index. This will be streamed into the iframe
def content():
    global timing
    timing = 10
    # if request.form.get("submit"):
        # timing = request.form['timing']
        # print(timing)
    def countdown(t):
        
        while t:
            mins, secs = divmod(t, 60)
            timer = '{:02d}:{:02d}'.format(mins, secs)
            print(timer, end="\r")
            yield timer
            time.sleep(1)
            t -= 1
        # return timer
        
    return app.response_class(countdown(timing)) #at the moment the time value is hardcoded in the function just for simplicity
    # return render_template('display.html')
@app.route('/')
def index():
    value = "Bonjour"
    title_html = value
    return render_template('display.html', message=title_html) # render a template at the index. The content will be embedded in this template

if __name__ == '__main__':
    app.run(use_reloader=False)

我想找到 print(timer, end="\r")yield 的等效项,以便覆盖计时器的值,并且在它递减时看不到所有结果。我希望我的解释清楚。

  1. 第二期:定时器的输入值

如您在我的代码 screen.py 中所见,timing 的值是硬编码的 timing=10。但我想允许用户在输入中输入他想要的值:

if request.form.get("submit"):
    timing = request.form['timing']
    print(timing)

您可以在 screen.py 中看到这些行,我将它们注释掉 timing=10 因为当我写这些行时出现以下错误:

Method Not Allowed
The method is not allowed for the requested URL.
127.0.0.1 - - [02/Aug/2021 12:50:26] "POST / HTTP/1.1" 405 -

这是链接到我的 python 代码的 HTML 代码 display.html:

<!DOCTYPE HTML>
<html>
<head>
    <link rel="stylesheet" href='/static/main.css'/>
    <title>your dish</title>
</head>
<body>
    <h1>{{message}}! Here are some informations about your dish:</h1>
    <h2> countdown </h2>
     
    <!-- <p>{{message}}</p> -->
    <form method="POST" action=".">
        <p><input name="timing" value="{{timing}}" placeholder="Enter your time"></p>
        <input type="submit" name="submit" value="submit">
        
    </form>
    <div>
        <iframe frameborder="0" noresize="noresize"
     style='background: transparent; width: 100%; height:100%;' src="{{ url_for('content')}}"></iframe>
    </div>
</body>
</html>

如何避免此错误并考虑用户在 display.html 的输入字段中输入的值?

我试图在本地 运行 你的脚本,但我不确定你希望在哪里看到计时器;我假设您使用了 here.

中的倒计时功能

我想向您推荐一种不同的方法:使用 iframe 将计数器动态地流式传输到网页:

from flask import Flask, render_template, Response
import time
app = Flask(__name__)

@app.route('/content') # render the content a url differnt from index. This will be streamed into the iframe
def content():
    def timer(t):
        for i in range(t):
            time.sleep(5) #put 60 here if you want to have seconds
            yield str(i)
    return Response(timer(10), mimetype='text/html') #at the moment the time value is hardcoded in the function just for simplicity

@app.route('/')
def index():
    return render_template('test.html.jinja') # render a template at the index. The content will be embedded in this template

if __name__ == '__main__':
    app.run(use_reloader=False)

然后在 html

中您喜欢的位置添加 iframe
<!doctype html>
<head>
    <title>Title</title>
</head>
<body>
    <h2> countdown </h2>
    <div>
        <iframe frameborder="0" noresize="noresize"
     style='background: transparent; width: 100%; height:100%;' src="{{ url_for('content')}}"></iframe>
    </div>
</body>

结果将是您网页上的动态倒计时

倒计时 0123456789

你可以看到它完成得又快又脏here on my repl

虽然它还没有围绕您的应用程序进行调整,(并且在图形上不是特别漂亮)您可以修改函数以接受来自用户的表单输入(我看到您实际上已经在您的应用程序中这样做了),或者也直接调倒数功能。

t = request.form['t']

并在您的 html 表格中添加

<form method="post" action=".">
    <p><input name="t" placeholder="your time"/></p>
    <p><input type="submit" value="Submit"/></p>
</form>

您有相同的路线 @app.route("/") 出现了 3 次。系统将选择第一个仅显示 display.html 的。而且我怀疑这目前还行不通,因为您的页面需要 message, timing 的值,但这些属性在您的第一条路线中不存在。

你应该试试


@app.route("/", methods=['POST', 'GET'])
def display():
    
    page = 'display.html'
    params = {"message":"", "timing":0} # initialize values for both message and timing. These will be returned when user loads the page (a GET call)
    
    if request.method == 'POST':
        timing = request.values.get("timing")
        # do whatever processing you want
        params["timing"]  = <your computed value>
        params["message"] = <your message>
        params["message_2"] = <your other message>

    return render_template(page, **params)


删除 @app.route("/")

的所有其他路线