首页 > 解决方案 > 在编译代码之前,在 Python 中将用户事件函数值作为字符串返回

问题描述

我有一个拖放 GUI 功能,可以显示文件名并提供文件路径。我正在尝试将该文件路径插入 Pandas 以便稍后进行操作。我的问题是python试图在用户将文件放入函数之前打开路径。我如何告诉它等到用户输入数据后再编译。下面是我正在使用的代码,并将其缩小到我认为的问题所在。如果你能告诉我如何将函数变成一个类,那么我就不必编辑每个输入框的函数了。

import pandas as pd
import numpy as np
import docx
import os
import zipfile
import re
import PyPDF2
from docx2pdf import convert
import csv
from math import *
from pathlib import Path
import statistics
import matplotlib.pyplot as plt
from scipy.stats import linregress, stats
from tkinter import *
from tkinterdnd2 import *
from docx2pdf import convert

    

root = TkinterDnD.Tk()
root.title('Pathfinder')
root.geometry('600x400')
root.config(bg='#039dfc')

 

def drop(event):
    var.set(event.data)
    stringvar = str(event.data) 
    size = len(stringvar)
    res = []  # list of file paths
    name = ""
    idx = 0
    while idx < size:
        if stringvar[idx] == "{":
            j = idx + 1
            while stringvar[j] != "}":
                name += stringvar[j]
                j += 1
            res.append(name)
            name = ""
            idx = j
        elif stringvar[idx] == " " and name != "":
            res.append(name)
            name = ""
        elif stringvar[idx] != " ":
            name += stringvar[idx]
        idx += 1
    if name != "":
        res.append(name)
    file_paths = res
    current_e_box_item = set(e_box.get())
    for file_path in file_paths:
        if file_path.endswith(".XLS"):
            path_object = Path(file_path)
            file_name = path_object.name
            if file_name not in current_e_box_item:
                e_box.insert("end", file_name)
                e_box.delete(0,last=size)
    print(file_name)
    print (res)
    print(file_path)
    print(path_object)
    print(stringvar)
    return file_path # this is what i want


var = StringVar()
e_box = Entry(root, textvar=var)
e_box.place(x=150, y=90, width=180, height=25)
e_box.drop_target_register(DND_FILES)
e_box.dnd_bind('<<Drop>>', drop)


File_as_DF = pd.read_excel(file_path) # This is where it needs to go


def drop2(event):
    var2.set(event.data)
    stringvar2 = str(event.data) 
    print (stringvar2) 
    
var2 = StringVar()
e_box2 = Entry(root, textvar=var2)
e_box2.place(x=150, y=150, width=180, height=25)
e_box2.drop_target_register(DND_FILES)
e_box2.dnd_bind('<<Drop>>', drop2)


def drop3(event):
    var3.set(event.data)
    stringvar3 = str(event.data)
    print(stringvar3)

var3 = StringVar()
e_box3 = Entry(root, textvar=var3)
e_box3.place(x=150, y=200, width=180, height=25)
e_box3.drop_target_register(DND_FILES)
e_box3.dnd_bind('<<Drop>>', drop3)


root.mainloop()

标签: pythonpandasfunctionclasstkinter

解决方案


要回答主要问题——你需要这个:

File_as_DF = pd.read_excel(file_path) # This is where it needs to go

发生在你之后drop(),而不是之前。大概你有一个你想用那个数据框做什么的计划——你的drop()函数应该启动一个做那件事的函数。

对于奖励积分,而不是类,我只需要一个函数来构建一个盒子以及它自己的 drop 函数:

def drop2(event):
    var2.set(event.data)
    stringvar2 = str(event.data) 
    print (stringvar2) 
    
var2 = StringVar()
e_box2 = Entry(root, textvar=var2)
e_box2.place(x=150, y=150, width=180, height=25)
e_box2.drop_target_register(DND_FILES)
e_box2.dnd_bind('<<Drop>>', drop2)


def drop3(event):
    var3.set(event.data)
    stringvar3 = str(event.data)
    print(stringvar3)

var3 = StringVar()
e_box3 = Entry(root, textvar=var3)
e_box3.place(x=150, y=200, width=180, height=25)
e_box3.drop_target_register(DND_FILES)
e_box3.dnd_bind('<<Drop>>', drop3)

变成:

def make_e_box():
    var = StringVar()
    def drop(event):
        var.set(event.data)
        print(event.data)
    e_box = Entry(root, textvar=var)
    e_box.drop_target_register(DND_FILES)
    e_box.dnd_bind('<<Drop>>', drop)
    return e_box

make_e_box().place(x=150, y=150, width=180, height=25)
make_e_box().place(x=150, y=200, width=180, height=25)

推荐阅读