How can I change the shape of the scrollbar in tkinter, python? - python

I use scrollbar widget and I want to change the shape of it.
Here's my questions below.
Can I use the image on the scroll bar?
How can I modify the color and shape with the options like relief, background, highlightbackground, highlightcolor or highlightthickness? I already tried but not a thing has changed.
from tkinter import *
root = Tk()
root.geometry("640x480")
frame = Frame(root)
frame.pack()
scrollbar = Scrollbar(frame, relief=RAISED, width=20, bd=5, activebackground="yellow", elementborderwidth=10, troughcolor="yellow", highlightbackground="red")
scrollbar.pack(side="right", fill="y")
listbox = Listbox(frame, selectmode="extended", height=10, bg="green", fg="white", yscrollcommand=scrollbar.set)
for i in range(1, 32):
listbox.insert(END, str(i) + "day")
listbox.pack()
scrollbar.config(command = listbox.yview) # scrollbar와 listbox를 mapping 해줌
root.mainloop()

Related

Add a scrollbar for text object inside frame

I have a frame which has a text object inside it. How do I add a vertical scrollbar that controls the text object. The scrollbar should be on the right side..
inputFrame = Frame(bg='#d9d9d9')
inputFrame.pack()
inputEntryImg = PhotoImage(file=resource_path("inputEntry.png"))
inputEntryBg = mainWindowCanvas.create_image(400.0, 168.5, image=inputEntryImg)
inputEntry = Text(inputFrame, bd=0, bg="#d9d9d9", highlightthickness=0, font='calibri',
pady=10)
inputEntry.pack(padx=(0, 10), pady=10)
inputFrame.place(x=41.0, y=83, width=718.0, height=169)
Thankyou.
Try this
scrollbar = Scrollbar(inputFrame, orient=VERTICAL, command=inputEntry.yview)
scrollbar.pack(side=RIGHT, fill=Y)
inputEntry.config(yscrollcommand=scrollbar.set)
How do I add a vertical scrollbar that controls the text object. The
scrollbar should be on the right side..
Try this. I did not add PhotoImage. You can add it by yourself.
Code:
import tkinter as tk
root = tk.Tk()
inputFrame = tk.Frame(bg='#d9d9d9')
inputFrame.pack()
#inputEntryImg = tk.PhotoImage(file=resource_path("inputEntry.png"))
#inputEntryBg = mainWindowCanvas.create_image(400.0, 168.5, image=inputEntryImg)
inputEntry=tk.Text(inputFrame, height=10, width=50)
scrollBar= tk.Scrollbar(inputFrame, command=inputEntry.yview, orient="vertical")
scrollBar.grid(row=0, column=1, sticky="ns")
inputEntry.grid(row=0,column=0)
inputEntry.configure(yscrollcommand=scrollBar.set)
root.mainloop()
Screenshot for scrollbar with text:

tkinter centering two or more widgets

