Re: Tkinter pack Problem

2006-07-27 Thread H J van Rooyen

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

2006-07-26 Thread 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

Re: Tkinter pack Problem

2006-07-26 Thread Eric Brunel
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

2006-07-26 Thread Simon Forman
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

2006-07-26 Thread Joe Knapka
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

2006-07-26 Thread H J van Rooyen

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?

|