Why my ttk style won't apply to my Frame? - python-3.x

I've been fighting with ttk style for about 2 days right now, but nothing seems to work. I've tried a lot of different approaches, but I had no effect. Right now, I just want to see that the Frame that I'm trying to add to my App is working, could you please show me where is the problem?
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
# Main window configuration
self.title("Work Tracker")
self.geometry("600x700")
self.resizable(0,0)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Styles
style = ttk.Style()
style.configure('TFrame', background='blue')
# Logo frame
frame = ttk.Frame(self, width=200, height=150)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
frame.grid_propagate(False)
frame.grid(row=0, column=0, sticky='nw')
label = ttk.Label(frame, text ="WORK TRACKER")
label.pack()
def main():
app = App()
app.mainloop()
main()

Related

How to show two Frames side by side in Tkinter

This is what I got
This is what I want to get
I've tried it like 2 hours with reading the documentation and every tutorial I could possibly find but after all I'm not able to display two ttk.Frames side by side with a border around them.
What have I done wrong?
This is my code so far (and yeah, I know, I've never used self.path but I just like to have it available in need):
import os
import tkinter as tk
import tkinter.ttk as ttk
from ttkthemes import ThemedTk
class GUI(ThemedTk):
def __init__(self):
super().__init__()
self.set_theme("breeze")
self.path = os.path.dirname(__file__)
self.title("Kniffel All In One")
self.defineVariables()
# Root Window
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=5)
self.columnconfigure(1, weight=1)
self.LeftFrame = ttk.Frame(self, border=True, borderwidth=1)
self.LeftFrame.grid(row=0, column=0, padx=5, pady=5, sticky="NSWE")
self.RightFrame= ttk.Frame(self, border=True, borderwidth=1)
self.RightFrame.grid(row=0, column=1, padx=5, pady=5, sticky="NSWE")
# LeftFrame
self.LeftEntry = ttk.Entry(self.LeftFrame, textvariable=self.text1).grid(row=0, column=0, ipadx=5, ipady=5, sticky="WE")
self.LeftLabel = ttk.Label(self.LeftFrame, text="Little test left side").grid(row=1, column=0, ipadx=5, ipady=5, sticky="WE")
# RightFrame
self.RightEntry = ttk.Entry(self.RightFrame, textvariable=self.text2).grid(row=0, column=0, ipadx=5, ipady=5, sticky="WE")
self.RightLabel = ttk.Label(self.RightFrame, text="Litte test right side").grid(row=1, column=0, ipadx=5, ipady=5, sticky="WE")
self.mainloop()
def defineVariables(self):
self.text1 = tk.StringVar()
self.text2 = tk.StringVar()
if __name__ == '__main__':
GUI()
Note that I didn't use .pack() and .grid() together and it doesn't display a border even though I thought border=True would show one.
Please be so kind to just answer my question since I haven't ask for aesthetics, readability or programming style improvements. Also this won't be a professional application.
Thanks for understanding this.

tkinter: how do i make the Scrollbar react to the new size of the frame

