Re: Tkinter pack Problem
Simon Forman [EMAIL PROTECTED] wrote: | I find the Tkinter reference: a GUI for Python under Local links on | this page http://infohost.nmt.edu/tcc/help/lang/python/tkinter.html to | be very helpful. It has a decent discussion of the grid layout | manager. | | HTH, | ~Simon Thanks am checking it out - downloading pdf... - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Tkinter pack Problem
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 This seems so simple - but I have now spent a day or two mucking around - and no matter what I do with the side, after and anchor parameters, I just seem to get weird results - I must be doing something terribly stupid, but I cant see it So I have boiled the thing down as far as I can. - to an entry window with a start and quit button, one entry method, and the display window for the entered content - aside from displaying, the programme does nothing. Its doing the same thing on Linux and on Windows This code should run and illustrate the hassles I am having: 8-start of code section-- #!/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): 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() 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) 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() 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}) Start = Button(self) Start[text] = Start a new entry Start[fg] = blue Start['bg'] = 'green' Start[command] = self.start_new Start.pack({'expand': 'yes', 'fill': 'both', side: left, 'after': self.descr}) 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}) 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}) 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 self.disp.Amount_des = Label(self.disp) # and put it into the display window
Re: Tkinter pack Problem
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
Re: Tkinter pack Problem
I find the Tkinter reference: a GUI for Python under Local links on this page http://infohost.nmt.edu/tcc/help/lang/python/tkinter.html to be very helpful. It has a decent discussion of the grid layout manager. HTH, ~Simon -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter pack Problem
H J van Rooyen 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 can achieve this with pack(), but only by using a lot of nested panels: +-+ | Current entry | +-+ +-+ |Company : entered co. name | +-+ +-+ |First entry : entered stuff| +-+ +-+ |The second entry: more entered stuff | +-+ +-+ |Entry number three : Last entered stuff | +-+ Create the subpanels and pack the labels into their respective subpanels with side=left and the entry fields with side=right; then pack all the subpanels into the main window with side=top. But this is really a PITA, it would be simpler use grid() as Eric B suggests. Once you learn grid(), you will probably never need to use pack() again. -- JK -- http://mail.python.org/mailman/listinfo/python-list
Re: Tkinter pack Problem
Eric Brunel [EMAIL PROTECTED] wrote: |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. I can kind of agree with this - If I learnt one thing it was that I can get them in a column, or a row, or what looks like a weird kind of horizontal hierarchy, but not what I was looking for... | |[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). No particular reason other than ignorance - the original example I was following did something like this, and as it actually produced something that looked to me like it was working I did not mess with it :-) What is the best place to get info on all these wonderful things - I have been trying to come right by reading the module help - but its kind of cryptic... - like most things its cool as a reminder if you already know what it does... | | 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. | Ok I will try it, thanks. | 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: The original code actually used the variables as globals ... *ducks* | |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. The thing was giving me all sorts of errors when I changed disp from being a global - It prolly has to do with the bad move of having a second instance of k - I messed around and stopped when I got no more errors - could this be what is really meant by Heuristic Programming? |