我正在尝试使用 Flask 为桌面应用程序构建 GUI(即在与嵌入式浏览器本地捆绑运行的服务器上运行的 Web 应用程序)。目前看来一切正常,但我想添加一个文件选择器以允许用户选择计算机上的目录。我需要目录的完整路径,因此使用 HTML/JavaScript 打开对话框将不起作用(由于安全限制)。
我尝试做的是在按下按钮时启动 Tkinter 文件对话框这一页。问题是,虽然它似乎确实启动了某些东西,但该过程只是冻结(不显示窗口)并且我被迫终止它,之后页面重定向到“/view_1_actions”并且我收到“错误代码:ERR_EMPTY_RESPONSE” “错误(即 Flask 应用程序仅在我杀死看似对话框窗口的内容后才会崩溃)。
这是我的代码:
HTML:
<form action="/view_1_actions" method="post">
<input type="submit" name="submit" value="Select"></input>
</form>
Python:
from flask import Flask, request, redirect
from Tkinter import Tk
from tkFileDialog import askdirectory
@app.route('/view_1_actions', methods = ['POST'])
def view_1_actions():
if request.form['submit'] == 'Select':
Tk().withdraw()
dirname = askdirectory()
return redirect('/')
这确实是一个相当奇怪的场景,因为您不会通常不会在“服务器端”启动图形界面,但我的问题是是否有一种方法可以解决此问题,或者是否有一种替代解决方案可以用来显示文件选择器对话框(最好是每个操作系统的本机对话框)。
你指出了问题的关键:在 Flask 服务器上运行的 Web 服务器的上下文中混淆了服务器端代码和客户端代码。虽然你的 Flask 应用是用 Python 编写的(Tkinter 也是如此),但这并不意味着你可以直接从 Flask 路由打开一个 Tkinter 对话框。Flask 路由的目的是处理 HTTP 请求并发送回 HTTP 响应(比如 HTML 页面、JSON 数据等)。
你不能做的是 直接从 Flask 路由打开一个“客户端”文件选择器对话框。
你可以做的是 利用 HTML 文件输入元素,并将其设置为允许选择文件夹:
HTML (index.html):
<!DOCTYPE html>
<html>
<head>
<title>选择文件夹</title>
<script>
function submitForm() {
document.getElementById('folderForm').submit();
}
</script>
</head>
<body>
<form id="folderForm" action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" id="folderInput" name="folder" webkitdirectory="" directory="" multiple/>
<br>
<button type="button" onclick="submitForm()">上传</button>
</form>
</body>
</html>
Python (app.py):
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload():
if 'folder' in request.files:
folder = request.files['folder']
# folder 在这里是一个 FileStorage 对象
# 你可以像处理任何其他上传文件一样处理它
print(f"选中的文件夹: {folder.filename}")
# 进一步处理文件夹(例如,保存、读取内容等)
else:
return "没有选择文件夹"
return '文件上传成功!'
if __name__ == '__main__':
app.run(debug=True)
说明:
- HTML 文件输入:
-
<input type="file" webkitdirectory directory multiple />
创建了一个文件输入元素,webkitdirectory
和directory
属性使它能够选择文件夹。 -
multiple
属性允许选择多个文件夹(如果需要)。 -
JavaScript 提交:
-
我们使用一个简单的 JavaScript 函数
submitForm()
来提交表单,因为点击文件输入按钮选择文件夹不会自动提交表单。 -
Flask 路由:
-
/upload
路由处理上传。 -
我们检查
request.files
中是否存在名为 'folder' 的文件。 -
如果找到了,我们就可以访问
folder
对象,它是一个FileStorage
对象,代表选中的文件夹。你可以获取它的文件名和其他元数据。
重要说明:
-
此方法依赖于现代浏览器对
webkitdirectory
和directory
属性的支持。 - 由于安全限制,你只能访问用户明确选择的文件夹,而不能访问整个文件系统。
- 你需要一种方法来处理上传的文件夹,比如将它们保存在服务器上或读取它们的内容。
这种方法提供了一种更安全、更符合 Web 标准的方式来让用户在你的 Flask 应用程序中选择文件夹。
标签:python,python-2.7,flask From: 23775211