from tkinter import *
from tkinter import ttk
class Scrollbar:
def __init__(self, master):
frame = ttk.Frame(master)
frame.pack()
self.canvas = Canvas(frame, width=700, height=930)
self.scrollbar = ttk.Scrollbar(frame, orient=VERTICAL, command=self.canvas.yview)
self.main_frame = ttk.Frame(self.canvas)
self.placing_widgets()
def placing_widgets(self):
self.canvas.pack(side=LEFT, fill=Y)
self.scrollbar.pack(side=RIGHT, fill=Y)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind('<Configure>', lambda e: self.canvas.configure(scrollregion=self.canvas.bbox('all')))
self.canvas.create_window((0,0), window=self.main_frame, anchor='n')
Frame1(self.main_frame)
class Frame1:
def __init__(self, main_frame):
self.main_frame = main_frame
for i in range(100):
self.button = ttk.Button(self.main_frame, text=f"Button {i}", command=lambda i=i: self.destroying(i))
self.button.grid(row=i, column=0, pady=5)
def destroying(self, i):
for frame in self.main_frame.winfo_children():
frame.destroy()
Frame2(self.main_frame)
class Frame2:
def __init__(self, main_frame):
self.main_frame = main_frame
self.button = ttk.Button(self.main_frame, text='back', command=self.destroying)
self.button.pack()
def destroying(self):
for frame in self.main_frame.winfo_children():
frame.destroy()
Frame1(self.main_frame)
def main():
root = Tk()
root.config(background='black')
Scrollbar(root)
root.mainloop()
if __name__ == '__main__':
main()
I couldn't find a solution to this problem anywhere on the internet.
I have given a scrollbar to a lengthy frame but when I make the frame shorter, I don't know why the scrollbar doesn't resize to the frame's length.
Above is a short program that represents the problem I am talking about. The program has 2 different pages, one with 100 buttons and the other with one button. You can switch between pages with any buttons and see that the page with one button is scrollable which shouldn't be.
Could you please provide a solution to how I could make the scrollbar resize to the frame's length? Thank you for your time.

How can I fix my button positions on python tkinter?

I want to fix the position of my two buttons like if I resize my window the buttons will remain in their positions. Or My buttons dynamically resize with the window size. I have positioned my buttons using place. But I ain't getting success. Here's the code so far.
import turtle
import tkinter as tk
##wn=turtle.Screen()
wn=tk.Tk()
image=tk.PhotoImage(file="MS-3.PNG")
wn.geometry("700x700")
label1=tk.Label(wn,image=image)
label1.pack(side="top",fill="both",expand="yes")
label1.grid_rowconfigure(0, weight=1)
label1.grid_columnconfigure(0, weight=1)
label1.grid_rowconfigure(1, weight=1)
def callback1():
import Detection1
def callback():
import detection
button1=tk.Button(label1,text="Health Identification", command=callback, bd=12,bg="grey",font="caliber")
button1.place(x=100,y=500 )
label1.image=image
button2=tk.Button(label1,text="Disease Classification", command=callback1, bd=10,bg="grey",font="caliber")
button2.place(x=400, y=500 )
label1.image=image
wn.mainloop()
Sadia: If I understood your question correctly, you could make your windows non-resizable with wn.resizable(False, False). Then place your buttons exactly where you want them to be. If you are new to tkinter and python, making every object resizable might be a bit too complex to begin with.
Hopefully this helps.
import turtle
import tkinter as tk
from PIL import Image, ImageTk
##wn=turtle.Screen()
wn = tk.Tk()
wn.geometry("700x700")
wn.resizable(False, False)
img = ImageTk.PhotoImage(Image.open("MS-3.PNG"))
label1 = tk.Label(wn, image=img)
label1.pack(side="top", fill="both", expand="yes")
# label1.grid_rowconfigure(0, weight=1)
# label1.grid_columnconfigure(0, weight=1)
# label1.grid_rowconfigure(1, weight=1)
def callback1():
import Detection1
def callback():
import detection
button1 = tk.Button(label1, text="Health Identification", command=callback, bd=12, bg="grey", font="caliber")
button1.place(x=100, y=500)
button2 = tk.Button(label1, text="Disease Classification", command=callback1, bd=10, bg="grey", font="caliber")
button2.place(x=400, y=500)
wn.mainloop()

How to resize Canvas scrollable widget?

