我正在创建一个基本的 Flask 应用程序来展示我在 python 中为了好玩而完成的愚蠢的迷你项目(最初是为 CLI 创建的)。其中之一是可视化约翰·康威的生命游戏 (GOL) 的程序。如果你不知道那是什么,你不需要知道,只需知道它是一个不断变化的二进制矩阵即可。
用户提交一个表单,指定网格大小的整数和 0 到 1 之间的浮点数以自动生成初始状态下活细胞的密度,我希望网格显示在表单下方并切换到每 0.1 秒进入下一个状态(不刷新页面)。
我对 Vanilla Python 和 HTML 有相当多的了解,但我是 Flask 新手,对 JavaScript 一无所知。我 ChatGPTed 了一些我认为可以工作的 JS,但是提交后表单下方没有任何显示。附带说明一下,如果可能的话,我希望在提交表单之前不要开始查询 Flask,而 ChatGPT 的 JS 不会这样做。以下是与应用程序的 GOL 部分相关的代码:
在app.py中:
import game_of_life
from markupsafe import Markup
game = None
@app.route("/create_GOL", methods=['post'])
def create_game():
density, size = request.form['density'], request.form['size']
global game
# initializes game in GameOfLife class
game = game_of_life.GameOfLife(int(size), float(density))
return render_template("index.html")
@app.route("/next_state", methods=['get'])
def next_state():
# runs method to update "game" to the next state in-place
game.find_next_state()
# returns the HTML-friendly version of the matrix
return Markup('<br>'.join(''.join((' ', '██')[j] for j in i) for i in game.m))
在index.html中:
<form action="create_GOL", method="post">
<label for="density">Density (0-1): </label>
<input type="number" name="density", step="any", min=0, max=1>
<label for="size">Size: </label>
<input type="number" name="size", min=1, max=100>
<input type="submit" value="Submit">
</form><br>
<div id="game-state"></div>
<script>
function updateGameState() {
fetch('/next_state')
.then(response => response.json())
.then(data => document.getElementById('game-state').innerText = data.state)
}
setInterval(updateGameState, 100);
</script>
我应该如何修改我的代码: 1.实际展示一些东西 2. 在表单实际提交之前不要浪费查询
或者,我应该使用不同的方法吗?
好的,所以您的代码中几乎没有问题。
您还没有发布带有路由“/”的Python代码,我假设它返回index.html。
当您提交表单并点击“create_GOL”路线时,您再次发送相同的 index.html 文件,该文件会重置更新循环,因此您看不到任何内容。提交事件后,您立即开始下一个循环,而无需初始化游戏。
我已经修改了 python 和 javascript 代码,这应该可以工作(我在随机二维数组上测试了它)
from flask import Flask,render_template,request, jsonify
import numpy as np
app = Flask(__name__)
game = None
@app.route('/')
def index():
return render_template('index.html')
@app.route("/create_GOL", methods=['post'])
def create_game():
global game
jsonData = request.get_json()
density, size = float(jsonData['density']), int(jsonData['size'])
game = game_of_life.GameOfLife(size,density)
return {
'response' : 'Created'
}
@app.route("/next_state", methods=['get'])
def next_state():
global game
game.find_next_state()
ret = '<br>'.join(''.join((' ', '██')[j] for j in i) for i in game.m)
return jsonify(ret)
<body>
<form action="create_GOL" , method="post" onsubmit="doSubmit();return false">
<label for="density">Density (0-1): </label>
<input id='density' type="number" name="density" , step="any" , min=0, max=1>
<label for="size">Size: </label>
<input id='size' type="number" name="size" , min=1, max=100>
<input type="submit" value="Submit">
</form><br>
<div id="game-state"></div>
<script>
function updateGameState() {
fetch('/next_state')
.then(response => response.json())
.then(data => { document.getElementById('game-state').innerHTML = data })
}
function doSubmit() {
const jsonData = { density: document.getElementById('density').value, size: document.getElementById('size').value };
// Set up options for the fetch request
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json' // Set content type to JSON
},
body: JSON.stringify(jsonData) // Convert JSON data to a string and set it as the request body
};
fetch('/create_GOL', options);
setInterval(updateGameState, 1000);
}
</script>
</body>