Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2004
    Location
    There where the rabbits jump
    Posts
    556
    Rep Power
    11

    Tkinter Text wraplength


    hi

    I have a small little problem with wraplength in a Tkinter Text, Label, Entry, everything that can use it.

    It gives me this error:

    Code:
    Traceback (most recent call last):
      File "E:\ggg.py", line 5, in ?
        Entry(root,wraplength=10)
      File "E:\Python\lib\lib-tk\Tkinter.py", line 2304, in __init__
        Widget.__init__(self, master, 'entry', cnf, kw)
      File "E:\Python\lib\lib-tk\Tkinter.py", line 1868, in __init__
        self.tk.call(
    TclError: unknown option "-wraplength"
    With this script:

    Code:
    from Tkinter import *
    
    root = Tk()
    
    Entry(root,wraplength=10)
    
    root.mainloop()
    Those people who think they know everything are a great annoyance to those of us who do.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Hi!

    Well, Text and Entry don't have the option wraplength. For an Entry it wouldn't make much sense because it only has one line

    Regards, mawe
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2004
    Location
    There where the rabbits jump
    Posts
    556
    Rep Power
    11
    well for example on a text widget it does not work I also recviece the same error
    Those people who think they know everything are a great annoyance to those of us who do.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    ... because
    Originally Posted by mawe
    Text and Entry don't have the option wraplength
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2004
    Location
    There where the rabbits jump
    Posts
    556
    Rep Power
    11
    oh oops how could I do the line length then???

    I really need to know
    Those people who think they know everything are a great annoyance to those of us who do.
  10. #6
  11. Caress me down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2005
    Location
    Pennsylvania
    Posts
    289
    Rep Power
    511
    instead of wraplength use width

    so make it

    Code:
    from Tkinter import *
    
    root = Tk()
    
    Entry(root,width=10).grid(row=0, column=0)
    
    root.mainloop()
    you also had to place it into the window. i prefer using grid as you can see. that code there works.
  12. #7
  13. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    13
    Hi Monkey,

    I had a look at the EditorWindow.py module in idlelib (fyi line 90).

    It seems that Text has an option wrap='none' I've not seen this in documentation.

    grim
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Hi Grim!

    The option wrap can have the values NONE, CHAR or WORD. So it only says how the text wraps, but you can't limit the line length with it, as monkeyman23555 wants.

    Regards, mawe
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Ok, here's a little hack to implement wraplength in a Text widget. It's not perfect, but it works
    Code:
    from Tkinter import *
    
    class WrapText(Text):
        def __init__(self, master, wraplength=100, **kw):
            Text.__init__(self, master, **kw)
            self.bind("<Any-Key>", self.check)
            self.wraplength = wraplength-1 
    
        def check(self, event=None):
            line, column = self.index(INSERT).split('.')
            if event and event.keysym in ["BackSpace","Return"]: pass
            elif int(column) > self.wraplength: 
                self.insert("%s.%s" % (line,column),"\n")
    
        def wrap_insert(self, index, text):
            for char in text:
                self.check()
                self.insert(index, char)
    
    
    if __name__ == '__main__':
    
        def long_line():
            w.wrap_insert(END, "afkjdskfjskfjsdkfjadkfjaskfjaskfjaskfjkasdfjask")
    
        root = Tk()
        w = WrapText(root, bg="white",wraplength=5)
        w.pack()
        Button(text="Insert long line", command=long_line).pack()
        root.mainloop()
    EDIT: and it only works if you type in the text. It doesn't work if your do it by text.insert(END, ...).
    EDIT2: now it does

    Regards, mawe
    Last edited by mawe; June 29th, 2005 at 05:37 AM.
  18. #10
  19. Mini me.
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2003
    Location
    Cambridge, UK
    Posts
    783
    Rep Power
    13
    Mawe,

    His direct request to me was to know how IDLE does text wrapping (I should have mentioned it I guess). It avoids the problem by not doing it at all

    Your idea is great. For me the wordwrap needs to be intelligent and only split on spaces/tabs so a bit more processing is required which could be a performance issue. You could extend your idea to have a modified insert method that gets around your insert issues.

    grim
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Hi!

    A little update:
    I added a wrapmode. The mode word splits the text on spaces or tabs, as Grim suggested
    Code:
    from Tkinter import *
    
    class WrapText(Text):
        def __init__(self, master, wraplength=100, wrapmode="word", **kw):
            Text.__init__(self, master, **kw)
            self.bind("<Any-Key>", self._check)
            self.wraplength = wraplength-1 
            self.wrapmode = wrapmode
    
        def _check(self, event=None, char=None):
            line, column = self.index(INSERT).split('.')
            if char: self.insert(END, char)
            if event and event.keysym in ["BackSpace","Return"]: pass
            elif int(column) > self.wraplength: 
                if self.wrapmode == "word":
                    chunk = self.get("%s.0" % line, END)
                    space = max(
                            chunk.rfind(" "),
                            chunk.rfind("\t"))
                    self.insert("%s.%s" % (line, space+1), "\n")
                else:
                    self.insert(END ,"\n")
    
        def wrap_insert(self, text):
            for char in text:
                self._check(char=char)
            
    
    
    if __name__ == '__main__':
    
        def long_line():
            w.wrap_insert("""this is a very long text with spaces, and it will be wrapped at some of these spaces, because I want it so. And so it will be.""")
    
        root = Tk()
        w = WrapText(root, bg="white",wraplength=20, wrapmode="word")
        w.pack()
        Button(text="Insert long line", command=long_line).pack()
        root.mainloop()
    I don't know if performance is a problem. All I can say is that this is still a silly hack, so use it carefully I'm sure there is a better way to do it, but hey, it works


    Regards, mawe
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2004
    Location
    There where the rabbits jump
    Posts
    556
    Rep Power
    11
    Nice script mawe

    But what about the wrap thing What do "None","Char" and "Word" do?

    whats the difference
    Those people who think they know everything are a great annoyance to those of us who do.
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Originally Posted by monkeyman23555
    But what about the wrap thing What do "None","Char" and "Word" do?
    Do you mean the wrap option in the normal text widget? Well, it does the same as my script, but at the right border of the widget. So the lines of the widget are filled. With my script you can have the text widget with, lets say, width=100, and the text wraps e.g. after the 10th character (so the lines are filled with only 10 chars).
    The modes look like this:
    CHAR
    Code:
    +-------------+
    | foo bar hel |
    | lo          |
    +-------------+
    WORD
    Code:
    +-------------+
    | foo bar     |
    | hello       |
    +-------------+
    Great ASCII-art, eh?
    NONE doesn't start a new line.

    In my script, "word" is the default. If you type anything else, the text is wrapped like with CHAR.
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Nov 2004
    Location
    There where the rabbits jump
    Posts
    556
    Rep Power
    11

    Scroll Horiztontal


    so the default by the text widget is CHAR

    EDIT:

    okay thanks guys I made it now, but now a problem with the horizontal scrolling is coming up it sort of messed up with the arrow on the right...

    Code:
    from Tkinter import *
    
    root = Tk()
    
    txt = Text(self.root,width=100,height=50,wrap='none')
    txt.grid(sticky=N+S+W+E,row=0,column=0)
                            
    sy = Scrollbar(self.root)
    sy.grid(sticky=N+S,row=0,column=1)
                            
    sx = Scrollbar(self.root,orient=HORIZONTAL)
    sx.grid(sticky=W+E,row=1,column=0)
                           
    txt.config(yscrollcommand=sy.set)
    sy.config(command=txt.yview)
                            
    txt.config(xscrollcommand=sx.set)
    sx.config(command=txt.yview)
    root.mainloop()
    Last edited by monkeyman23555; June 29th, 2005 at 10:13 AM. Reason: Avoiding New Thread
    Those people who think they know everything are a great annoyance to those of us who do.
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    This should work
    Code:
    from Tkinter import *
    
    root = Tk()
    
    xscrollbar = Scrollbar(root, orient=HORIZONTAL)
    xscrollbar.pack(side=BOTTOM, fill=X)
    
    yscrollbar = Scrollbar(root)
    yscrollbar.pack(side=RIGHT, fill=Y)
    
    text = Text(root, wrap=NONE,
            xscrollcommand=xscrollbar.set,
            yscrollcommand=yscrollbar.set)
    text.pack()
    
    xscrollbar.config(command=text.xview)
    yscrollbar.config(command=text.yview)
    
    root.mainloop()
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo