Tkinter pack Problem

H

H J van Rooyen

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
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"})

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})

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"})

req = Label(self)
req ["text"] = req_string
req ["fg"] = 'yellow'
req ['bg'] = 'blue'
req.pack({'expand': 'yes', 'fill': 'both', "side" :"top",'after':
descr})

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

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()

8<----------------------------------end of code section-------------------

can anybody see what I am doing wrong?

- Hendrik
 
E

Eric Brunel

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
 
H

H J van Rooyen

|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?

|
|> 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.

What is a modal dialog, daddy? (I am not being facetious, I really wanna know)

- I am actually not closing the window - the frame with the two labels and the
entry line disappears when you hit enter, and then gets manufactured again for
the next entry - in the real app there is also a choice widget with scroll bars
that is populated from a file and that also disappears when you make a choice by
double mouse click - that is how coded things like company, document type, and
account codes would be entered in practice - the entry thingy was the simplest
thing to include to show what I was complaining about.

Will the wait_window method work for the Frame, or must it be a window? Or is
there a wait_frame method?

I am not sure I understand the mainloop bit - is this mainloop the same mainloop
as the other mainloop?
What does this mainloop actually do? - I need to pass control to the thingy that
gets the entry somehow, and wait for it to complete, and get the value that was
entered and displayed to use in the real app... - or will this happen
*automagically* because of the binding of the enter key to the entryend
method? - and I need the data before the entry thingy is destroyed so I cant let
it commit seppoku (Hara Kiri for the uninitiated) - or must I do that and then I
would have to go fetch the data out of the other window where its displayed? (if
its still there and not a reference to a destroyed thing - I find assignment in
Python a bit confusing at times...)
I was under the impression that this mainloop is tied to line and not to the
*main* instance...
I did not (and cannot) call mainloop for the second Tk instance - if I do then
app blocks until the second window is closed, and then the whole thing is
broken...

Another small issue - the binding to entryend - on Linux, I see that it binds
only the main keyboard enter key, and not the numeric pad enter key - (I did not
test this on Windows) How does one get both?

|> 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.

Thanks - did not know this and I like it - its also less to type and that is
important cos I am lazy...

|
|> 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)

*nods*

|
|> Start.pack({'expand': 'yes', 'fill': 'both', "side": "left",
|> 'after':
|> self.descr})
|
|(see above)

*nods*

|
|> 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)

*nods*

|
|> 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)

*nods*

|
|> 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.

Ok - I think it might have to be an instance thinghy really - cos it is
effectively the *return value* of what was typed - and it happens more than
once - OTOH - if I read it out of the class variable at the right time, it might
also work - there *should* only be one of these alive at any one time - or am I
talking BS?

|
|>
|> 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)

*nods*

|
|> 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)

*nods*

|
|> 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)

*nods*

|
|> 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)

*nods*

|
|> 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?

a) they used to be globals *ducks again*
b) when I was changing them from being globals I was getting errors and after I
did this the errors went away... - I just changed the names to make them formal
parameters by appending a "P"...
c) the value of self.dis_string is used above to populate the instance of
disp.Amount_des["text"] in entryend - it is needed there - the other two are
used below in the createWidgets call - but you are right - below here I could
have used them just as they were passed, like I do with master in the __init__
call

|
|> 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

Yes it does - thanks for the effort

In a sense, the answer of "you cant do this with pack, use grid" is the wrong
answer, as I have spent far too much time on this - but hey, that's how you
learn...

Did you actually try to run this thing to see what it did? - from my perspective
it seems to do everything I want except that it messes up the display of the
data in the second window...

|--
|python -c "print ''.join([chr(154 - ord(c)) for c in
|'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
 
J

Joe Knapka

H said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top