0

So, I have a more a curiosity of how to do something in Tkinter. It's not required but I kind of want to implement it. Anyways, what I want to do is when one of the items in the apSelect Listbox is selected, I want to create one or two multi Listboxes that are then populated from data from a file (for simplicities sake, lets just say it's from a preset list.) In addition to this, I would like to have them disappear if an different entry is selected in apSelect. The other thing, would be then grabbing what ever data is selected in those dynamic Listboxes (assuming they exist). Here is the code that is utilizing Tkinter. Really the only important part is the init_ method (which is probably where I can set up for the dynamic generation) and the generate method (where I will need to pull the data).

class App:
    def __init__(self, master):
        dateFrame= Frame(master)
        dateFrame.pack()
        apSelectFrame = Frame(master)
        apSelectFrame.pack()
        entryFrame = Frame(master)
        entryFrame.pack()
        buttonFrame = Frame(master)
        buttonFrame.pack()

        Label(dateFrame, text="Period:").grid(row=0)
        self.period = Entry(dateFrame)
        self.period.grid(row=0, column=1)
        Label(dateFrame, text="Year:").grid(row=1)
        self.year = Entry(dateFrame)
        self.year.grid(row=1, column=1)

        Label(apSelectFrame, text="Select Report Type:").grid(row=0)
        self.apSelect = Listbox(apSelectFrame, selectmode=SINGLE, height=3)
        self.apSelect.grid(row=1)
        for item in ["Artists", "Publishers", "Both"]:
            self.apSelect.insert(END, item)
        self.allTheThings = IntVar()
        self.checkAll = Checkbutton(apSelectFrame, text="All?", variable=self.allTheThings)
        self.checkAll.grid(row=1, column=1)

        Label(entryFrame, text="Client Name: ").grid(row=0)
        self.client = Entry(entryFrame)
        self.client.grid(row=0, column=1)
        Label(entryFrame, text="Publisher Name: ").grid(row=1)
        self.pub = Entry(entryFrame)
        self.pub.grid(row=1, column=1)

        self.generateBt = Button(buttonFrame, text="Generate!", command=self.generate)
        self.generateBt.pack(side=LEFT)
        self.resetBt = Button(buttonFrame, text="Reset!", command=self.reset)
        self.resetBt.pack(side=LEFT)
        self.quitBt = Button(buttonFrame, text="Quit!", fg="red", command=buttonFrame.quit)
        self.quitBt.pack(side=LEFT)

    def fileChecker(self, filename):
        if(not os.path.isfile(filename)):
            return "Missing file: "+filename+"\n"

    def checkForFiles(self, srFilename):
        errorFlag = False
        errorReport = []    
        errorReport.append(self.fileChecker("albums.csv"))
        errorReport.append(self.fileChecker("clients.csv"))
        errorReport.append(self.fileChecker("composition_copyright_holders.csv"))
        errorReport.append(self.fileChecker("compositions.csv"))
        errorReport.append(self.fileChecker("copyright_holders.csv"))
        errorReport.append(self.fileChecker("track_compositions.csv"))
        #errorReport.append(self.fileChecker("track_copyright_holders.csv"))
        errorReport.append(self.fileChecker("tracks.csv"))
        errorReport.append(self.fileChecker("copyright_holders_previously_owed.csv"))
        errorReport.append(self.fileChecker("artist_override.csv"))
        errorReport.append(self.fileChecker(srFilename))
        if(errorFlag):
            tkMessageBox.showerror("Error",
                "Either select all or enter publisher name!")
        else:
            return

    def generate(self):
        #TODO File checker
        month = self.period.get()
        #month = 'q1'
        year = self.year.get()
        #year = '2012'
        clname = self.client.get()
        pubname = self.pub.get()
        report_type = self.apSelect.curselection()
        #report_type = '1'
        allTheThings = self.allTheThings.get()
        #allTheThings = True
        if len(month)==0:
            tkMessageBox.showerror("Error",
                "You forgot to enter a period!")
            return
        if len(year)==0:
            tkMessageBox.showerror("Error",
                "You forgot to enter a year!")
            return
        if len(report_type)==0:
            tkMessageBox.showerror("Error",
                "You forgot to select a report type!")
            return
        if report_type[0]=='0' and allTheThings==0 and clname=="":
            tkMessageBox.showerror("Error",
                "Either select all or enter a client name!")
            return
        if report_type[0]=='1' and allTheThings==0 and pubname=="":
            tkMessageBox.showerror("Error",
                "Either select all or enter publisher name!")
            return
        if report_type[0]=='2' and allTheThings==0 and clname=="" and pubname=="":
            tkMessageBox.showerror("Error",
                "Either select all or enter a client and publisher name!")
            return
        if(not os.path.exists("reports")):
            os.makedirs("reports")
        if(not os.path.exists('reports/'+month+'_'+year+'')):
            os.makedirs('reports/'+month+'_'+year)
        if(not os.path.exists('reports/'+month+'_'+year+'/artists')):
            os.makedirs('reports/'+month+'_'+year+'/artists')
        if(not os.path.exists('reports/'+month+'_'+year+'/publishers')):
            os.makedirs('reports/'+month+'_'+year+'/publishers')
        if(not os.path.exists('reports/'+month+'_'+year+'/artists/empty')):
            os.makedirs('reports/'+month+'_'+year+'/artists/empty')
        if(not os.path.exists('reports/'+month+'_'+year+'/publishers/empty')):
            os.makedirs('reports/'+month+'_'+year+'/publishers/empty')
        srFilename="sr1_"+month+"_"+year+".csv"
        self.checkForFiles(srFilename)
        tester=ACR_CALC()
        tester.calc(month, year, clname, pubname, report_type, allTheThings,srFilename)

    def reset(self):
        print "RESETING!"
        self.period.delete(0, END)
        self.year.delete(0, END)
        self.allTheThings.set(0)
        self.client.delete(0, END)
        self.pub.delete(0, END)
        self.apSelect.select_clear(0,END)

