scrollbar not working for an inner frame inside a canvas - python

I am trying to build a pattern for question paper...
I created a canvas in a frame and added a scrollbar. I created another frame inside and set the scrollbar to it. THe pattern for a question is in a frames which is repeated on the inner frame as per choice of user.
But the scrollbar is not working here, so after the question pattern has crossed the page, I cannot view them.
Here is a shortened form of my code.....
from tkinter import *
from tkinter import ttk
home = Tk()
width = home.winfo_screenwidth() - 20
height = home.winfo_screenheight() - 100
home.wm_geometry(f"{width}x{height}")
home.state("zoomed")
frame1 = Frame(home, bg='RED')
frame2 = Frame(home, bg='yellow')
frame1.pack(fill=Y, side=LEFT)
frame2.pack(fill=BOTH, expand=YES, side=LEFT)
label1 = Label(frame1, text="Label for Frame1", bg='light blue')
label1.grid(row=0, column=0)
def handle_resize(event):
canvas = event.widget
canvas_frame = canvas.nametowidget(canvas.itemcget("canvas_frame", "window"))
min_width = canvas_frame.winfo_reqwidth()
min_height = canvas_frame.winfo_reqheight()
if min_width < event.width:
canvas.itemconfigure("canvas_frame", width=event.width)
if min_height < event.height:
canvas.itemconfigure("canvas_frame", height=event.height)
canvas.configure(scrollregion=canvas.bbox("all"))
question_type_canvas = Canvas(frame2, bg='light green')
question_type_canvas.pack(side=LEFT, expand=YES, fill=BOTH)
inner_question_type_frame = Frame(question_type_canvas)
question_type_canvas.create_window((0, 0), window=inner_question_type_frame, anchor='nw', tags=("canvas_frame",))
vbar = Scrollbar(frame2, orient=VERTICAL, command=question_type_canvas.yview())
vbar.pack(side=RIGHT, fill=Y)
question_type_canvas.configure(yscrollcommand=vbar.set)
question_type_canvas.bind('<Configure>', handle_resize)
def clone_question_types(ques_index, row_number):
question_type_frame = Frame(inner_question_type_frame, bg='light pink')
question_type_frame.grid(row=row_number, column=0)
question_types_dict = dict({'Multiple Choice Questions': 1,
'Fill in the Blanks': 2})
question_types_combo_values = list(question_types_dict.keys())
question_no_label = Label(question_type_frame, text=f'Q {ques_index + 1}', bg='light pink', width=5)
type_label = Label(question_type_frame, text='Type: ', width=20, padx=5, bg='light pink')
type_selected = StringVar(question_type_frame)
type_menu = ttk.Combobox(question_type_frame, textvariable=type_selected,
values=list(question_types_combo_values), width=20, state="readonly")
next_question_button = Button(question_type_frame, text='Next Question',
command=lambda: [next_question_button.configure(state=DISABLED),
clone_question_types(ques_index + 1, row_number + 1)])
question_no_label.grid(row=0, column=0, sticky='w')
type_label.grid(row=0, column=1, sticky='w')
type_menu.grid(row=0, column=2, sticky='w')
next_question_button.grid(row=3, column=1)
clone_question_types(0, 0)
home.mainloop()

Related

why my tkinter scrollbar not working after adding scrollbar?

