Flask:如何使用ajax将变量打印到网页上



我有以下代码:

import cv2
import numpy as np
import time
import datetime
from flask import *
import random
from threading import Thread

app = Flask(__name__)

def Tracking():
    lower = np.array([35, 192, 65])
    upper = np.array([179, 255, 255])
    video = cv2.VideoCapture(1, 0)
    times = []
    total = 0
    is_round = False
    while True:
        success, img = video.read()
        image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(image, lower, upper)
        blur = cv2.GaussianBlur(mask, (15, 15), 0)
        circles = cv2.HoughCircles(blur, cv2.HOUGH_GRADIENT, 1, 14,
                                   param1=34, param2=10, minRadius=4, maxRadius=10)
        circles = np.uint16(np.around(circles))
        if (len(circles[0, :]) == 7) and not is_round:
            start_time = time.time()
            is_round = True
            curr_count = 0
            round_total = 0
        elif is_round:
            if len(circles[0, :]) == 1:
                end_time = time.time()
                is_round = False
                time_taken = end_time - start_time
                print('time: ', str(
                    datetime.timedelta(seconds=time_taken))[2:7])
                times.append(time_taken)
                average = sum(times) / len(times)
                print('Avg time: ', str(
                    datetime.timedelta(seconds=average))[2:7])
            elif len(circles[0, :]) < 7:
                curr_count = (7 - round_total) - len(circles[0, :])
                total += curr_count
                round_total += curr_count
            for i in circles[0, :]:
                cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
                cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
        yield total  

@app.route("/")
def home():
    return render_template('theme1.html')

gen_total = Tracking()  # initate the function out of the scope of update route

@app.get("/update")
def update():
    global gen_total  
    return str(next(gen_total))

if __name__ == "__main__":
    app.run(debug=True)

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <link rel= "stylesheet"  href= "{{ url_for('static', filename='styles.css')}}">
</head>
<body>
    <div class="data">
    <p id="output"></p>
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script>
        function update(){
            $.get("/update", function(data){
                $("#output").html(data)
            });
        }
        update()
        var intervalId = setInterval(function() {
            update()
        }, 10000);
    </script>
        
</body>
</html>

我正在尝试将变量"average"打印到网页上,我已经将"total"添加到网页中,但我不确定如何添加average,这个变量不会总是有值,因为在给定值之前必须发生某件事,任何帮助都会得到通知。我也不确定是否必须将其转换为要显示的字符串,ajax在html文件中用于每隔一段时间更新页面。

若要从生成器中生成多个值,请使用元组、列表、类、字典或其他数据结构。我建议一个dict,它很简单,但有很好的命名语义。CCD_ 1。

由于average在条件分支内部,因此可能在未实际初始化此变量的情况下达到yield,这是非法的。设置一个无条件地在yield语句范围内的默认值,这样就可以保证它有一个值。

最后,使用Flask的jsonify将其作为JSON而不是文本返回给客户端。

下面是一个可以调整的简化示例:

app.py

from flask import Flask, jsonify, render_template

app = Flask(__name__)

def track():
    total = 0
    average = 0
    while True:
        if 1 == 1:
            average += 2
        total += 1
        yield dict(total=total, average=average)

@app.route("/")
def home():
    return render_template("theme1.html")

@app.get("/update")
def update():
    return jsonify(next(gen_total))

if __name__ == "__main__":
    gen_total = track()
    app.run(debug=True)

templates/theme1.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</head>
<body>
  <div class="data">
    <p id="average"></p>
    <p id="total"></p>
  </div>
  <script>
function update() {
  $.get("/update", function (data) {
    $("#average").text("average " + data.average);
    $("#total").text("total " + data.total);
  });
}
update();
var intervalId = setInterval(update, 10000);
  </script>
</body>
</html>