0

我创建了一个函数,它应该在列表框中获取用户选择,并填充它们的列表。然后我希望能够在函数之外访问这个列表,但我不知道该怎么做。我知道我应该调用该函数,但我对如何将任何内容传递给它感到困惑.. 这是我的代码

def usr_fc(*events):
   UsrFCList = []
   selctd_indices = lbox.curselection()
   lst_select = list(selctd_indices)
   for i in lst_select:
     UsrFCList.append(lbox.get(i))
   lbox.quit()

我已经编辑了这个以包含我到目前为止的所有代码:

#import modules and functions
import arcpy
import tkFont
from Tkinter import *

#create entry widget and get/set variable/workspace with function 'set_wkspc'
def set_wkspc():
  wk = e_ws.get()
  arcpy.env.workspace = wk
  e_ws.quit()

wk_input = Tk()

e_ws = Entry(wk_input, width=75)
e_ws.pack()

e_ws.focus_set()

b = Button(wk_input, text="choose workspace", width=15, command=set_wkspc)
b.pack()

mainloop()

#function to list all feature classes within specified workspace
def getFC(ws):
  ws = arcpy.env.workspace
  FCList1 = []
  FCList2 = []
  fcs1 = arcpy.ListFeatureClasses()
  FCList1.append(fcs1)
  fds = arcpy.ListDatasets()
  for fd in fds:
    arcpy.env.workspace = ws + '/'  + fd
    fcs2 = arcpy.ListFeatureClasses()
    FCList2.append(fcs2)
  FCList1.extend(FCList2)
  return FCList1

x = arcpy.env.workspace

lb_list = getFC(x)

#new Listbox class and function that sets up a listbox size according to its contents
class AutoSzLB(Listbox):
def autowidth(self,maxwidth):
    f = tkFont.Font(font=self.cget("font"))
    pixels = 0
    for item in self.get(0, "end"):
        pixels = max(pixels, f.measure(item))
    # bump listbox size until all entries fit
    pixels = pixels + 10
    width = int(self.cget("width"))
    for w in range(0, maxwidth+1, 5):
        if self.winfo_reqwidth() >= pixels:
            break
        self.config(width=width+w)

#list variable for user's choice of feature classes and a function that creates
#list of chosen feature classes

def usr_fc(*events):
  UsrFCList = []
  selctd_indices = lbox.curselection()
  lst_select = list(selctd_indices)
  for i in lst_select:
    UsrFCList.append(lbox.get(i))
  lbox.quit()

#generate scrollbar, execute button and listbox of feature classes to select
#for analysis
fc_lb = Tk()
scrollbar = Scrollbar(fc_lb)
scrollbar.pack(side=RIGHT, fill=Y)
lbox = AutoSzLB(fc_lb,selectmode=EXTENDED)
for item in lb_list:
  lbox.insert(END, *item)

button = Button(fc_lb, text="Analyze selected feature classes", command=usr_fc)

lbox.autowidth(250)
lbox.pack()
button.pack()

#attach listbox to scrollbar
lbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=lbox.yview)

mainloop()

#create entry widget and set workspace for analysis output
def set_out_wkspc():
  wk = out_ws.get()
  ident_ouput_path = wk
  out_ws.quit()

out_wk = Tk()

out_ws = Entry(out_wk, width=75)
out_ws.pack()

out_ws.focus_set()

b2 = Button(out_wk, text="set output workspace", width=20, command=set_wkspc)
b2.pack()

mainloop()
4

1 回答 1

1

这是快速修复:

UsrFCList = []  # You've added this name to the module-level namespace.

def usr_fc(*events):
   selctd_indices = lbox.curselection()
   lst_select = list(selctd_indices)
   for i in lst_select:
     UsrFCList.append(lbox.get(i))  # The interpreter looks for UsrFCList in the local function namespace, and since you're not assigning to that name, it look at the next biggest namespace, which is the module namespace.
   lbox.quit()

# You should now have access to any data you put in UsrFCList, outside the usr_fc function.

但是,处理此问题的最佳方法是重写代码,以便 GUI 的内部数据、小部件和回调函数位于它们自己的类中。这样他们就可以共享一个类命名空间,所以他们可以像UsrFCList. 从长远来看,如果你想制作任何复杂的 GUI,你会想要做一些我在下面概述的事情。

在不重写整个代码的情况下,它大致如下所示:

class App:
    def __init__(root, self):
        # initialize your class with all your widgets
        self.fc_lb = root
        self.button = Button(fc_lb, text="Analyze selected feature classes", command=lambda *events:self.usr_fc(*events))
# Note  ^^^^ all your widgets and data will be accessible through the `self` reference to your GUI instance.
        self.UsrFCList = []
        self.lbox = AutoSzLB(self.fc_lb,selectmode=EXTENDED)
        # . . . you'd have to add all the other setup required to make your GUI

    def usr_fc(self, *events):
    #          ^^^^ you now have access to everything in the instance namespace available inside usr_fc 
        self.UsrFCList = []
        selctd_indices = lbox.curselection()
        lst_select = list(selctd_indices)
        for i in lst_select:
            self.UsrFCList.append(lbox.get(i))
        self.lbox.quit()

    # . . . and you'd add all the other functions that need to work with internal GUI widgets/data 

rootWindow = Tk()
newGUI = App(rootWindow)  # Create a new GUI instance
rootWindow.mainloop()

# Hopefully that gives you the idea.
于 2013-08-21T02:46:33.680 回答