【问题标题】:How to give the location of "Input" and "Output" for a python code using User Interface and run the code from UI itself?如何使用用户界面为 python 代码提供“输入”和“输出”的位置并从 UI 本身运行代码?
【发布时间】:2019-04-21 17:39:50
【问题描述】:

我有一个 python 代码:

import gdal
import numpy
from skimage.filters import threshold_otsu
ds = gdal.Open('A:\\algo\\f2.tif')

在这段代码中,第 4 行给出了“输入文件”的位置/路径,第 10 行给出了“输出文件”的位置。

我想创建一个用户界面以在用户界面本身中提供此位置并从用户界面本身运行代码。

我尝试使用“tkinter”模块制作用户界面:

from tkinter import *
from tkinter import filedialog
def input():
    file1 = filedialog.askopenfile()
    label = Label(text=file1).pack()
def input2():
    file2 = filedialog.asksaveasfile(mode="w", defaultextension=".tif")
    label = Label(text=file2).pack()    
w = Tk()
w.geometry("500x500")
w.title("FLOOD_MAPPER")
h = Label(text = "S1A FLOOD MAPPER", bg = "yellow", fg = "black", height = "3", width = "500")
h.pack()
i1 = Label(text = "Input*")
i1.place(x=10, y=70)
i1b = Button(w, text = "Select File", command =input)
i1b.place(x=250, y=70)
i2 = Label(text = "Intermediate Product*")
i2.place(x=10, y=140)
i2b = Button(w, text = "Save as", command =input2)
i2b.place(x=250, y=140)
button = Button(w, text="Generate Map", bg = "red", fg = "black", height = "2", width="30")
button.place(x=150, y=400)
w.mainloop()

但我不明白如何链接这两个代码。

当我单击用户界面中的“生成地图”按钮时,我希望用户界面框中给出的输入和输出的位置/路径移动到第一个代码中各自的位置,然后自动运行相同的代码.

请帮助我实现我的要求。

【问题讨论】:

  • 把你的代码放在函数中,即。 def my_code() 并点击按钮 Button( command=my_code)
  • @furas 如果我这样做,它会做什么。
  • 当你按下按钮时它会运行你的代码。
  • @没关系。传递输入和输出位置呢?

标签: python user-interface tkinter


【解决方案1】:

它可能看起来像这样。我删除了只保留 tkinter 中的重要元素。

我将代码放在your_code 中,它可以获取文件名作为参数。所以这段代码看起来和以前一样。

我创建了函数gen_map,它使用分配给全局变量input_filename、`output_filename 的文件名运行your_code

我将gen_map 分配给按钮Button( command=gen_map),以便在您按下按钮时运行它。

其他按钮打开对话框以获取文件名并分配给全局变量input_filenameoutput_filename

from tkinter import *
from tkinter import filedialog

import gdal
import numpy
from skimage.filters import threshold_otsu

def your_code(input_file, output_file):

    #ds = gdal.Open('A:\\algo\\f2.tif')

    ds = gdal.Open(input_file)

    band = ds.GetRasterBand(1)
    arr = band.ReadAsArray()
    thresh = threshold_otsu(arr,16)
    binary = arr > thresh
    driver = gdal.GetDriverByName("GTiff")

    #outdata = driver.Create("A:\\algo\\test11.tif", 14823, 9985, 1, gdal.GDT_UInt16)
    outdata = driver.Create(output_file, 14823, 9985, 1, gdal.GDT_UInt16)

    outdata.SetGeoTransform(ds.GetGeoTransform())
    outdata.SetProjection(ds.GetProjection())
    outdata.GetRasterBand(1).WriteArray(binary)
    outdata.GetRasterBand(1).SetNoDataValue(10000)
    outdata.FlushCache() ##saves to disk!!

    #outdata = None
    #band = None
    #ds = None

def get_input_filename():
    global input_filename

    # `askopenfilename` instead of `askopenfile` to get filename instead of object file
    input_filename = filedialog.askopenfilename()
    input_label['text'] = input_filename

def get_output_filename():
    global output_filename

    # `asksaveasfilename` instead of `asksaveasfile` to get filename instead of object file
    output_filename = filedialog.asksaveasfilename(defaultextension=".tif")
    output_label['text'] = output_filename

def gen_map():
    #global input_filename
    #global output_filename
    print('input:', input_filename)
    print('output:', output_filename)

    your_code(input_filename, output_filename)

#---------------------------------------------
# global variables with default values at start

input_filename = 'A:\\algo\\f2.tif'
output_filename = "A:\\algo\\test11.tif"

root = Tk()

#input_label = Label(root, text=input_filename)
input_label = Label(root, text="Input*")
input_label.pack()

input_button = Button(root, text="Select File", command=get_input_filename)
input_button.pack()

#output_label = Label(root, text=output_filename)
output_label = Label(root, text="Intermediate Product*")
output_label.pack()

output_button = Button(root, text="Save as", command=get_output_filename)
output_button.pack()

gen_map_button = Button(root, text="Generate Map", command=gen_map)
gen_map_button.pack()

root.mainloop()

【讨论】:

  • 你能解释一下 def gen_map() 中发生了什么:
  • 当您使用对话框选择文件时,请将文件名保留在 Viarables input_filenameoutput_filename 中。 gen_mapinput_filenameoutput_filename 获取文件名并使用这些文件名运行函数 you_code。您的代码获取这些文件名并使用它们来读取和写入数据。 command= 需要不带 () 和参数的函数名称,所以我无法指定 command= your_code(input_filename, output_filename) - 这就是我创建 gen_map 以将其分配为 command=gen_map 的原因
  • 遇到以下错误:Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\Anaconda3\lib\tkinter\__init__.py", line 1702, in __call__ return self.func(*args) File "<ipython-input-4-675a3c59d479>", line 50, in gen_map your_code(input_filename, output_filename) File "<ipython-input-4-675a3c59d479>", line 21, in your_code outdata = driver.Create(output_file, 14823, 9985, 1, gdal.GDT_UInt16) File "C:\Users\Anaconda3\lib\site-packages\osgeo\gdal.py", line 1743, in Create return _gdal.Driver_Create(self, *args, **kwargs) RuntimeError: not a string
  • 我在一小时前将asksaveasfile 更改为asksaveasfilename - 也许您使用的是旧版本。 asksaveasfilename 给出文件名,asksaveasfile 给出目标文件(open(selected_filename) 的结果)。您的代码需要第一个 - asksaveasfilename - 给出文件名,而不是文件对象。
  • 您可以添加Label 并更改其中的文字。在当前代码中,我更改 Label 中的文本以显示选定的文件名。 Tkitner 也有 progressbar 但如果您开始长时间运行的过程,则 mainloop 等待其结束并且无法更新进度条(并且它也无法响应单击的按钮或更新标签或状态栏中的文本。)
猜你喜欢
  • 2016-08-12
  • 2017-07-30
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
相关资源
最近更新 更多