On Wed, 26 Jul 2006 12:46:39 +0200, H J van Rooyen <[EMAIL PROTECTED]> wrote:
> Hi, > > I am struggling to get the pack method to do what I intend. > I am trying to display user input in a seperate window, along with > a little description of the field, something like this: > > Current entry > Company : entered co. name > First entry : entered stuff > The second entry: more entered stuff > Entry number three : Last entered stuff You won't be able to do that kind of layout with pack. This is - quite obviously IMHO - a job for grid, since your widgets are arranged in a grid. According to my experience, pack should only be used for *very* simple layouts, such as all widgets in a single row or in a single column. Trying to do anything else will very soon end up being a nightmare, with unneeded frames everywhere. Learn to use grid and life will be far easier for you. [snip] A few comments on your code: > #!/usr/bin/python > # The original of this module is supposed to do an accounting entry - > > # we get the gui stuff > > from Tkinter import * > > class Entryscreen(Frame): Why do you inherit from Frame? Apparently, you're trying to do a window. A Frame is not a window; it's a general-purpose container for widgets. If you want to do a window, inherit from Tk (for a main window) or from Toplevel (for any other). > """This screen is used to construct a new Entry.""" > > # we define the variables we use > > des_string = '' # Description of what we want to do > req_string = '' # Prompt string > dis_string = '' # Description of field for display > > Company = "New Entry Screen" # we dont have a company yet > Entry_1 = '' # or any entries > Entry_2 = '' > Entry_3 = '' > > def start_new(self): > """This is the routine that assembles a new record""" > > if self.Company == "New Entry Screen": # if its the first time, > > # we make a new window > > show = Tk() No, we don't. We actually create a whole new tcl/tk interpreter environment, completely independent from the one we already have, which happens to create a new main window. Doing so is bound to cause problems later. If you want to create a new window, instantiate Toplevel. > show.title('Accounting entry display window') > > # we get an instance to display results in > > self.disp = Showscreen("Current entry",master=show) > > # then we ask for the company: > > des_string = "Getting the Company " > req_string = "Enter the Company for this session" > dis_string = 'Company:' > error = self.GetEntry(des_string, req_string, dis_string, > self.disp) > self.Company = self.Amount > > # Then or else we ask for entry details > > des_string = "Getting first entry" > req_string = "Enter first field" > dis_string = "First entry:" > error = self.GetEntry(des_string, req_string, dis_string, > self.disp) > > des_string = "Getting second entry" > req_string = "Enter second field" > dis_string = "The second entry:" > error = self.GetEntry(des_string, req_string, dis_string, > self.disp) > > des_string = "Getting third entry" > req_string = "Enter third field" > dis_string = "Entry number three:" > error = self.GetEntry(des_string, req_string, dis_string, > self.disp) This is not important, but why do you always create variables for your strings instead of passing them directly? For example, the previous 4 lines can be written: error = self.GetEntry("Getting third entry", "Enter third field", "Entry number three:", self.disp) This would shorten your code a lot. And why do you always pass self.disp as the last argument? This is an attribute, so using it directly inside the GetEntry method is not a problem. > def GetEntry(self, des_string, req_string, dis_string, disp): > """Entry routine for one field""" > > line = Entryline(des_string, req_string, dis_string, disp, > master=root) > error = line.mainloop() *Never* call mainloop twice in an application! This is not the way to go. If you want to do a modal dialog, you have to use the wait_window method, which waits for a given window to be closed. > self.Amount = line.retstring > line.destroy() > > def say_bye(self): > print 'Have a nice day, Bye!' > self.quit() > > def createWidgets(self): > > self.descr = Label(self) > self.descr["text"] = self.Company > self.descr["fg"] = 'purple' > self.descr['bg'] = 'yellow' > self.descr.pack({'expand': 'yes', 'fill': 'both', "side": "top"}) This can be written: self.descr.pack(side=TOP, fill=BOTH, expand=1) which is shorter and IMHO clearer. TOP and BOTH are constants defined in the Tkinter module, and passing named arguments is exactly the same as passing a dictionary. > Start = Button(self) > Start["text"] = "Start a new entry" > Start["fg"] = "blue" > Start['bg'] = 'green' > Start["command"] = self.start_new Again, replace the 5 last lines with: Start = Button(self, text="Start a new entry", fg='blue', bg='green', command=self.start_new) > Start.pack({'expand': 'yes', 'fill': 'both', "side": "left", > 'after': > self.descr}) (see above) > QUIT = Button(self) > QUIT["text"] = "QUIT" > QUIT["fg"] = "black" > QUIT['bg'] = 'red' > QUIT["command"] = self.say_bye > QUIT.pack({'expand': 'yes', 'fill': 'both', "side": "left", > 'after': > Start}) (see above) > def __init__(self, master=None): > Frame.__init__(self, master) > self.pack() > self.createWidgets() > > class Showscreen(Frame): > """This is supposed to show the entries as they occur.""" > > def CreateWidgets(self, Description): > > self.descr = Label(self) > self.descr["text"] = Description > self.descr["fg"] = 'purple' > self.descr['bg'] = 'yellow' > self.descr.pack({'expand': 'yes', 'fill': 'x', "side": "top", > "anchor": > "n"}) (see above) > def __init__(self, Description, master=None): > Frame.__init__(self,master) > self.pack() > self.CreateWidgets(Description) > > class Entryline(Frame): > """This asks for an entry from the user and displays the result""" > > retstring = '' > > def entryend(self,S): > """This gets done on carriage return and is where the hassles > originate""" > > self.retstring = self.estring.get() # get the entered string You're using retstring both as a class attribute (in "retstring = ''" above) and here as an instance attribute. This is not really wrong, but a bit weird. If you want retstring to be a class attribute, you should access it using Entryline.retstring (and not self.retstring); If you want it to be an instance attribute, you should remove the line "retstring = ''" above and add a line: self.retstring = '' in the constructor below. > > self.disp.Amount_des = Label(self.disp) # and put it into > the > display window > self.disp.Amount_des["text"] = self.dis_string > self.disp.Amount_des["fg"] = 'purple' > self.disp.Amount_des['bg'] = 'yellow' > self.disp.Amount_des.pack({'expand': 'yes', 'fill': 'x', "side": > "left"}) (see above) > self.disp.Amount = Label(self.disp) > self.disp.Amount["text"] = self.retstring > self.disp.Amount["fg"] = 'blue' > self.disp.Amount['bg'] = 'green' > self.disp.Amount.pack({'expand': 'yes', 'fill': 'x', "after": > self.disp.Amount_des}) (see above) > self.quit() # That's it, folks > > def createWidgets(self, des_string, req_string): > """makes the stuff to ask the question""" > > descr = Label(self) > descr["text"] = des_string > descr["fg"] = 'purple' > descr['bg'] = 'yellow' > descr.pack({'expand': 'yes', 'fill': 'both', "side": "top"}) (see above) > req = Label(self) > req ["text"] = req_string > req ["fg"] = 'yellow' > req ['bg'] = 'blue' > req.pack({'expand': 'yes', 'fill': 'both', "side" :"top",'after': > descr}) (see above) > self.estring = Entry(self) > self.estring['fg'] = 'black' > self.estring['bg'] = 'white' > self.estring.pack({'expand':'yes','fill': 'both', 'side': 'top', > 'after': req}) > self.estring.bind('<Key-Return>', self.entryend) > self.estring.focus_set() > > def __init__(self, des_stringP, req_stringP, dis_stringP, dispP, > master): > > self.disp = dispP # keep the passed params in instance vars > self.des_string = des_stringP > self.req_string = req_stringP > self.dis_string = dis_stringP AFAICS, these attributes are never used. Why did you create them? > Frame.__init__(self, master) > self.pack() > self.createWidgets(self.des_string, self.req_string) > > root = Tk() > root.title('Accounting Entry Window') > app = Entryscreen(master=root) > app.mainloop() > root.destroy() HTH -- python -c "print ''.join([chr(154 - ord(c)) for c in 'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])" -- http://mail.python.org/mailman/listinfo/python-list