I'm Bloodly Beginner in Python. I was learning to create tabs in python using tkinter pkg. I have successfully created 2 tabs, but I can't show Text (Label) in both tab. When I show only 1 text in one tab (heading.pack()) it works perfectly. But when I show another text in Tab 2 (heading2.pack()), The frame Resulation Broked. I have also set width and height in Frame Option. I want to fix resulation(Before adding 2nd text resulation). Here is Before and after Screenshots
Before adding 2nd Text
After adding 2nd Text
Here is The Code:
from tkinter import *
from tkinter import ttk
root=Tk()
root.title('Tab Widget')
root.geometry('600x400')
book=ttk.Notebook(root)
book.pack(pady=2)
tab1=Frame(book,width=600,height=500,bg='white')
tab2=Frame(book,width=600,height=500,bg='white')
tab1.pack(fill='both',expand=1)
tab2.pack(fill='both',expand=1)
book.add(tab1,text='Tab 1')
book.add(tab2,text='Tab 2')
heading=Label(tab1,text='This is Tab 1',font='arial 20 bold',bg='white')
heading2=Label(tab2,text='This is Tab 2',font='arial 20 bold',bg='white')
heading.pack() #Show Text in Tab 1
heading2.pack() #Show Text in Tab 2
root.mainloop()
When you call heading.pack(), tab1 will be shrink to the size of the label. And if you don't call heading2.pack(), tab2 will still have size 600x500. So the notebook client area will be kept at 600x500.
However when you call heading2.pack(), tab2 will be shrink to the size of the label as well which cause the notebook client area to be shrink as well.
You can avoid the above size adjustment by changing:
book.pack(pady=2)
to
book.pack(pady=2, fill='both', expand=1)
so that notebook will use all the available space of the root window.
Also note that the following two lines are not necessary and can be removed:
tab1.pack(fill='both',expand=1)
tab2.pack(fill='both',expand=1)
Related
I am trying to build an application using Tkinter library. When I am creating labels pervious label doesn't show window and last label also showing wrong label name. Right now my python version is 3.9 and tkinter version 8.6 . I went through all the question related to issue, but couldn't find any solution at stack overflow forum. Below I am pasting my dummy code. Kindly help me debugging my code.
'''
from tkinter import *
window = Tk()
window.title("Window") ## giving window a name
window.geometry("600x600")
window.resizable(False,False)
Label(window,text="Name",font="10").place(x=30,y=110)
Label(window,text="Place",font="10").place(x=30,y=110)
Label(window,text="Age",font="10").place(x=30,y=110)
mainloop()
'''
You have placed the labels at the same coordinates so they will be placed on top of each other. Try with different x & y parameters to separate them:
from tkinter import *
window = Tk()
window.title("Window") ## giving window a name
window.geometry("600x600")
window.resizable(False,False)
Label(window,text="Name",font="10").place(x=30,y=110) # Diffterent
Label(window,text="Place",font="10").place(x=30,y=130) # vertical
Label(window,text="Age",font="10").place(x=30,y=150) # placement
mainloop()
You have placed all the labels at the same location (30,110). That's the reason why the content of the labels overlap and "Age e" is displayed. As "Age" is the last label you add to the screen, it is displayed on top of the other two labels.
If you give the labels different locations, you will be able to view all the labels correctly.
I am trying to make a date chooser using python. I am using spinboxes, however I was wondering whether I could get all 5 widgets into one grid space, so it seemed like all 5 widgets are really one widget. Hopefully the following code articulates the problem better.
import tkinter as tk
root=tk.Tk()
Day=tk.IntVar()
Month=tk.IntVar()
Year=tk.IntVar()
Label1=tk.Label(root,text="Label Label Label Expanding Row")
Label1.grid(row=1,column=1)
DayEntry=tk.Spinbox(root,textvariable=Day,bg="white",from_=0, to_=31,width=2)
DayEntry.grid(row=2,column=1)
MonthEntry=tk.Spinbox(root,textvariable=Month,bg="white",from_=0, to_=12,width=2)
MonthEntry.grid(row=2,column=3)
YearEntry=tk.Spinbox(root,textvariable=Year,bg="white",from_=2000, to_=20019,width=4)
YearEntry.grid(row=2,column=5)
Divider1=tk.Label(root,text="/")
Divider1.grid(row=2,column=2)
Divider2=tk.Label(root,text="/")
Divider2.grid(row=2,column=4)
root.mainloop()
The solution is to put all of the widgets in a frame.
datepicker = tk.Frame(root)
datepicker.grid(row=2, column=0)
DayEntry=tk.Spinbox(datepicker,textvariable=Day,bg="white",from_=0, to_=31,width=2)
MonthEntry=tk.Spinbox(datepicker,textvariable=Month,bg="white",from_=0, to_=12,width=2)
YearEntry=tk.Spinbox(datepicker,textvariable=Year,bg="white",from_=2000, to_=20019,width=4)
Divider1=tk.Label(datepicker,text="/")
Divider2=tk.Label(datepicker,text="/")
DayEntry.grid(row=0,column=1)
Divider1.grid(row=0,column=2)
MonthEntry.grid(row=0,column=3)
Divider2.grid(row=0,column=4)
YearEntry.grid(row=0,column=5)
Here's my program:
import tkinter as tk
#Create main window object
root = tk.Tk()
#build GUI
for i in range(5):
tk.Label(root, text="hello", height=0).grid(row=i)
#mainloop
root.mainloop()
It produces the following (running in Xubuntu 16.04 LTS)
Notice all that extra vertical space between the lines of text. I don't want that! How do I decrease it?
If I run this code instead:
import tkinter as tk
#Create main window object
root = tk.Tk()
#build GUI
for i in range(5):
tk.Label(root, text="hello", height=0).grid(row=i)
tk.Grid.rowconfigure(root, i, weight=1) #allow vertical compression/expansion to fit window size after manual resizing
#mainloop
root.mainloop()
...it opens up and initially looks exactly the same as before, but now I can manually drag the box vertically to shrink it, like so:
Notice how much more vertically-compressed it is! But, how do I do this programatically, so I don't have to manually drag it to make it this way? I want to set this tight vertical spacing from the start, but no matter which parameters I change in Label, grid, or rowconfigure I can't seem to make it work without me manually dragging the box with the mouse to resize and vertically compress the text.
There are many ways to affect vertical spacing.
When you use grid or pack there are options for padding (eg: pady, ipady, minsize). Also, the widget itself has many options which control its appearance. For example, in the case of a label you can set the borderwidth, highlightthickness and pady values to zero in order to make the widget less tall.
Different systems have different default values for these various options, and for some of the options the default is something bigger than zero. When trying to configure the visual aspects of your GUI, the first step is to read the documentation, and look for options that affect the visual appearance. Then, you can start experimenting with them to see which ones give you the look that you desire.
In your specific case, this is about the most compact you can get:
label = tk.Label(root, highlightthickness=0, borderwidth=0, pady=0, text="hello")
label.grid(row=i, pady=0, ipady=0)
You can programatically modify the geometry just before starting the main loop instead of manually dragging it (change 0.6 to whatever % reduction you want):
import tkinter as tk
#Create main window object
root = tk.Tk()
#build GUI
for i in range(5):
label = tk.Label(root, text = 'hello')
label.grid(row=i)
tk.Grid.rowconfigure(root, i, weight=1) #allow vertical compression/expansion to fit window size after manual resizing
#mainloop
root.update()
root.geometry("{}x{}".format(root.winfo_width(), int(0.6*root.winfo_height())))
root.mainloop()
Here is a screenshot of the result running on Xubuntu 16.04 LTS with Python 3.5.2:
On python tkinter, I am using 2 different frames on a Toplevel window, one on the right and another on the left.
The frame which is on right side is not scrollable. I have created a canvas on top of the frame on that frame and one more frame on top of that canvas. I have made that canvas scrollable and pasted the widgets on that canvas but it's not scrollable. I am attaching the code of the scrollable part.
w1 = Canvas(frame2, width=600, height=300,background="white", scrollregion=(1500,1500,3000,3000))
scr_h1 = ttk.Scrollbar(frame2,orient=HORIZONTAL)
scr_h1.pack(side=BOTTOM,fill=X)
scr_h1.config(command=w1.xview)
scr_v1 = ttk.Scrollbar(frame2,orient=VERTICAL)
scr_v1.pack(side=RIGHT,fill=Y)
scr_v1.config(command=w1.yview)
w1.config(xscrollcommand=scr_h1.set,yscrollcommand=scr_v1.set)
w1.pack(fill=BOTH,expand=True)
This code works for me running Python 3.4 - a tkinter window pops up with a red oval (for testing), and the scrollbar allows you to navigate the frame. If you are using Python 2, change tkinter to Tkinter (capital T).
from tkinter import *
root = Tk()
frame2 = Frame(root)
frame2.pack(side=RIGHT)
w1 = Canvas(frame2, width=600, height=300,background="white", scrollregion=(0,0,3000,3000))
scr_h1 = Scrollbar(frame2,orient=HORIZONTAL)
scr_h1.pack(side=BOTTOM,fill=X)
scr_h1.config(command=w1.xview)
scr_v1 = Scrollbar(frame2,orient=VERTICAL)
scr_v1.pack(side=RIGHT,fill=Y)
scr_v1.config(command=w1.yview)
w1.config(xscrollcommand=scr_h1.set,yscrollcommand=scr_v1.set)
w1.pack(fill=BOTH,expand=True)
# inserted to see if it's actually scrolling
w1.create_oval(0,0,50,50,fill='red')
root.mainloop()
Two Possible Issues
Why were you using a ttk ScrollBar? The simple tkinter scroll bar will suffice for your code. When things aren't working, it might help to go back to the simpler model.
Why your starting scroll region was 1500 - any object placed on the canvas in the first 1500 units in either direction were not visible, with this setting, which may have given you the illusion that the scrollbar was not working. See http://effbot.org/zone/tkinter-scrollbar-patterns.htm for more information on using scroll bars.
It should not matter that there are two frames or their orientation, though you may run into problems if you try to mix managers (grid,pack,etc.). These problems are more along the lines of stalled programs, not stationary scrollbars.
I'm trying to change the background color of a ttk frame and I've looked up other examples, but none have seemed to work. This is my code so far:
from Tkinter import *
import ttk
p = Tk()
p.geometry('600x350')
p.configure(bg='#334353')
gui_style = ttk.Style()
gui_style.configure('My.TButton', foreground='#334353')
gui_style.configure('My.TFrame', background='#334353')
frame = ttk.Frame(p, style='My.TFrame')
frame.grid(column=1, row=1)
ttk.Button(frame, text='test', style='My.TButton').grid(column=0, row=0)
ttk.Button(frame, text='Test 2', style='My.TButton').grid(column=3, row=3)
p.mainloop()
The window has the background color that I want, but the frame still has the default gray background. Is there something i need to add differently? I want the entire window except for the buttons to be the color #334353. How do I do this?
EDIT: I've attached what my window looks like. I don't want the gray. :/ (Note. I don't have enough rep to post images apparently, so here is a link to imgur with my current window: http://imgur.com/KyhbdMB
Your frame is only sized to the minimum size required to hold the two child windows (the buttons). It seems like you want the frame to fill the main window. When you grid the frame you should add the sticky option to have it expand to fill the available space (eg: frame.grid(column=1,row=1,sticky='news')). Then you need to have the parent allocate all the space space to this grid cell. For that you want to use the grid_rowconfigure and grid_columnconfigure methods for the parent window. In this case:
p.grid_columnconfigure(1, weight=1)
p.grid_rowconfigure(1, weight=1)
which tells the main frame grid geometry manager that spare space should be given to the cell and row 1 column 1. This will lead to your frame expanding to fill the window.
It works on my PC!
Try this:
Update your Python environment(Tested under Py 3.4 Windows 32bit)
Install the lastest TTK package