I am quite new to Tkinter, but, nevertheless, I was asked to "create" a simple form where user could provide info about the status of their work (this is sort of a side project to my usual work). Since I need to have quite a big number of text widget (where users are required to provide comments about status of documentation, or open issues and so far), I would like to have something "scrollable" (along the y-axis).
I browsed around looking for solutions and after some trial and error I found something that works quite fine. Basically I create a canvas, and inside a canvas a have a scrollbar and a frame. Within the frame I have all the widgets that I need.
This is a snipet of the code (with just some of the actual widgets, in particular the text ones):
from Tkinter import * ## My frame for form class simpleform_ap(Tk): # constructor def __init__(self,parent): Tk.__init__(self,parent) self.parent = parent self.initialize() # def initialize(self): # self.grid_columnconfigure(0,weight=1) self.grid_rowconfigure(0,weight=1) # self.canvas=Canvas(self.parent) self.canvas.grid(row=0,column=0,sticky='nsew') # self.yscrollbar = Scrollbar(self,orient=VERTICAL) self.yscrollbar.grid(column =4, sticky="ns") # self.yscrollbar.config(command=self.canvas.yview) self.yscrollbar.pack(size=RIGTH,expand=FALSE) # self.canvas.config(yscrollcommand=self.yscrollbar.set) self.canvas.pack(side=LEFT,expand=TRUE,fill=BOTH) # self.frame1 = Frame(self.canvas) self.canvas.create_window(0,0,window=self.frame1,anchor='nw') # Various Widget # Block Part # Label self.labelVariableIP = StringVar() # Label variable labelIP=Label(self.frame1,textvariable=self.labelVariableIP, anchor="w", fg="Black") labelIP.grid(column=0,row=0,columnspan=1,sticky='EW') self.labelVariableIP.set(u"IP: ") # Entry: Single line of text!!!! self.entryVariableIP =StringVar() # variable for entry field self.entryIP =Entry(self.frame1, textvariable=self.entryVariableIP,bg="White") self.entryIP.grid(column = 1, row= 0, sticky='EW') self.entryVariableIP.set(u"IP") # Update Button or Enter button1=Button(self.frame1, text=u"Update", command=self.OnButtonClickIP) button1.grid(column=2, row=0) self.entryIP.bind("<Return>", self.OnPressEnterIP) #... # Other widget here # # Some Text # Label self.labelVariableText = StringVar() # Label variable labelText=Label(self.frame1,textvariable= self.labelVariableText, anchor="nw", fg="Black") labelText.grid(column=0,row=curr_row,columnspan=1,sticky='EW') self.labelVariableTexta.set(u"Insert some texts: ") # Text textState = TRUE self.TextVar=StringVar() self.mytext=Text(self.frame1,state=textState, height = text_height, width = 10, fg="black",bg="white") # self.mytext.grid(column=1, row=curr_row+4, columnspan=2, sticky='EW') self.mytext.insert('1.0',"Insert your text") # # other text widget here # self.update() self.geometry(self.geometry() ) self.frame1.update_idletasks() self.canvas.config(scrollregion=(0,0, self.frame1.winfo_width(), self.frame1.winfo_height())) # def release_block(argv): # Create Form form = simpleform_ap(None) form.title('Release Information') # form.mainloop() # if __name__ == "__main__": release_block(sys.argv) As I mentioned before, this scripts quite does the work, even if, it has a couple of small issue that are not "fundamental" but a little annoying.
When I launch it I got this (sorry for the bad screen-capture): enter image description here
As it can be seen, it only shows up the first "column" of the grid, while I would like to have all them (in my case they should be 4) To see all of the fields, I have to resize manually (with the mouse) the window. What I would like to have is something like this (all 4 columns are there): enter image description here
Moreover, the scrollbar does not extend all over the form, but it is just on the low, right corner of the windows.
While the latter issue (scrollbar) I can leave with it, the first one is a little more important, since I would like to have the final user to have a "picture" of what they should do without needing to resize the windows.
Does any have any idea on how I should proceed with this? What am I missing?
Thanks in advance for your help
__init__, you do not appear to have set the size of your main window. You should do that, or it will just set the window to a default size, which will only show whatever it can, and in your case, only 1 column. Therefore, in the__init__part of the class, try puttingself.geometry(str(your_width) + "x" + str(your_height))whereyour_widthandyour_heightare whatever integers you choose that allow you to see what you need to in the window.