root = Tk()
app = App(root)
root.mainloop()

1 Answer 1

1

Using the grid geometry manager, you can easily have a widget appear/disappear on a given event, as I did in my example below.

pack has an analogous pack_forget method, but I imagine it might be a little more difficult to have your widget disappear/re-appear in the same place, if it's not confined to a stationary, dedicated frame.

The widget in this code appears/disappears on pressing a button, but this method can be used to make a widget (dis)appear on any event that you'd like, if you understand how to bind events in Tkinter (look up the bind method for more info).

import Tkinter as tk

class App(tk.Frame):
    def __init__(self,master):
        tk.Frame.__init__(self,master)
        self.b=tk.Button(self,text='hide',command=self.hide)
        self.lbl=tk.Label(self,text="This is a label you can hide")
        self.b.grid(row=0,column=0)
        self.lbl.grid(row=0,column=1)

    def hide(self):
        self.lbl.grid_forget()
        self.b.config(command=self.show,text='show')

    def show(self):
        self.lbl.grid(row=0,column=1)
        self.b.config(command=self.hide,text='hide')

if __name__ == '__main__':
    root = tk.Tk()
    f=App(root)
    f.grid(row=0,column=0)
    root.mainloop()

I'm not completely sure that I've answered the whole question here -- there was a lot in your question to sort through...Let me know if you have other questions...

Sign up to request clarification or add additional context in comments.

3 Comments

So would this more or less work for the linkbox as well? Can I add a 'command=' in the initialization of the linkbox and when you select something it runs the command again?
command=func is button specific. However, you can bind arbitrary commands to arbitrary widgets. e.g. MyLabel.bind("<Button-1>",func2) will run func2 whenver you click on the label. (Googling "tkinter bind" should give you lots of info. I particularly like this page: pythonware.com/library/tkinter/introduction/… )
@bagelbits et al.: For a listbox you will want to bind on <<ListboxSelect>> rather than a button event. The reason is too deep to describe in this comment. It is related to the order in which events are processed. For more information, read up on bindtags.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.