4

I have problem with set in Scrollbar inside Text widget in Tkinter. I know, that it's preferable to use grid to locate widgets but I want to set my widget in absolute location (x,y - red dot on GUI picture) with specified height and width.

My code:

from Tkinter import * from ttk import * class NotebookDemo(Frame): def __init__(self): Frame.__init__(self) self.pack(expand=1, fill=BOTH) self.master.title('Sample') self.master.geometry("650x550+100+50") self._initUI() def _initUI(self): self._createPanel() def _createPanel(self): # create frame inside top level frame panel = Frame(self) panel.pack(side=TOP, fill=BOTH, expand=1) # create the notebook nb = Notebook(panel) nb.pack(fill=BOTH, expand=1, padx=2, pady=3) self._FirstTab(nb) def _FirstTab(self, nb): # frame to hold content frame = Frame(nb) #textbox txtOutput = Text(frame, wrap = NONE, height = 17, width = 70) txtOutput.place(x=10, y=75) #button btnStart = Button(frame, text = 'Start', underline=0) btnStart.place(x=220, y=380) #scrollbar #vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) #txtOutput['yscroll'] = vscroll.set #vscroll.pack(side=RIGHT, fill=Y) #txtOutput.pack(fill=BOTH, expand=Y) #add to notebook (underline = index for short-cut character) nb.add(frame, text='TAB 1', underline=0, padding=2) if __name__ == '__main__': app = NotebookDemo() app.mainloop() 

GUI:

If I uncomment this part of code (set Scrollbar):

vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) txtOutput['yscroll'] = vscroll.set vscroll.pack(side=RIGHT, fill=Y) 

My Scrollbar is located inside all window, not inside Text box:

enter image description here

But of course I want to have the Scrollbar inside the Text box widget (black border). If I use pack function to textbox:

txtOutput.pack(fill=BOTH, expand=Y) 

text widget fill in the whole window...:

enter image description here

I really don't know how fix this problem. Any help will be appreciated. Thank you!

EDIT:

Of course I can use place method with Scrollbar too, but I can't change length of them, because it hasn't attribute length.

vscroll.place(x=573, y=75) 

enter image description here

6
  • 1
    If you insist on using place for the text widget, why are you not also using it for the scrollbar? Are you aware that place has many options, including options to place one widget relative to another? If you are aware of them, have you tried them? Commented Feb 1, 2017 at 12:25
  • Of course I can use place method with Scrollbar too, but I can't change length of them, because it hasn't length attribute (or maybe has it?). I edited my post and attached image. Commented Feb 1, 2017 at 13:32
  • 1
    You can use place to set the width and height of elements. For example, the height attribute sets the height to an absolute height, the relheight attribute sets the height relative to some other widget. You should spend some time reading the documentation. While I rarely recommend place, it's remarkably powerful when you make use of all of its features. Commented Feb 1, 2017 at 13:34
  • I read about Text widget's attributes: effbot.org/tkinterbook/scrollbar.htm. According to this spec it has only width attribute. If I try use height attribute, I get AttributeError: Scrollbar instance has no attribute 'height' or TclError: unknown option "-height".. Commented Feb 1, 2017 at 13:44
  • 1
    You are misunderstanding me. The attributes are for place. Commented Feb 1, 2017 at 14:06

2 Answers 2

5

While I rarely recommend place, it is quite powerful when you take advantage of the configuration options. For example, you can use in_ to specify a widget that this widget is to be placed relative to. You can use relx to specify a relative x coordinate, and you can use relheight to specify a height.

In your case you can try something like this:

vscroll.place(in_=txtOutput, relx=1.0, relheight=1.0, bordermode="outside") 

If you want the illusion that the scrollbar is embedded inside the text widget as is (or used to be) common on some platforms, I recommend placing the text widget and scrollbar in a frame.You can use pack to put the widgets in the frame, and continue to use place to place the combination anywhere you want.

For example:

txtFrame = Frame(frame, borderwidth=1, relief="sunken") txtOutput = Text(txtFrame, wrap = NONE, height = 17, width = 70, borderwidth=0) vscroll = Scrollbar(txtFrame, orient=VERTICAL, command=txtOutput.yview) txtOutput['yscroll'] = vscroll.set vscroll.pack(side="right", fill="y") txtOutput.pack(side="left", fill="both", expand=True) txtFrame.place(x=10, y=75) 
Sign up to request clarification or add additional context in comments.

2 Comments

I exactly looked for that, Thank you again !!
just what i needed.
3

Different geometry managers like place and pack don't mix so well. I see four options for you:

Use a parent frame

Create a new Frame that you place at the exact same position as you did with the text box. In this frame, you can use another geometry manager (I'd prefer pack) to make the layout appear as you want.

Use ScrolledText

Use the ScrolledText Tkinter module to have the solution above in a premade form. Note that this widget doesn't use ttk so the scrollbar style does not really adapt to the OS' look. Just use import ScrolledText and replace the Text creation in your code with ScrolledText.ScrolledText(...).

Use place for the scrollbar

If you are using place for the text widget, use place for the scrollbar too. place has options that allow you to place a widget relative to another widget both in location and size (ie: you can place the scrollbar along the right edge of the text widget, and cause it to be exactly as tall as the text widget). See Bryan's answer.

Don't use place

Simple as that. Use grid or pack instead, unless you really need to use place.

3 Comments

The other option is to continue to use place, and also use place for the scrollbar.
@BryanOakley Of course, I missed the obvious... feel free to edit this option in, I don't know too much about that.
Thank for your options :) I will choose one of them and try to implement.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.