954,549 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Tkinter EntryBox

The last time I posted a question here, I got a rather nasty response, so please just constructive stuff!

I want to make a scrollable entrybox for Tkinter GUI, the scrollbar shows up and works, but text does not move. Am I missing something?

import Tkinter as tk
 
root = tk.Tk()
 
enter1 = tk.Entry(root, bg='yellow', width=30)
enter1.grid(row=0, column=0)
 
# create a horizontal scrollbar at bottom of enter1
# (similar to code shown for a listbox)
xscroll = tk.Scrollbar(orient='horizontal', command=enter1.xview)
xscroll.grid(row=1, column=0, sticky='ew')
enter1.configure(xscrollcommand=xscroll.set)
 
enter1.insert('end', 'just a very long sentence to put into the enter space')
 
root.mainloop()
sneekula
Nearly a Posting Maven
2,427 posts since Oct 2006
Reputation Points: 961
Solved Threads: 212
 

So I usually test my Tkinter apps from IDLE; in this case, I get the following error message every 'pixel' I scroll:

Traceback (most recent call last):
  File "C:\Python24\lib\lib-tk\Tkinter.py", line 1345, in __call__
    return self.func(*args)
TypeError: xview() takes exactly 2 arguments (3 given)



I interpret that to mean that enter1 is passing too many arguments to xview.

Sure 'nuff, when we examine what gets passed ...

import Tkinter as tk

def wrapper(master, *args):
    # intercept the arguments and print before passing along
    print args
    enter1.xview(master,*args)
    
root = tk.Tk()
 
enter1 = tk.Entry(root, bg='yellow', width=30)
enter1.grid(row=0, column=0)
 
# create a horizontal scrollbar at bottom of enter1
# (similar to code shown for a listbox)
xscroll = tk.Scrollbar(orient='horizontal', command=wrapper) # <<<
xscroll.grid(row=1, column=0, sticky='ew')
enter1['xscrollcommand']=xscroll.set
 
enter1.insert('end', 'just a very long sentence to put into the enter space')
 
root.mainloop()

We get lots of these:

('0.0065',)
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python24\lib\lib-tk\Tkinter.py", line 1345, in __call__
    return self.func(*args)
  File "C:/Python24/scrollentry.py", line 5, in wrapper
    enter1.xview(master,*args)
TypeError: xview() takes exactly 2 arguments (3 given)



Which indicates that entry widgets are somehow passing a tuple instead of a single argument on to xview. On the hunt...

def wrapper(master, *args):
    print args
    enter1.xview(args[0])


yields

TclError: bad entry index "0.0839"



Hmm... wonder what arguments are supposed to be passed? AH-HA: according to the manual,The Entry widget does not have an .xview() method. See
Section 8.1, “Scrolling an Entry widget” (p. 32).

And from p. 32,
Making an Entry widget scrollable requires a little extra code on your part to adapt the Scrollbar
widget's callback to the methods available on the Entry widget. Here are some code fragments illustrating
the setup. First, the creation and linking of the Entry and Scrollbar widgets:

self.entry = Entry ( self, width=10 )
self.entry.grid(row=0, sticky=E+W)
self.entryScroll = Scrollbar ( self, orient=HORIZONTAL,
command=self.__scrollHandler )
self.entryScroll.grid(row=1, sticky=E+W)
self.entry["xscrollcommand"] = self.entryScroll.set

def __scrollHandler(self, *L):
    op, howMany = L[0], L[1]
    if op == "scroll":
    units = L[2]
    self.entry.xview_scroll ( howMany, units )
    elif op == "moveto":
    self.entry.xview_moveto ( howMany )

And sure nuff, this works:

import Tkinter as tk

def wrapper(*args):
    op, howMany = args[0], args[1]
    if op == "scroll":
        units = args[2]
        enter1.xview_scroll ( howMany, units )
    elif op == "moveto":
        enter1.xview_moveto ( howMany )
    
root = tk.Tk()
 
enter1 = tk.Entry(root, bg='yellow', width=30)
enter1.grid(row=0, column=0)
 
# create a horizontal scrollbar at bottom of enter1
# (similar to code shown for a listbox)
xscroll = tk.Scrollbar(orient='horizontal', command=wrapper)
xscroll.grid(row=1, column=0, sticky='ew')
enter1['xscrollcommand']=xscroll.set
 
enter1.insert('end', 'just a very long sentence to put into the enter space')
 
root.mainloop()


Hope it helps,
Jeff

jrcagle
Practically a Master Poster
608 posts since Jul 2006
Reputation Points: 92
Solved Threads: 156
 

Wow, that was quick detective work!
My problem was that I used PSPad for my editor and that does not show runtime error messages. So IDLE is good for some things!

The code works well, and I learned something new. Thanks for the well explained path to the truth. I shall follow it in the future.

sneekula
Nearly a Posting Maven
2,427 posts since Oct 2006
Reputation Points: 961
Solved Threads: 212
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You