So I created a frame in which I want to put two widgets with them being centered on the x-axis. When it's one object pack() centers it automatically. But I can't figure out two widgets. I tried with grid() but there is free space left on the right which makes it look unsymetrical as seen in the image.
how could I get what is seen on the right? (I'd prefer it being dont with pack() but if there is a solution with grid() and/or place() as well i'd appreciate those as well!)
here's the code for the left picture
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.place(relwidth=0.5, relheight=0.5, relx=0.5, rely=0.5, anchor=CENTER)
label = Label(frame, bg="lime", text="label", font=font.Font(size=20))
label.grid(column=0, row=0)
button = Button(frame, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.grid(column=1, row=0)
root.mainloop()
You can use frame.pack() to easily position the frame in the top, middle of its parent.
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.pack()
label = Label(frame, bg="lime", text="label", font=font.Font(size=20))
label.grid(column=0, row=0)
button = Button(frame, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.grid(column=1, row=0)
root.mainloop()
You can put the label and button in another frame, and use pack() on that frame:
from tkinter import *
from tkinter import font
root = Tk()
root.geometry("500x500")
frame = Frame(root, bg="white", highlightbackground="black", highlightthickness=2)
frame.place(relwidth=0.5, relheight=0.5, relx=0.5, rely=0.5, anchor=CENTER)
frame2 = Frame(frame)
frame2.pack() # default side='top'
label = Label(frame2, bg="lime", text="label", font=font.Font(size=20))
label.pack(side='left', fill='both')
button = Button(frame2, bg="yellow", text="pressbutton", font=font.Font(size=20))
button.pack(side='left')
root.mainloop()

Python tkiner, two text boxes with x and y scrollbars for both

I am trying to make a gui that has two separate text outputs with horizontal and vertical scollbars for each text box that are fixed to the right and bottom edges of each respective text windows. I am struggling with how to do this with the tkinter grid and any help would be appreciated.
import tkinter as tk
class WeatherGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
# Horizontal (x) Scroll bar
self.xscrollbar = tk.Scrollbar(self, orient="horizontal")
self.xscrollbar.grid(column=5, row=10, sticky="we")
# Vertical (y) Scroll Bar
self.yscrollbar = tk.Scrollbar(self)
self.yscrollbar.grid(column=5, row=10, sticky='ns')
self.xscrollbar2 = tk.Scrollbar(self, orient="horizontal")
self.xscrollbar2.grid(column=9, row=10, sticky="we")
# Vertical (y) Scroll Bar
self.yscrollbar2 = tk.Scrollbar(self)
self.yscrollbar2.grid(column=9, row=10, sticky='ns')
self.NSW_actual_text = tk.Text(self, width=50, wrap = "none", xscrollcommand=self.xscrollbar.set, yscrollcommand=self.yscrollbar.set,)
self.NSW_actual_text.grid(column=0, columnspan=4, row= 8,padx=(20, 10))
self.NSW_forecast_text = tk.Text(self, width=50, wrap = "none", xscrollcommand=self.xscrollbar.set, yscrollcommand=self.yscrollbar.set)
self.NSW_forecast_text.grid(column=8, columnspan=4, row= 8,padx=(20, 10))
self.xscrollbar.config(command=self.NSW_actual_text.xview)
self.yscrollbar.config(command=self.NSW_actual_text.yview)
self.xscrollbar2.config(command=self.NSW_forecast_text.xview)
self.yscrollbar2.config(command=self.NSW_forecast_text.yview)
self.btn1 = tk.Button(self, text="Generate NWS Actual", command=self.GenerateNWSActual)
self.btn1.grid(column=1, row=0)
self.btn2 = tk.Button(self, text="Generate NWS Forecast", command=self.GenerateNWSForecast)
self.btn2.grid(column=10, row=0)
def GenerateNWSActual(self):
self.NSW_actual_text.insert('1.0', "This is where actual weather would go")
def GenerateNWSForecast(self):
self.NSW_forecast_text.insert('1.0', "this is where forecast weather would go")
app = WeatherGUI()
app.mainloop()
The following example allows you to attach two functional scrollbars (x, y) to a Text widget
from tkinter import *
# Create Window
root = Tk()
# Create ScrollBars
xScrollbar = Scrollbar(root, orient=HORIZONTAL)
yScrollbar = Scrollbar(root, orient=VERTICAL)
# Create Text Widget with scroll commands
TextWidget = Text(root, xscrollcommand=xScrollbar, yscrollcommand=yScrollbar)
# Package Componets
xScrollbar.pack(side=BOTTOM, fill=X)
yScrollbar.pack(side=RIGHT, fill=Y)
TextWidget.pack(fill=BOTH, expand=20)
# Assign Scrollbars with TextWidget
xScollbar.config(command=TextWidget.xview)
yScollbar.config(command=TextWidget.yview)
You can use this examble for both of your TextWidgets in your weather application.

Tkinter canvas & scrollbar with grid

I have a canvas in a frame
photoFrame = Frame(centerFrame, width=250, height=190, bg="#EBEBEB")
photoFrame.grid(row=0, column=1, sticky="nsew")
photoCanvas = Canvas(photoFrame, bg="#EBEBEB")
photoCanvas.grid(row=0, column=0, sticky="nsew")
and I try to put a scrollbar to my canvas with this
photoScroll = Scrollbar(photoFrame, orient=VERTICAL)
photoScroll.config(command=photoCanvas.yview)
photoCanvas.config(yscrollcommand=photoScroll.set)
photoScroll.grid(row=0, column=1, sticky="ns")
The scrollbar appears but it's disabled. Can you help me please ?
Sorry for my bad english.
In a for loop I add lots of Image button with this code
element = Button(photoCanvas, image = listPhotos[i], borderwidth=0, height = 200, width = 200, bg="#EBEBEB")
element.grid(row=rowPhoto, column=columnPhoto, padx=5, pady=5, sticky="nsew")
Finnally I have this
root = Tk()
photoFrame = Frame(root, width=250, height=190, bg="#EBEBEB")
photoCanvas = Canvas(photoFrame, bg="#EBEBEB")
photoCanvas.grid(row=0, column=0, sticky="nsew")
for i in range(0, len(listPhotos), 1):
element = Button(photoCanvas, image = listPhotos[i], borderwidth=0, height = 200, width = 200, bg="#EBEBEB")
element.grid(row=rowPhoto, column=columnPhoto, padx=5, pady=5, sticky="nsew")
photoScroll=Scrollbar(photoFrame,orient=VERTICAL)
photoScroll.config(command=photoCanvas.yview)
photoCanvas.config(yscrollcommand=photoScroll.set)
photoScroll.grid(row=0, column=1, sticky="ns")
in my app, the purple rectangle is the next frame and I need a vertical scrollbar
Say if you have some questions
One way to scroll a group of widgets is to put them (with grid of pack) inside a frame and put this frame inside a canvas.
The two key elements (besides connecting the scrollbar to the canvas) for the scrolling to work are:
Use canvas.create_window(x, y, window=frame) to put the frame inside the canvas so that it is treated like a canvas item.
Update the canvas scrollregion each time the size of the frame changes (for instance after adding a new widget) with canvas.configure(scrollregion=canvas.bbox('all')).
Here is an adaptation of the code of the question Python Tkinter scrollbar for frame, but using the widgets name from the OP's question and grid instead of pack:
import tkinter as tk
def update_scrollregion(event):
photoCanvas.configure(scrollregion=photoCanvas.bbox("all"))
root = tk.Tk()
photoFrame = tk.Frame(root, width=250, height=190, bg="#EBEBEB")
photoFrame.grid()
photoFrame.rowconfigure(0, weight=1)
photoFrame.columnconfigure(0, weight=1)
photoCanvas = tk.Canvas(photoFrame, bg="#EBEBEB")
photoCanvas.grid(row=0, column=0, sticky="nsew")
canvasFrame = tk.Frame(photoCanvas, bg="#EBEBEB")
photoCanvas.create_window(0, 0, window=canvasFrame, anchor='nw')
for i in range(10):
element = tk.Button(canvasFrame, text='Button %i' % i, borderwidth=0, bg="#EBEBEB")
element.grid(padx=5, pady=5, sticky="nsew")
photoScroll = tk.Scrollbar(photoFrame, orient=tk.VERTICAL)
photoScroll.config(command=photoCanvas.yview)
photoCanvas.config(yscrollcommand=photoScroll.set)
photoScroll.grid(row=0, column=1, sticky="ns")
canvasFrame.bind("<Configure>", update_scrollregion)
root.mainloop()

Tkinter: Placing the Labels one after another in Canvas relatively.

I would like to arrange the Labels in the canvas one after another. But placement is not coming out as desired.
Below is the function that inserts the labels in the canvas. But the ones in the for loop overlaps. Reason - some labels are larger in size than the other. Hence, I assume that largest size be 80 and do the placements respectively. I would like to change this type of approach. Rather I want the labels to be placed relatively one after the other.
def calculate(*args):
try:
ttk.Label(canvas, text="Result:").place(x=20, y=20)
ttk.Label(canvas, text="Topic:").place(x=20, y=80)
ttk.Label(canvas, textvariable=topic).place(x=200, y=80)
ttk.Label(canvas, text="Environment:").place(x=20, y=120)
ttk.Label(canvas, textvariable=environment).place(x=200, y=120)
ttk.Label(canvas, text="Event Results:").place(x=20, y=160)
inputValue=TextArea.get("1.0","end-1c")
len_max=0
result={}
for s in inputValue.splitlines():
data = MainInstance.searchWithPayload(s)
result[s]=data
if len(s+data) > len_max:
len_max = len(s+data)
i = 190
for key in result.keys():
print(key)
print(result[key])
ttk.Label(canvas, text=key+"\n\n"+result[key], wraplength=800).place(x=20,y = i)
i = i + 80
except ValueError:
pass
Below is the code that integrates the canvas widget. And the calculate button calls the calculate function.
ttk.Button(page2, text="Exit",command=page1.quit).grid(column=2, row=8)
ttk.Button(page2, text="Calculate", command=calculate).grid(column=3, row=8)
canvas = Canvas(root, width=900, height=universal_height)
canvas.grid(column=1, row=0)
root.mainloop()
Actually, there are two parts of the question:
How can I relatively place the label to stop the overlapping?
I tried adding the scroll to the canvas. But the application does not respond and does not pop up.
Code for adding the scrollbar:
canvas=Canvas(root,bg='#FFFFFF',width=300,height=300,scrollregion=
(0,0,500,500))
hbar=Scrollbar(root,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(root,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=300,height=300)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)
This is the output that I am getting, wherein the first two labels are getting overlapped.
If you want to scroll the widgets that you put inside the canvas, you need to use canvas.create_window(x, y, window=label) instead of label.place(...).
I suggest you to create a frame, grid all you labels inside it so that you won't have overlapping issues and put the frame inside the canvas using create_window to be able to scroll it:
import tkinter as tk
from tkinter import ttk
def on_resize(event):
"""Resize canvas scrollregion when the canvas is resized."""
canvas.configure(scrollregion=canvas.bbox('all'))
root = tk.Tk()
root.geometry('100x100')
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
canvas = tk.Canvas(root)
frame = ttk.Frame(canvas)
# create and grid the labels
for i in range(3):
for j in range(3):
ttk.Label(frame, text="Label %i-%i" % (i, j)).grid(row=i, column=j, padx=10, pady=10)
# put the frame in the canvas
canvas.create_window(0, 0, anchor='nw', window=frame)
# add the scrollbars
vbar = ttk.Scrollbar(root, orient='vertical', command=canvas.yview)
hbar = ttk.Scrollbar(root, orient='horizontal', command=canvas.xview)
canvas.configure(xscrollcommand=hbar.set,
yscrollcommand=vbar.set,
scrollregion=canvas.bbox('all'))
canvas.grid(row=0, column=0, sticky='eswn')
vbar.grid(row=0, column=1, sticky='ns')
hbar.grid(row=1, column=0, sticky='ew')
canvas.bind('<Configure>', on_resize)
root.mainloop()

Categories