Hello,

I am learning Tkinter. As a part of the learning process I am building a Notepad clone in order to become familiar with Tkinter widgets. I am pretty close to completing it - I added about 90% functionality to the application - but I face two problems:
1) The text widget has a default fixed size (80x25 chars I believe). If I resize the root window at a greater size, the text widget stays at the initial size. This is an undesirable behavior - I expect/want the text to resize along with the root. Now, I came with something (see the code below) in which I define a callback function called whenever the resize event of the root window takes place. In the callback function I take the pixel/character ratio (both horizontal and vertical) for the text widget, and based on this information I compute roughly the new size of the text widget by considering the new root window size (both horizontal and vertical). The ratio is determined for the current set font of the text widget.
This idea works but there is a drawback. For certain root window sizes there is a thick border between the root window margins and the text widget. This is normal to happen (although undesired). What happens is that the root window can be resized with a finer resolution while the text widget is resized in steps equal with font size in pixels (on horizontal and vertical). The remained border, after the root window resize, has a thickness, for example on the vertical side, less than the number of pixels in the current font height (text widget). The effect is noticeable even for small fonts - but for a large sized fond it becomes very visible. This is my first problem. I give the code below. I simplified the problem as much as possible - this is not the notepad clone, but a minimal Tkinter application that is still able to reproduce the problem.

from Tkinter import *
import tkFont

root=Tk()
dFont=tkFont.Font(family="Arial", size=30)

def killme():
    root.quit()
    root.destroy()

LB=Text(root, width=16, height=5, font=dFont)

LB.grid(row=0, column=0, sticky=W+N+S)

yscrollbar=Scrollbar(root, orient=VERTICAL, command=LB.yview)
yscrollbar.grid(row=0, column=1, sticky=N+S+E+W)
LB["yscrollcommand"]=yscrollbar.set

LB.update()
h=int(round(LB.winfo_height()/LB["height"])), int(round(LB.winfo_width()/LB["width"]))

def resize(event):
   
    pixelX=root.winfo_width()-yscrollbar.winfo_width()
    pixelY=root.winfo_height()
    LB["width"]=int(round(pixelX/h[1])) 
    LB["height"]=int(round(pixelY/h[0]))

root.bind("<Configure>", resize)

root.mainloop()

I am a little bit frustrated - I got stuck several days ago on this matter - I hope a Tkinter/Python guru can give me a solution or a hint on how to smoothly resize the text widget along with the root window without the interference of the annoying border.

2) Second problem is related to the Print Dialog. I want to be able to run this clone on Linux too and I was hoping to find a cross-platform widget for printing, similar to the open file dialog which is available as a widget. I do have a workaround for this: I will simply copy the IDLE source code from the printing session. I'll detect the operating system used and call the appropriate code (taken from IDLE windows and linux versions) to handle printing. At least this is my plan - if any of you have a nicer solution please share it with me - my original idea was to use the canvas widget to make a custom widget for the Print Dialog - but further I don't know how to deal with printers in Python.

Best regards,

pts

Recommended Answers

All 4 Replies

I do not know pack method so well, but here is how I do it with pack:

from Tkinter import *
import tkFont

def killme():
    root.quit()
    root.destroy()

root=Tk()
dFont=tkFont.Font(family="Arial", size=30)

lb=Text(root, width=16, height=5, font=dFont)

lb.pack(side=LEFT, fill=BOTH, expand = YES)

yscrollbar=Scrollbar(root, orient=VERTICAL, command=lb.yview)
yscrollbar.pack(side=RIGHT, fill=Y)
lb["yscrollcommand"]=yscrollbar.set

root.mainloop()

I tried your solution. It is ok when the window is resized to a larger size. But when the window is resized to a size smaller than the initial one the vertical scrollbar is hidden. I notices that with my code (provided on the first post) this thing doesn't happen. Any thoughts on how to overcome this?

I got no problem with shrinking window, only at minimal size window takes out the scrollbar to show some text as it takes inappropriate amount of space compared to content. That limit appears to be original size of the text area, when scroll bar was added. If you resize big window everything is regular way.

This resize of root from default seems to keep the scroll bar visible even smallest sizes:

from Tkinter import *
import tkFont

def killme():
    root.quit()
    root.destroy()

root=Tk()
root.geometry('10x10+0+0')
dFont=tkFont.Font(family="Arial", size=30)

lb=Text(root, width=16, height=5, font=dFont)
yscrollbar=Scrollbar(root, orient=VERTICAL, command=lb.yview)
yscrollbar.pack(side=RIGHT, fill=Y)
lb["yscrollcommand"]=yscrollbar.set
lb.pack(side=LEFT, fill=BOTH, expand = YES)
root.geometry('1000x600+0+0')

root.mainloop()

Is it possible to do this using grid rather than pack?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.