gracecai

Tkinter GUI Disconnect with ArcGIS Script Interface

Discussion created by gracecai on Jun 6, 2011
Latest reply on Dec 22, 2011 by timatwork
I'm working on a script that allows the user to set various parameters on multiple datasets and does some geoprocessing on the data based on said user defined parameters. I've created a simple GUI for taking in the parameters using Tkinter. Things work fine when testing in IDLE but when I import the script into a tool box and try to run from there, the interface falls apart. By that I mean, what is suppose to be a multi-paged widget (using "back" and "next" buttons to flip through) comes up separately. But more importantly, it won't allow any text inputs. The text boxes are there but it seems that the widgets are competing against the processes run by Arc in running the script.  The cursor never stays long enough for text to be entered. Check-boxes work.

Here's the code I'm not sure if it'll help.

import os, sys, arcpy
from Tkinter import *

if len(sys.argv) > 1:
    vdata = sys.argv[1]# get list of datasets from the script UI
    rdata = sys.argv[2]
    outDir = sys.argv[3]

else:
    vdata = [...]
    rdata = [...]
    outDir = "C:\Users\..."
    
taskList={} #params for all the datasets are stored here, with datapath as key
task = {} #params for each dataset is stored 
log = "C:\Users\...\log.txt"
file = open(log, 'w')

class VectorHandle(Frame):
    
    def __init__(self, root, source):
        Frame.__init__(self, root)
       
        Label(self, text="Data source \n"+ source).pack()

        Label(self, text="Weight").pack()
        weight = Entry(self)
        weight.pack()

        Label(self, text="Season (if left empty, this constraint is applicable all year)").pack()
        season = []
        spring = Checkbutton(self, text='spring', command= lambda: self.season('spring', season))
        summer = Checkbutton(self, text='summer', command= lambda: self.season('summer', season))
        fall = Checkbutton(self, text='fall', command= lambda: self.season('fall', season))
        winter = Checkbutton(self, text='winter', command= lambda: self.season('winter', season))
        spring.pack() 
        summer.pack()
        fall.pack()
        winter.pack()
            
        Label(self, text="Feature membership").pack()
        featMem = Entry(self)
        featMem.pack()

        Label(self, text="Function").pack()
        var = IntVar()
        var.set("buffer")
        funcDropdown = OptionMenu(self, var, "buffer", "ring", command = self.setFunction)
        funcDropdown.pack()
        Button(self, text="Edit", command = lambda: self.setFunction).pack()
                
        Button(self, text="Commit", command = lambda: self.commit(source, temp)).pack(side = BOTTOM)

    def season(self, s, season):
       ......

    def setFunction(self, event):
        ....
                    
    def commit(self, source, temp): #updates the updates the params of a task
        task["weight"] = weight.get()
        task["season"] = season
        task["type"] = 'v'
        task.update(temp)
        taskList[source] = str(task)       
        task.clear


class RasterHandle(Frame):
 #same idea as VectorHandle
    
class Application(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)
        self.root = root
        self.page = 0
        self.pages = [VectorHandle(self, source) for source in vdata]
        self.pages_raster = [RasterHandle(self, source) for source in rdata]
        self.pages.extend(self.pages_raster)
        self.pages[self.page].pack(side=TOP)
        Button(self, text="Next", command= self.next).pack(side=RIGHT)
        Button(self, text="Back", command= self.back).pack(side=LEFT)
        Button(self, text="Go", command= lambda: self.main(root)).pack(side=BOTTOM)
        

    def next(self):
        self.pages[self.page].pack_forget() #remove the current page
        self.page += 1
        if self.page >= len(self.pages): 
            self.page = 0
        self.pages[self.page].pack(side=TOP) #add the next one

    def back(self):
        self.pages[self.page].pack_forget() #remove the current page
        self.page -= 1
        if self.page < 0: 
            self.page = 4
        self.pages[self.page].pack(side=TOP) #add the next one

    def main(self, root):
        self.destroy
        for dataset in taskList:
            logMsg = str(dataset) + "\n" + str(taskList[dataset]) +"\n"
            file.write(logMsg)
        file.close()



if __name__ == "__main__":
    root = Tk()
    root.title("Cost Surface Generator")
    app = Application(root)
    app.mainloop()

Outcomes