I have made a user interface but my scrollbar is not working. it is working if i add content statically but when i add frames from button click then it adds new frame but not scrolling to view bottom content or we can say the scroll bar is disabled.
Here is my code:
import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.title("Hello Python")
root.configure(bg="#010523")
root.iconbitmap('logo.ico')
root.geometry("400x500")
frame_main = tk.Frame(root, bg="#010523")
frame_main.grid(sticky='news')
# ********************header frame********************************
header_frame = LabelFrame(frame_main, bg="#010523", border=0, height=100)
header_frame.grid(row=0, column=0, columnspan=2, sticky='ew')
width =50
height =50
photo= Image.open("logo.png")
photo= photo.resize((width, height),Image.ANTIALIAS)
# create an object of PhotoImage
photoImg = ImageTk.PhotoImage(photo)
photo_label= Label(header_frame, image=photoImg, bg="#010523")
photo_label.grid(row=0, column=0, rowspan=2)
# Label
public_broadcast = Label(header_frame, text="Public broadcast",
font="bold", bg="#010523", fg="white")
public_broadcast.grid(row=0, column=1)
_id = Label(header_frame, text="MY ID: 0013A20041EFD12C",
font="10", bg="#010523", fg="grey")
_id.grid(row=1, column=1, padx=10)
# ********************end of header frame*************************
# label1 = tk.Label(frame_main, text="Label 1", fg="green")
# label1.grid(row=0, column=0, pady=(5, 0), sticky='nw')
# label2 = tk.Label(frame_main, text="Label 2", fg="blue")
# label2.grid(row=1, column=0, pady=(5, 0), sticky='nw')
# label3 = tk.Label(frame_main, text="Label 3", fg="red")
# label3.grid(row=3, column=0, pady=5, sticky='nw')
# Create a frame for the canvas with non-zero row&column weights
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow 5-by-5 buttons resizing later
frame_canvas.grid_propagate(False)
# Add a canvas in that frame
canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")
# Link a scrollbar to the canvas
vsb = tk.Scrollbar(frame_canvas, orient=VERTICAL, command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
# Create a frame to contain the buttons
frame_buttons = tk.Frame(canvas, bg="blue")
# Add 9-by-5 buttons to the frame
last_frame_row = 3
frame_canvas.config(width=400, height=300)
# Entering self msg frame with text
def add_msg_frame():
global last_frame_row
msg = "This is a test msg"
# msg = e.get()
# e.delete(0, END)
new_frame = Frame(frame_buttons, bg="#4857a8", borderwidth=0)
new_frame.grid(row=last_frame_row, column=1, columnspan=2, sticky='e', pady=5)
last_frame_row += 1
new_label = Label(new_frame, text=msg, font="10", bg="#4857a8", fg="white")
new_label.grid(row=0, column=0)
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
def add_reply_msg(device_id="0983ADFCD9827sd", msg="this is a sample message"):
global last_frame_row
new_frame = Frame(frame_buttons, bg="#1f243f", borderwidth=0)
new_frame.grid(row=last_frame_row, column=0, columnspan=2, sticky='w', pady=5)
last_frame_row += 1
new_label = Label(new_frame, text=device_id, bg="#1f243f", font="10", fg="#a6a6a6")
new_label.grid(row=0, column=0)
new_label2 = Label(new_frame, text=msg, font="10", bg="#1f243f", fg="white")
new_label2.grid(row=1, column=0)
# Update buttons frames idle tasks to let tkinter calculate buttons sizes
# for i in range(30):
# add_msg_frame()
add_reply_msg()
add_reply_msg()
add_msg_frame()
frame_buttons.update_idletasks()
# Set the canvas scrolling region
canvas.config(scrollregion=canvas.bbox("all"), yscrollcommand=vsb.set)
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
canvas.bind('<Configure>', lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
# # Entry
eFrame = Frame(root, width=400, height=100)
eFrame.grid(row=1000, column=0)
e = Entry(eFrame, width=50)
e.grid(row=0, column=0)
ebtn = Button(eFrame, text="Send", bg="skyblue", command=add_msg_frame)
ebtn.grid(row=0, column=1)
# Launch the GUI
root.mainloop()
Please give me suggestions that how can i enable scrollbar when add a frame by clicking the send button.
Thank you.
You need to update the scrollregion whenever you add or modify things on the canvas.
frame_buttons will be resized when items are added to it, so you need to update the scrollregion of the canvas in this case via bind('<Configure>', ...). Also it is better to call canvas.create_window((0, 0), window=frame_buttons, anchor='nw') once outside the function add_msg_frame():
...
# Create a frame to contain the buttons
frame_buttons = tk.Frame(canvas, bg="blue")
# call canvas.create_window(...) once here
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
# update scrollregion of canvas whenever the frame is resized
frame_buttons.bind('<Configure>', lambda e: canvas.config(scrollregion=canvas.bbox('all')))
...

How to create Tkinter Tab frame with different (dynamic) heights

I am trying to create Tabs in python tkinter. I would like the Tab's height to size dynamically based on its content. Below is a sample of my code
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Frames')
root.geometry('500x500')
frame1 = LabelFrame(root)
frame1.pack(padx=5, pady = 5)
notebook1 = ttk.Notebook(frame1)
notebook1.pack(pady= 5)
nbframe1 = Frame(notebook1, bg = 'white')
nbframe2 = Frame(notebook1, bg = 'grey')
nbframe1.pack(fill ='both', expand=1)
nbframe2.pack(fill ='both', expand=1)
notebook1.add(nbframe1, text= 'A Search')
notebook1.add(nbframe2, text= 'B Search')
a_label = Label(nbframe1, text= 'A_Tag', bg = 'white')
a_label.grid(row = 0, column = 0, sticky=W, padx=5)
b_label = Label(nbframe1, text= 'B_Tag', bg = 'white')
b_label.grid(row = 1, column = 0, sticky=W, padx=5)
a_text = StringVar()
a_entry = Entry(nbframe1, textvariable = a_text, width=50)
a_entry.grid(row = 0, column = 1, sticky=W, padx=5)
b_text = StringVar()
b_entry = Entry(nbframe1, textvariable = b_text, width=25)
b_entry.grid(row = 1, column = 1, sticky=W, padx=5)
root.mainloop()
From my code, the Tabs created have same height even though one is empty. This is based on the height of the Tab with content. How can i set it so that each Tab's height is based only on the contents.
You can bind a function to the virtual event <<NotebookTabChanged>> to adapt the height of the notebook to the currently selected tab using the height option of the notebook:
def on_change_tab(event):
tab = event.widget.nametowidget(event.widget.select()) # get selected tab
event.widget.configure(height=tab.winfo_reqheight()) # resize notebook
With your example:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Frames')
root.geometry('500x500')
def on_change_tab(event):
tab = event.widget.nametowidget(event.widget.select())
event.widget.configure(height=tab.winfo_reqheight())
frame1 = LabelFrame(root)
frame1.pack(padx=5, pady=5)
notebook1 = ttk.Notebook(frame1)
notebook1.pack(pady=5)
nbframe1 = Frame(notebook1, bg='white')
nbframe2 = Frame(notebook1, bg='grey')
notebook1.add(nbframe1, text='A Search')
notebook1.add(nbframe2, text='B Search')
a_label = Label(nbframe1, text='A_Tag', bg='white')
a_label.grid(row=0, column=0, sticky=W, padx=5)
b_label = Label(nbframe1, text='B_Tag', bg='white')
b_label.grid(row=1, column=0, sticky=W, padx=5)
a_text = StringVar()
a_entry = Entry(nbframe1, textvariable=a_text, width=50)
a_entry.grid(row=0, column=1, sticky=W, padx=5)
b_text = StringVar()
b_entry = Entry(nbframe1, textvariable=b_text, width=25)
b_entry.grid(row=1, column=1, sticky=W, padx=5)
root.update_idletasks() # force display update so that the initial tab is displayed correctly
notebook1.bind('<<NotebookTabChanged>>', on_change_tab) # binding to update the height
root.mainloop()

Tkinter, alignment - the endless question

Since some days I'll try to align these two items inside a Tkinter frame:
The pink part should be on the left and the green button on the right. With HtmlDivs and CSS a question of seconds, with TKinter a pain in the ...
Here is my python code:
import tkinter as tk
root = tk.Tk()
root.geometry("400x200")
buttons = tk.Frame(root)
buttons.pack(side="top", expand=True, fill='both')
label = tk.Label(buttons, text="Hello, world", anchor='w', background='pink')
b2 = tk.Button(buttons, text="EXIT", background='green')
label.grid(row=0, column=1, sticky='w', ipadx = '20', padx = '20')
b2.grid(row=0, column=3, sticky='e', ipadx = '20', padx = '20')
root.mainloop()
The final app will be running fullscreen on a 7" touch display.
The simplest solution is to use pack instead of grid, since you only have a single row of widgets inside of buttons. pack's strength is arranging things in a single row or a single column.
Just remove these two lines:
label.grid(row=0, column=1, sticky='w', ipadx = '20', padx = '20')
b2.grid(row=0, column=3, sticky='e', ipadx = '20', padx = '20')
... and replace them with this:
label.pack(side='left')
b2.pack(side='right')
Also, since you appear to be creating a toolbar, you want to leave expand as False and set fill to just "x", otherwise the toolbar will expand to fill the entire window:
buttons.pack(side="top", expand=False, fill='x')
Thx for your tips,
this is just a testcode to update my maincode.
Its not good to mix .pack and .grid, right ? If i do, the script crashes completely,
so ill have to re-do my mainscript i think.
This is what i need:
row: 1/2: label (it will be a real time clock) left 2/2: exit button (exit fullscreen) right
row: 1/3: image (weather), 2/3: weather data (label), 3/3: calendar
row: 4 buttons: 1. lightoff 2. light25%, 3.light50% 4.light100&
Thats it basically all is working, it just need to align it (im a coding hero g)
Since i have the frame from the code above, i thought i can easily add 2. & 3. row with another frames, but that does not seem to work ??
Preview:
https://i.stack.imgur.com/KzoqV.png
My (main)Code so far
root = Tk()
root.title('Model Definition')
root.config(background = "deepskyblue4")
root.attributes('-fullscreen',True)
root.bind('<Escape>',lambda e: root.destroy())
def currenttime():
string = strftime("%A, %d.%B.%Y %H:%M:%S")
lbl.config(text = string, background = 'deepskyblue4', fg='white', font=("colibri", 30))
lbl.after(1000, currenttime)
def light400():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 401'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light425():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 425'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light450():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 450'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
def light475():
FNULL = open(os.devnull, 'w')
subprocess.call(['gpio -g pwm 18 500'], stdout=FNULL, stderr=subprocess.STDOUT, shell=True)
# Main frames
top_frame = Frame(root, bg='deepskyblue4', width=450, height=90, pady=3)
center = Frame(root, bg='deepskyblue2', width=50, height=40, padx=3, pady=3)
btm_frame = Frame(root, bg='deepskyblue4', width=450, height=20, pady=3)
btm_frame2 = Frame(root, bg='deepskyblue4', width=450, height=60, pady=3)
# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
top_frame.grid(row=0, sticky="e", padx=(10, 0))
center.grid(row=1, sticky="nsew", pady=(10, 50))
btm_frame.grid(row=3, sticky="ew")
btm_frame2.grid(row=4, sticky="ew", padx=(10, 50))
# create the widgets for the top frame
lbl = Label(top_frame, background = 'deepskyblue4', anchor=W, justify=LEFT)
lbl.pack()
currenttime()
actionbutton = Button(top_frame, text="X", width=5, height=2, bg="deepskyblue4", fg="white", command=root.destroy)
hdr_left = Frame(top_frame, bg='deepskyblue4', width=100, height=190)
hdr_right = Frame(top_frame, bg='deepskyblue4', width=400, height=190, padx=3, pady=3)
# layout the widgets in the top frame
lbl.grid(row=0, column=1, sticky="w")
actionbutton.grid(row=0, column=2, sticky="e")
# create the center widgets
center.grid_rowconfigure(0, weight=1)
center.grid_columnconfigure(1, weight=1)
ctr_left = Frame(center, bg='deepskyblue2', width=100, height=190)
ctr_mid = Frame(center, bg='deepskyblue2', width=150, height=190, padx=3, pady=3)
ctr_right = Frame(center, bg='deepskyblue2', width=400, height=190, padx=3, pady=3)
ctr_left.grid(row=0, column=0, sticky="ns")
ctr_mid.grid(row=0, column=1, sticky="nsew")
ctr_right.grid(row=0, column=2, sticky="ns")
path = "icons/rain.png"
img = ImageTk.PhotoImage(Image.open(path))
panel = Label(ctr_left, image = img, bg="deepskyblue2")
panel.grid(row=0, columnspan=3)
#imgag = panel.pack(top_frame)
#CENTER ctr_mid
if x["cod"] != "404":
y = x["main"]
y2 = x["wind"]
currenttemp = y["temp"]
currentpressure = y["pressure"]
currenthumidiy = y["humidity"]
z = x["weather"]
weather_description = z[0]["description"]
currentwind = y2["speed"]
label1 = Label(ctr_mid,text='Karlsruhe', font = ('calibri', 30), background = 'deepskyblue2')
label2 = Label(ctr_mid,text='Temperatur: '+str(round(currenttemp-272.15))+' °C', font = ('calibri', 20), background = 'deepskyblue2')
label3 = Label(ctr_mid,text='Beschreibung: '+str(weather_description),font = ('calibri', 20), background = 'deepskyblue2')
label4 = Label(ctr_mid,text='Druck: '+str(currentpressure)+' hPa', font = ('calibri', 20), background = 'deepskyblue2')
label5 = Label(ctr_mid,text='Feuchtigkeit: '+str(currenthumidiy)+' %',font = ('calibri', 20), background = 'deepskyblue2')
label6 = Label(ctr_mid,text='Wind: '+str(currentwind)+' m/Sek',font = ('calibri', 20), background = 'deepskyblue2')
label1.grid(row=0, column=0, sticky="nw")
label2.grid(row=1, column=0, sticky="nw")
label3.grid(row=2, column=0, sticky="nw")
label4.grid(row=3, column=0, sticky="nw")
label5.grid(row=4, column=0, sticky="nw")
label6.grid(row=5, column=0, sticky="nw")
# btm_frame2 widgets
licht = Label(btm_frame2, text='Licht:', width=5, height=1, bg="deepskyblue4", fg='white', font=("colibri", 20))
button = Button(btm_frame2, command=light400, text="AUS", width=5, height=1, bg="deepskyblue2", fg="white")
button2 = Button(btm_frame2, text="25 %", command=light425, width=5, height=1, bg="deepskyblue2", fg="white")
button3 = Button(btm_frame2, text="50%", command=light450, width=5, height=1, bg="deepskyblue2", fg="white")
button4 = Button(btm_frame2, text="100%", command=light475, width=5, height=1, bg="deepskyblue2", fg="white")
licht.grid(row=0, column=0, sticky="nw")
button.grid(row=0, column=1, sticky="nw")
button2.grid(row=0, column=2, sticky="nw")
button3.grid(row=0, column=3, sticky="nw")
button4.grid(row=0, column=4, sticky="nw")
actionbutton.grid(row=0, column=6, sticky="nw")
root.mainloop()

how to replace text in tkinter?

I'm making a wrong-word corrector so I use replace method, but it doesn't work
because it is not all same word.
For example:
string = i like icecream
I want to change the word = icecream
It only works for "i like icecream" if it is all the same
This is my whole code:
# coding: utf-8
from tkinter import *
import tkinter.messagebox
root=Tk()
root.title("words corrector")
root.resizable(0, 0)
root.geometry("+{}+{}".format(600, 400))
mainFrame = Frame(root, width=600, height=400)
mainFrame.pack()
textFrame = Frame(mainFrame, width=100, height=100)
textFrame.pack()
textFrame_1 = Frame(mainFrame, width=100, height=100)
textFrame_1.pack()
textFrame_2 = Frame(mainFrame,width=100, height=100)
textFrame_2.pack()
scrollbar = Scrollbar(textFrame)
scrollbar.pack(side=RIGHT, fill="y")
#textField == sentance
textField = Text(textFrame, width=50, height=10, bd=5, relief="groove")
textField.insert(CURRENT,"enter the text\n")
textField.pack(side=LEFT, padx=(5, 0), pady=(5, 5))
textField["yscrollcommand"] = scrollbar.set
#textField_2 == wrong word
textField_2= Text(textFrame_1, width=15, height=3, bd=5, relief="groove")
textField_2.insert(CURRENT,"wrong words\n")
textField_2.pack(side=LEFT, padx=(5,0), pady=(5,5))
#textField_3 == correct word
textField_3= Text(textFrame_1,width=15, height=3, bd=5, relief="groove")
textField_3.insert(CURRENT, "correct words\n")
textField_3.pack(side=LEFT, padx=(5,0), pady=(5,5))
def chg():
sentance = textField.get("1.0",END)
wrong_word = textField_2.get("1.0",END)
correct_word = textField_3.get("1.0",END)
result = sentance.replace(wrong_word,correct_word)
textField_4.insert("1.0",result)
def msg():
tkinter.messagebox.showerror("error","there's no words")
def ok():
if textField_2.get("1.0",END) in textField.get("1.0",END):
chg()
else:
msg()
okButton = Button(textFrame_1, text="OK", command=ok)
okButton.pack(padx=40, pady=(20,5))
scrollbar_2 = Scrollbar(textFrame_2)
scrollbar_2.pack(side=RIGHT, fill="y")
textField_4 = Text(textFrame_2, width=50, height=10, bd=5, relief="groove")
textField_4.pack(side=LEFT, padx=(5, 0), pady=(5, 5))
textField_4["yscrollcommand"] = scrollbar.set
root.mainloop()
Try the following code. You have to convert unicode characters to a string and use str.replace.
from tkinter import *
import tkinter.messagebox
root=Tk()
root.title("words corrector")
root.resizable(0, 0)
root.geometry("+{}+{}".format(600, 400))
mainFrame = Frame(root, width=600, height=400)
mainFrame.pack()
textFrame = Frame(mainFrame, width=100, height=100)
textFrame.pack()
textFrame_1 = Frame(mainFrame, width=100, height=100)
textFrame_1.pack()
textFrame_2 = Frame(mainFrame,width=100, height=100)
textFrame_2.pack()
scrollbar = Scrollbar(textFrame)
scrollbar.pack(side=RIGHT, fill="y")
#textField == sentance
textField = Text(textFrame, width=50, height=10, bd=5,
relief="groove")
textField.insert(CURRENT,"enter the text\n")
textField.pack(side=LEFT, padx=(5, 0), pady=(5, 5))
textField["yscrollcommand"] = scrollbar.set
#textField_2 == wrong word
textField_2= Text(textFrame_1, width=15, height=3, bd=5,
relief="groove")
textField_2.insert(CURRENT,"wrong words\n")
textField_2.pack(side=LEFT, padx=(5,0), pady=(5,5))
#textField_3 == correct word
textField_3= Text(textFrame_1,width=15, height=3, bd=5,
relief="groove")
textField_3.insert(CURRENT, "correct words\n")
textField_3.pack(side=LEFT, padx=(5,0), pady=(5,5))
scrollbar_2 = Scrollbar(textFrame_2)
scrollbar_2.pack(side=RIGHT, fill="y")
textField_4 = Text(textFrame_2, width=50, height=10, bd=5,
relief="groove")
textField_4.pack(side=LEFT, padx=(5, 0), pady=(5, 5))
textField_4["yscrollcommand"] = scrollbar.set
def chg():
sentance = textField.get("1.0",END)
wrong_word = textField_2.get("1.0",END)
correct_word = textField_3.get("1.0",END)
# result = sentance.replace(wrong_word,correct_word)
result = str.replace(str(sentance), wrong_word, correct_word)
textField_4.insert("1.0",result)
def msg():
tkinter.messagebox.showerror("error","there's no words")
def ok():
# if textField_2.get("1.0",END) in textField.get("1.0",END):
chg()
# else:
# msg()
okButton = Button(textFrame_1, text="OK", command=ok)
okButton.pack(padx=40, pady=(20,5))
root.mainloop()
OUTPUT:
EDIT
If you want want to keep that "enter the text part" and type your sentence below, without replacing it, you should do the following in the relevant line for the code to work.
result = str.replace(str(sentance).replace('enter the text\n',''), wrong_word.replace('wrong words\n',''), correct_word.replace('correct words\n',''))

Python Tkitner : unknown option "-height". Can't change the size of button

I am trying to make a simple program using tkinter.
I was trying to change font or style of width or height.
width can be changed but when it comes to height or font - it shows mistake.
I am thinking - maybe it can be because the layout?
(The button that is changed in width is in the bottom of def initUI)
Also in case anyone can also answer this question:
I made 1 frame red because there will be error messages there but does anyone know how to make this red lie less in width?
Thank you in
from tkinter import *
from tkinter.ttk import *
class Example(Frame):
def __init__(self,master):
super().__init__()
master.minsize(width=350, height=160)
master.maxsize(width=650, height=500)
self.initUI()
def initUI(self):
self.master.title("Hank (version 3)")
self.pack(fill=BOTH, expand=True)
frame1 = Frame(self)
frame1.pack(fill=X)
#dataset
lbl1 = Label(frame1, text="Dataset file_name", width=18)
lbl1.pack(side=LEFT, padx=5, pady=5)
entryDataset= Entry(frame1)
entryDataset.pack(fill=X, padx=5, expand=True)
#row col begin
frame2 = Frame(self)
frame2.pack(fill=X)
lblRow = Label(frame2, text="Row", width=6)
lblRow.pack(side=LEFT, padx=5, pady=5)
entryRow = Entry(frame2, width=5)
entryRow.pack(side=LEFT, padx=0, expand=True)
lblCol = Label(frame2, text="Column", width=7.5)
lblCol.pack(side=LEFT, padx=5, pady=5)
entryCol = Entry(frame2, width=5)
entryCol.pack(side=LEFT, padx=5, expand=True)
lblBegin = Label(frame2, text="Start at", width=6)
lblBegin.pack(side=LEFT, padx=5, pady=5)
entryBegin = Entry(frame2, width=5)
entryBegin.pack(side=LEFT, padx=0, expand=True)
#console window
s = Style()
s.configure('My.TFrame', background='grey')
frame3 = Frame(self, style='My.TFrame')
frame3.pack(fill=BOTH, expand=True)
#button start and help
s = Style()
s.configure('My.ConsoleFrame', background='red')
frame4 = Frame(self)
frame4.pack(fill=BOTH, expand=True)
startbutton = Button(frame4, text="Start Clustering", height="100", width="100")
startbutton.pack(side=RIGHT, padx=5, pady=5)
def main():
root = Tk()
root.geometry("300x160+300+160")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
This is one of the prime examples of why global imports are bad.
You write at the top:
from tkinter import *
from tkinter.ttk import *
This means that you import everything from tkinter and tkinter.ttk into your main.py namespace. Then you write for example:
frame3 = Frame(self, bg="grey")
....
lblCol = Label(frame2, text="Column", width=7)
These are Frame/Label objects, but which ones? The one in tkinter or the one in tkinter.ttk? If it is the first, you will have to set the height with -height, else you will have to use tkinter.ttk.Style(). Same with the -bg for the frame.
Solution:
import tkinter as tk
class Example(tk.Frame):
def __init__(self,master):
super().__init__()
master.minsize(width=350, height=160)
master.maxsize(width=650, height=500)
self.initUI()
def initUI(self):
self.master.title("Hank (version 3)")
self.pack(fill=tk.BOTH, expand=True)
frame1 = tk.Frame(self)
frame1.pack(fill=tk.X)
#dataset
lbl1 = tk.Label(frame1, text="Dataset file_name", width=18)
lbl1.pack(side=tk.LEFT, padx=5, pady=5)
entryDataset= tk.Entry(frame1)
entryDataset.pack(fill=tk.X, padx=5, expand=True)
#row col begin
frame2 = tk.Frame(self)
frame2.pack(fill=tk.X)
lblRow = tk.Label(frame2, text="Row", width=6)
lblRow.pack(side=tk.LEFT, padx=5, pady=5)
entryRow = tk.Entry(frame2, width=5)
entryRow.pack(side=tk.LEFT, padx=0, expand=True)
lblCol = tk.Label(frame2, text="Column", width=7)
lblCol.pack(side=tk.LEFT, padx=5, pady=5)
entryCol = tk.Entry(frame2, width=5)
entryCol.pack(side=tk.LEFT, padx=5, expand=True)
lblBegin = tk.Label(frame2, text="Start at", width=6)
lblBegin.pack(side=tk.LEFT, padx=5, pady=5)
entryBegin = tk.Entry(frame2, width=5)
entryBegin.pack(side=tk.LEFT, padx=0, expand=True)
frame3 = tk.Frame(self, bg="grey")
frame3.pack(fill=tk.BOTH, expand=True)
frame4 = tk.Frame(self)
frame4.pack(fill=tk.BOTH, expand=True)
startbutton = tk.Button(frame4, text="Start Clustering", height="100", width="100")
startbutton.pack(side=tk.RIGHT, padx=5, pady=5)
def main():
root = tk.Tk()
root.geometry("300x160+300+160")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
I did it here with the tkinter widgets. You can obviously do import tkinter.ttk as ttk and rewrite the code using those, it is just a matter of taste.

Categories

Resources