【问题标题】:Flask Button run Python without refreshing page?Flask Button 在不刷新页面的情况下运行 Python?
【发布时间】:2014-03-01 06:11:58
【问题描述】:

我刚刚开始使用 python 和烧瓶(用于树莓派)。我想要一个 web 应用程序,它可以执行一些 python 代码来平移和倾斜相机并显示视频流。

到目前为止,我的烧瓶代码是:

from flask import Flask, render_template
import time
import serial
#ser = serial.Serial('/dev/ttyUSB0',9600)
app = Flask(__name__)
@app.route('/')
@app.route('/<cmd>') #each button in my html redirects to a specified directory
def execute(cmd=None):
    if cmd == "down":
        print "Moving Down"
        #ser.write("D")

    if cmd == "up":
        print "Moving Up"
        #ser.write("U")

    if cmd == "left":
        print "Moving Left"
        # ser.write("L")

    if cmd == "right":
        print "Moving Right"
        #ser.write("R")

    if cmd == "reset":
        print "Reseting.."
        #ser.write("X")

    return render_template("main.html")


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080, debug=True)

问题是我的代码依赖于重定向到新目录的每个按钮,虽然这效果很好,但它每次都会刷新页面,这意味着我的嵌入视频会重新加载并再次缓冲。有没有更好的方法来检测按钮按下然后使用烧瓶执行 python 代码?

【问题讨论】:

  • 为此,您需要使用来自页面上运行的 JavaScript 的 AJAX 调用。

标签: python flask raspberry-pi


【解决方案1】:

我会把它分成两条路线,以便更容易看到你必须做什么:

LEFT, RIGHT, UP, DOWN, RESET = "left", "right", "up", "down", "reset"
AVAILABLE_COMMANDS = {
    'Left': LEFT,
    'Right': RIGHT,
    'Up': UP,
    'Down': DOWN,
    'Reset': RESET
}

@app.route('/')
def execute():
    return render_template('main.html', commands=AVAILABLE_COMMANDS)

@app.route('/<cmd>')
def command(cmd=None):
    if cmd == RESET:
       camera_command = "X"
       response = "Resetting ..."
    else:
        camera_command = cmd[0].upper()
        response = "Moving {}".format(cmd.capitalize())

    # ser.write(camera_command)
    return response, 200, {'Content-Type': 'text/plain'}

然后在你的模板中你只需要使用一些 JavaScript 来发送请求:

{# in main.html #}
{% for label, command in commands.items() %}
    <button class="command command-{{ command }}" value="{{ command }}">
        {{ label }}
    </button>
{% endfor %}

{# and then elsewhere #}
<script>
// Only run what comes next *after* the page has loaded
addEventListener("DOMContentLoaded", function() {
  // Grab all of the elements with a class of command
  // (which all of the buttons we just created have)
  var commandButtons = document.querySelectorAll(".command");
  for (var i=0, l=commandButtons.length; i<l; i++) {
    var button = commandButtons[i];
    // For each button, listen for the "click" event
    button.addEventListener("click", function(e) {
      // When a click happens, stop the button
      // from submitting our form (if we have one)
      e.preventDefault();

      var clickedButton = e.target;
      var command = clickedButton.value;

      // Now we need to send the data to our server
      // without reloading the page - this is the domain of
      // AJAX (Asynchronous JavaScript And XML)
      // We will create a new request object
      // and set up a handler for the response
      var request = new XMLHttpRequest();
      request.onload = function() {
          // We could do more interesting things with the response
          // or, we could ignore it entirely
          alert(request.responseText);
      };
      // We point the request at the appropriate command
      request.open("GET", "/" + command, true);
      // and then we send it off
      request.send();
    });
  }
}, true);
</script>

【讨论】:

  • 嗨,谢谢你的回答,但由于我是 javascript 新手,我真的不明白它是如何工作的,我没有让它工作:/你能告诉我如何处理一个以最简单的方式按下按钮,这将在 python 上打印“X”?我会详细研究。
  • @user3264137 - 加载页面时浏览器的调试控制台中会显示哪些错误? (我假设 that 是破坏性的,而不是后端代码)。
  • 我试过了,但现在当我点击“提交”时,我没有转到新页面,而是得到一个Client disconnected
【解决方案2】:

我也遇到了同样的问题,答案很简单,用ajax XmlHttpRequest:

// send a request, but don't refresh page
xhttp = new XMLHttpRequest();
xhttp.open("GET", "your script action", true);
xhttp.send();

这是一个小例子,调用当前脚本,参数“like”,嵌入在一个函数中:

function likeStuffs()
{
    // send a request, but don't refresh page
    xhttp = new XMLHttpRequest();
    xhttp.open("GET", "?like", true);
    xhttp.send();
}

【讨论】:

    【解决方案3】:

    您可以在 AJAX 的帮助下简单地做到这一点...这是一个调用 python 函数的示例,该函数在不重定向或刷新页面的情况下打印 hello。

    在 app.py 中放下面的代码段。

    //rendering the HTML page which has the button
    @app.route('/json')
    def json():
        return render_template('json.html')
    
    //background process happening without any refreshing
    @app.route('/background_process_test')
    def background_process_test():
        print "Hello"
        return "nothing"
    

    您的 json.html 页面应如下所示。

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script type=text/javascript>
            $(function() {
              $('a#test').bind('click', function() {
                $.getJSON('/background_process_test',
                    function(data) {
                  //do nothing
                });
            return false;
          });
        });
    </script>
    
    
    //button
    <div class='container'>
    <h3>Test</h3>
        <form>
            <a href=# id=test><button class='btn btn-default'>Test</button></a>
        </form>
    
    </div>
    

    在这里,当您按下控制台中的简单测试按钮时,您可以看到“Hello”正在显示,没有任何刷新。

    【讨论】:

      猜你喜欢
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 2023-04-01
      • 2019-11-25
      • 2017-12-21
      • 1970-01-01
      相关资源
      最近更新 更多