import tkinter as tk
root = tk.Tk()
root.state('zoomed')
text1 = tk.Text(state=tk.DISABLED)
scroll = tk.Scrollbar(root, command=text1.yview)
text1.configure(yscrollcommand=scroll.set)
text1.grid(row=1, column=1, sticky='we')
scroll.grid(row=1, column=2, sticky="nse")
root.mainloop()
How do I make the Text box fill the X axis? (sticky='we' did not work for me)
import tkinter as tk
root = tk.Tk()
root.state('zoomed')
text1 = tk.Text(state=tk.DISABLED)
scroll = tk.Scrollbar(root, command=text1.yview)
text1.configure(yscrollcommand=scroll.set)
text1.grid(row=1, column=0,sticky='we')
scroll.grid(row=1, column=1, sticky="ns")
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=0)
root.mainloop()
I've added the parameter weight to the columns in that grid, which basically is a relationship between the columns. Please see,
What does 'weight' do in tkinter? to get a more detailed answer.
Related
The 2 buttons should take each of the half of the window, one on the left, one on the right. The height is fixed all time. With .grid() nor .place() I can come to that result. The red bar is the color of the frame where the buttons are placed on. The buttons resize in width with the window, but keep their constant height.
How to?
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root, bg='red')
frame.pack(fill='both', expand=True)
button1 = tk.Button(frame, text="<<")
button2 = tk.Button(frame, text=">>")
button1.grid(row=0, column=0, sticky='nsew')
button2.grid(row=0, column=1, sticky='nsew')
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=1)
root.mainloop()
Thx.
In the mean time I got this:
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root, bg='red',height=30)
frame.pack(fill='both')
button1 = tk.Button(frame, text="<<")
button2 = tk.Button(frame, text=">>")
button1.place(relwidth=0.5, relx=0, relheight=1)
button2.place(relwidth=0.5, relx=0.5, relheight=1)
root.mainloop()
Assuming that the buttons are the only widgets in the frame (ie: you are making a toolbar), I would use pack. grid will also work, but it requires one extra line of code.
Using pack
Here's a version with pack. Notice that the frame is packed along the top and fills the window in the "x" direction. The buttons each are instructed to expand (ie: receive extra, unused space) and to fill the space allocated to them in the "x" direction.
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root, bg='red',height=30)
frame.pack(side="top", fill="x")
button1 = tk.Button(frame, text="<<")
button2 = tk.Button(frame, text=">>")
button1.pack(side="left", fill="x", expand=True)
button2.pack(side="right", fill="x", expand=True)
root.mainloop()
Using Grid
A version with grid is similar, but you must use columnconfigure to give a non-zero weight to the two columns:
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root, bg='red',height=30)
frame.pack(side="top", fill="x")
button1 = tk.Button(frame, text="<<")
button2 = tk.Button(frame, text=">>")
button1.grid(row=0, column=0, sticky="ew")
button2.grid(row=0, column=1, sticky="ew")
frame.grid_columnconfigure((0, 1), weight=1)
root.mainloop()
i've the problem for make an GUI apps with python tkinter.
here is my sample code
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry('300x300')
root.title('CSV Editor')
notebook = ttk.Notebook(root)
notebook.pack(pady=10, expand=True)
tab_home = ttk.Frame(notebook, width=300, height=300)
notebook.add(tab_home, text='Home')
fr_home = tk.Frame(tab_home, background="white")
fr_home.grid(row=0, column=0)
fr_home_container_canvas = tk.Frame(fr_home, background="red")
fr_home_container_canvas.grid(row=0, column=0, sticky='nw')
fr_home_container_canvas.grid_rowconfigure(0, weight=1)
fr_home_container_canvas.grid_columnconfigure(0, weight=1)
fr_home_container_canvas.grid_propagate(False)
canvas_home = tk.Canvas(fr_home_container_canvas)
canvas_home.grid(row=0, column=0, sticky="news")
vsb = tk.Scrollbar(fr_home_container_canvas, orient="vertical", command=canvas_home.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas_home.configure(yscrollcommand=vsb.set)
fr_home_widget_canvas = tk.Frame(canvas_home, background="yellow")
canvas_home.create_window((0, 0), window=fr_home_widget_canvas, anchor='nw')
fr_home_widget_canvas.config(width=300, height=300, padx=10)
fr_home_container_canvas.config(width=300, height=300)
canvas_home.config(scrollregion=canvas_home.bbox("all"))
text_widget = tk.Text(fr_home_widget_canvas, width = 30, height = 10)
text_widget.grid(column=0, row=0)
root.mainloop()
if i run this code, this is the preview
enter image description here
but when i click inside the text widget, in the frame appear line / border like this
enter image description here
What is that line / border? how to remove it?
thank you so much :)
It is the highlight background which can be removed by setting highlightthickness=0:
canvas_home = tk.Canvas(fr_home_container_canvas, highlightthickness=0)
I saw this function (layout?) in android a few years ago, but I can't remind what is this function name...
I need an auto-replace widget.
if the new widget' width meets the end of the window, I want to move that widget new line.
The below is my expected output.
I Think, get the width and calculate new widget position will solve it.
But, I think this is so common need. Does tkinter support it?
Since tkinter has a canvas which gives you absolute control over positioning, you can accomplish this with just a little bit of math when adding items. You'll have to add code to reposition the widgets when the window is resized.
A simpler approach is to use the text widget, which supports embedded images or widgets, and has support for wrapping.
Here's a demonstration:
import tkinter as tk
root = tk.Tk()
toolbar = tk.Frame(root)
text = tk.Text(root, wrap="word", yscrollcommand=lambda *args: vsb.set(*args))
vsb = tk.Scrollbar(root, command=text.yview)
toolbar.pack(side="top", fill="x")
vsb.pack(side="right", fill="y")
text.pack(side="left",fill="both", expand=True)
COUNT = 0
def add_widget():
global COUNT
COUNT += 1
widget = tk.Label(root, width=12, text=f"Widget #{COUNT}", bd=1, relief="raised",
bg="#5C9BD5", foreground="white", padx=4, pady=4)
text.configure(state="normal")
text.window_create("insert", window=widget, padx=10, pady=10)
text.configure(state="disabled")
add_button = tk.Button(toolbar, command=add_widget, text="Add")
add_button.pack(side="left")
for i in range(9):
add_widget()
root.mainloop()
Refactored code :
The code in Bryan's answer works very well! But a little bit difficult to understand.
Thus I refactor the code
import tkinter as tk
def add_widget():
widget = tk.Button(root, width=12, text=f"Widget", padx=4, pady=4)
text.window_create("end", window=widget, padx=10, pady=10)
root = tk.Tk()
add_button = tk.Button(root, command=add_widget, text="Add")
add_button.pack()
text = tk.Text(root, wrap="word", yscrollcommand=lambda *args: vscroll.set(*args))
text.configure(state="disabled")
text.pack(side="left",fill="both", expand=True)
vscroll = tk.Scrollbar(root, command=text.yview)
vscroll.pack(side="right", fill="both")
root.mainloop()
I am trying to create a Scrollbar for my text widget however, I cannot seem to be able to grid() the scrollbar, thus the scrollbar does not appear on the text widget. Ignore what is in the variable Quote, it is just test data.
EventScrollBar= tk.Scrollbar(EventChoice)
EventText=tk.Text(EventChoice,height=25,width=50)
EventText.grid(row=3,column=1,columnspan=5)
EventScrollBar.config(command=EventText.yview)
EventText.config(yscrollcommand=EventScrollBar.set)
Quote=("""
...
wd""")
EventText.insert(tk.END,Quote)
EventText.config(state=tk.DISABLED)
I give you two ways of making a Scrollbar.
1) Using tk.Scrollbar
import tkinter as tk
root = tk.Tk()
EventText=tk.Text(root, height=10, width=50)
EventScrollBar= tk.Scrollbar(root, command=EventText.yview, orient="vertical")
EventScrollBar.grid(row=0, column=1, sticky="ns")
EventText.grid(row=0,column=0)
EventText.configure(yscrollcommand=EventScrollBar.set)
Quote=("""Suck\ne\ne\ne\ne\ne\ne\ne\ne\ne\nee\ne\ne\ne\ne\ne\ne\ne\nee\ned\ne\ne\nde\nd\ne\nded\nc\nc\nx\nc\nx\nc\nzc\ns\nds\nx\nwd\ns\nd\nwd""")
EventText.insert(tk.END,Quote)
root.mainloop()
2) Using ScrolledText
import tkinter as tk
from tkinter import scrolledtext
root = tk.Tk()
Quote=("""Suck\ne\ne\ne\ne\ne\ne\ne\ne\ne\nee\ne\ne\ne\ne\ne\ne\ne\nee\ned\ne\ne\nde\nd\ne\nded\nc\nc\nx\nc\nx\nc\nzc\ns\nds\nx\nwd\ns\nd\nwd""")
EventText = scrolledtext.ScrolledText(root, height=10, width=50)
EventText.insert("end", Quote)
EventText.grid(row=0, column=0)
root.mainloop()
Your code shows no attempt to grid the scrollbar.
See below example:
import tkinter as tk
root = tk.Tk()
ybar= tk.Scrollbar(root)
event_text=tk.Text(root, height=10, width=10)
ybar.config(command=event_text.yview)
event_text.config(yscrollcommand=ybar.set)
event_text.grid(row=0, column=0)
ybar.grid(row=0, column=1, sticky="ns")
for i in range(100):
event_text.insert("end", "{}\n".format(i))
root.mainloop()
Just in case you are using grid() in your original code and forgot it here in your example your problem is likely due to the columnspan=5.
If you do that to your text widget then it will sit on top of your scrollbar.
Try something like this when using columnspan:
import tkinter as tk
root = tk.Tk()
ybar= tk.Scrollbar(root)
event_text=tk.Text(root, height=10, width=10)
ybar.config(command=event_text.yview)
event_text.config(yscrollcommand=ybar.set)
event_text.grid(row=0, column=0, columnspan=5)
ybar.grid(row=0, column=5, sticky="ns")
for i in range(100):
event_text.insert("end", "{}\n".format(i))
root.mainloop()
I did search for a lot of examples before posting but still can't properly use the tkinter grid.
What I want:
my code:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
b1 = ttk.Button(root, text='b1')
b1.grid(row=0, column=0, sticky=tk.W)
e1 = ttk.Entry(root)
e1.grid(row=0, column=1, sticky=tk.EW)
t = ttk.Treeview(root)
t.grid(row=1, column=0, sticky=tk.NSEW)
scroll = ttk.Scrollbar(root)
scroll.grid(row=1, column=1, sticky=tk.E+tk.NS)
scroll.configure(command=t.yview)
t.configure(yscrollcommand=scroll.set)
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.rowconfigure(1, weight=1)
root.mainloop()
The quick and simple solution is to define the columnspan of the treeview. This will tell the treeview to spread across 2 columns and allow the entry field to sit next to your button.
On an unrelated note you can use strings for your sticky so you do not have to do things like tk.E+tk.NS. Instead simply use "nse" or whatever directions you need. Make sure thought you are doing them in order of "nsew".
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
b1 = ttk.Button(root, text='b1')
b1.grid(row=0, column=0, sticky="w")
e1 = ttk.Entry(root)
e1.grid(row=0, column=1, sticky="ew")
t = ttk.Treeview(root)
t.grid(row=1, column=0, columnspan=2, sticky="nsew") # columnspan=2 goes here.
scroll = ttk.Scrollbar(root)
scroll.grid(row=1, column=2, sticky="nse") # set this to column=2 so it sits in the correct spot.
scroll.configure(command=t.yview)
t.configure(yscrollcommand=scroll.set)
# root.columnconfigure(0, weight=1) Removing this line fixes the sizing issue with the entry field.
root.columnconfigure(1, weight=1)
root.rowconfigure(1, weight=1)
root.mainloop()
Results:
To fix your issue you mention in the comments you can delete root.columnconfigure(0, weight=1) to get the entry to expand properly.