【问题标题】:By using tkinter button command, how to pass var from function to local var in main function通过使用 tkinter 按钮命令,如何将 var 从函数传递到主函数中的本地 var
【发布时间】:2020-04-23 03:25:02
【问题描述】:

我是python和Tkinter的新手,乱码请多包涵。

目前我有 2 个按钮(一个是打开文件,第二个是运行)和 1 个文本框(Entry 或 Scrolledtext),我想要做的是

  1. 按下打开文件按钮,文件路径将显示在文本框中,该路径也将保存到main()中的局部变量'a'中。
  2. 当我按下“运行”按钮时,程序将获取变量“a”的最新值并执行其他操作。

我遇到的问题是,当我单击“打开文件”按钮时,这个局部变量“a”无法更新。我搜索了这类问题,得到的答案是我应该使用“全局变量”或“创建一个类并将文件路径视为属性”。但不知怎的,我无法做到。让我把我的代码放在下面。

首先是使用全局变量。我可以通过单击“btn_run”来获取更新的 file1,控制台将打印文件 1 的最新值,但 script_path 无法更新。

附言我也尝试了“trace()”方法。是的,我发现 var.在函数中可以更新,但我如何将这些更新的 var 放入我的局部变量 main 中?好像又回到原点了。


from functools import partial

from tkinter import scrolledtext,INSERT,END,Entry, messagebox, filedialog, ttk, Frame,Button

from os import path

import matplotlib.pyplot as plt

from matplotlib.figure import Figure

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2TkAgg

# Tkagg allows you to draw, navigation bar is to allow you save, zoomm ....the images 
import numpy as np

from tkinter import *

def openfile(txt1):
    global file1
    file1= filedialog.askopenfilename(filetypes=(("all files","*.*"),("Text files","*.txt"),("csv file","*.csv")))
    txt1.insert(0,file1)
#    print (file1)

def print_f1():
    print(file1)

def main ():

    # Create Main window 
    window = Tk()
    file1=''
    window.title("WADC FFT trial")

    window.minsize(1000,600)
    input_str=StringVar()
    input_str.set('')
    # Create Frame for buttons, bars and picts 

    mis_frame = Frame(window)
    mis_frame.grid(column=0, row=0)

    #Create a scrolled text box on mis_frame 
    txt=Entry(mis_frame,textvariable=input_str,width=40)
    txt.grid(column=0,row=0)
    #define openfile

    #Create a button on mis_frame, use lambda to avoid direct invoke the function called     
#    btn_path= Button(mis_frame,text="Open File",command=lambda:openfile(txt1))
    #another workaround is to use partial funciton in python, assign a new func with lesser variables. 
    op_func=partial(openfile,txt)
    btn_path=Button(mis_frame,text='Open File',command=op_func)
    btn_path.grid(column =1,row =0)
    script_path=input_str
    print('script path is '+str(script_path))
    btn_run = Button(mis_frame, text='Run',command=print_f1)

    btn_run.grid(column=3,row=0,padx=100)

    window.mainloop()

if __name__=='__main__':
    main()

第二个自带class属性。这个我只做了1个按钮,可以打开文件并获取文件路径。 关键是我想将此“文件名”传递给局部变量“a”,就像我运行代码一样,它将传递“a”默认值“文件名”并且在我单击“浏览”后不会更新按钮。

感谢您提供的建议,这可能会有所帮助


from tkinter import *

import tkinter as tk

class Canvas(tk.Tk): #inherient from Tkinter.tk
    def __init__(self):
        tk.Tk.__init__(self) #inheritate all attributes that tk has 
        self.filename ='' #declare filepath   
        tk.Button(self, text='Browse', command=self.openfile).grid(column=0,row=0)
    def openfile(self):
        self.filename = filedialog.askopenfilename(title="Open file")

def main ():
    b=Canvas()
    b.title("Test")
    b.minsize(600,400)
    a=b.filename
    print(a)
    b.mainloop()
if __name__=='__main__':
    main()

【问题讨论】:

标签: python python-3.x tkinter


【解决方案1】:

问题

script_path=input_str 

StringVar 分配给script_path,而不是它的值。 要获取值,请使用script_path = input_str.get()


当这条线

a = b.filename

执行时,它会将文件名的默认值分配给a,因为您没有调用openfile


解决方案

要将值传递给全局范围,您既不需要类也不需要全局关键字。 只需使用 tkinter 变量

file1 = StringVar()
def openfile(txt1):
    file1.set(filedialog.askopenfilename(filetypes=( ("all files","*.*"),("Text files","*.txt"),("csv file","*.csv") ) ) )
    txt1.insert(0,file1) 

或者让你的函数返回一些东西。

def openfile(txt1):
    file1 = filedialog.askopenfilename(filetypes=( ("all files","*.*"),("Text files","*.txt"),("csv file","*.csv") ))
    txt1.insert(0,file1) 
    return file1

【讨论】:

    猜你喜欢
    • 2014-06-21
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多