The idea is that the scrollable canvas and its text widgets grow or fill the entire root/toplevel when I resize it.
I can do this if I work on Frames but for a scrollable frame you need to create a canvas widget and make it scrollable. Now I don't know if the problem is the canvas or the inserted widgets on the canvas?
import tkinter as tk
from tkinter import ttk
class ScrollableFrame():
def __init__(self, container, *args, **kwargs):
self.container = container
self.canvas = tk.Canvas(self.container, bg="green")
self.scrollbar = ttk.Scrollbar(self.container, orient="horizontal", command=self.canvas.xview)
self.scrollable_frame = tk.Frame(self.canvas)
self.scrollable_frame.grid(sticky="wesn")
self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
self.canvas.configure(xscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky="wesn")
self.scrollbar.grid(row=1, column=0, sticky="wesn")
if __name__ == "__main__":
root = tk.Tk()
root.configure(bg="grey20")
s = ScrollableFrame(root)
t = tk.Text(s.scrollable_frame)
t.grid(row=0, column=0, sticky="wesn")
t2 = tk.Text(s.scrollable_frame)
t2.grid(row=0, column=1, sticky="wesn")
root.mainloop()
I'm glad for help
Base on the requirement in the comment, you want to grow/shrink the two text boxes when the root window is resized. Below is the modified code with the necessary changes to achieve it:
import tkinter as tk
from tkinter import ttk
class ScrollableFrame():
def __init__(self, container, *args, **kwargs):
self.container = container
self.canvas = tk.Canvas(self.container, bg="green")
self.scrollbar = ttk.Scrollbar(self.container, orient="horizontal", command=self.canvas.xview)
self.scrollable_frame = tk.Frame(self.canvas)
self.scrollable_frame.grid(sticky="wesn")
self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw", tags="scrollable")
self.canvas.configure(xscrollcommand=self.scrollbar.set)
self.canvas.grid(row=0, column=0, sticky="wesn")
self.scrollbar.grid(row=1, column=0, sticky="we") # fill horizontally only
# make self.canvas to fill all the available space of container
container.rowconfigure(0, weight=1)
container.columnconfigure(0, weight=1)
# resize self.scrollable_frame when self.canvas is resized
self.canvas.bind("<Configure>", lambda e: self.canvas.itemconfig("scrollable", width=e.width, height=e.height))
if __name__ == "__main__":
root = tk.Tk()
root.configure(bg="grey20")
s = ScrollableFrame(root)
# make the two text boxes to fill all the space of s.scrollable_frame
s.scrollable_frame.rowconfigure(0, weight=1)
s.scrollable_frame.columnconfigure((0,1), weight=1)
t = tk.Text(s.scrollable_frame)
t.grid(row=0, column=0, sticky="wesn")
t2 = tk.Text(s.scrollable_frame)
t2.grid(row=0, column=1, sticky="wesn")
root.mainloop()
So basically the logic is when the root window is resized, the canvas is resized to fill the root window. Then the frame (scrollable_frame) inside the canvas is resized to fill the canvas and finally the two text widgets are resized to fill the scrollable_frame.

Tkinter style not being applied

I'm simply trying to change to "clam" style but nothing changes. I have a more expansive UI written with other widgets, so I know that nothing changes when I try to change the style:
I'm working in Linux Mint 19.2, Python 3.6.8, and using Pycharm. I've verified that Pycharm is not the issue by running from terminal.
from tkinter import *
from tkinter.ttk import Style
class Window(Frame):
def __init__(self, master=None):
self.master = master
self.add_widgets()
def add_widgets(self, ):
self.mainframe = Frame(self.master, border=3)
self.mainframe.grid(columnspan=3, sticky='w', padx=5, pady=5)
Label(self.mainframe, text="Directory Selection", font='Helvetica 12 bold italic underline').grid(column=0, sticky="w")
self.pathframe = Frame(self.mainframe, relief=RIDGE, border=2)
self.pathframe.grid(rowspan=3, columnspan=3, sticky='w', padx=0, pady=10)
button_color="dark gray";
Button(self.pathframe, text="Run Folder Path", bg=button_color).grid(sticky="w")
Entry(self.pathframe, width=43).grid(row=0, column=1, sticky="w")
root = Tk()
style = Style()
style.theme_use("clam")
root.title('TestUI')
root.geometry("500x500")
app = Window(root)
root.mainloop()
I also tried:
style = Style(root)
style.theme_use("clam")
and still no change.
You're not using any ttk widgets. The normal tkinter widgets aren't affected by the ttk styles.
Typically this is done by importing ttk and then prefixing the widgets with ttk
from tkinter import ttk
...
self.mainframe = ttk.Frame(self.master, border=3)
...

Resources