Tkinter buttons are mixing with eachother - python

I don't know how to explain it but I have two different pages each with a certain number of buttons as grid
Simple form
Complex form
but when I select one of the radio buttons then select the other one after it gets mixed
Chaos
Here is the code for making the grid
import tkinter as tk
from tkinter import filedialog, Text
import os
import time, sys
from time import sleep
root = tk.Tk()
root.geometry('700x700')
def changecolo(i, j):
if not ((i == 0 and j == 0) or (i == 12 and j == 12)):
if mFrame.grid_slaves(row = i, column = j)[0].cget('bg') == 'black':
mFrame.grid_slaves(row = i, column = j)[0].configure(bg = 'white')
elif mFrame.grid_slaves(row = i, column = j)[0].cget('bg') == 'white':
mFrame.grid_slaves(row = i, column = j)[0].configure(bg = 'grey')
elif mFrame.grid_slaves(row = i, column = j)[0].cget('bg') == 'grey':
mFrame.grid_slaves(row = i, column = j)[0].configure(bg = 'black')
def setalg():
value = 6
def makegrid6():
mFrame.grid_forget()
makegrid66()
def makegrid66():
for i in range(6):
for j in range (6):
if i == 0 and j == 0:
grids6 = tk.Button(mFrame, bg='blue', text = (5 - i) + (5 - j), state = 'disabled', highlightcolor="black", highlightthickness=1, width = 11, height = 5)
grids6.grid(row = i, column = j)
elif i == 5 and j == 5:
grids6 = tk.Button(mFrame, bg='red', text = (5 - i) + (5 - j) , state = 'disabled',highlightcolor="black", highlightthickness=1, width = 11, height = 5)
grids6.grid(row = i, column = j)
elif (((i == 0 or i == 1 or i == 2) and (j == 2)) or (i == 4 and j == 1)):
grids6 = tk.Button(mFrame, bg='white', text = (5 - i) + (5 - j) , highlightcolor="black", highlightthickness=1, width = 11, height = 5, state = 'disabled')
grids6.grid(row = i, column = j)
elif (i == 3 and j == 2):
grids6 = tk.Button(mFrame, bg='grey', text = (5 - i) + (5 - j) , highlightcolor="black", highlightthickness=1, width = 11, height = 5, state = 'disabled')
grids6.grid(row = i, column = j)
else:
grids6 = tk.Button(mFrame, bg='black', text = (5 - i) + (5 - j), fg = 'white', highlightcolor="black", highlightthickness=1, width = 11, height = 5, state = 'disabled')
grids6.grid(row = i, column = j)
return mFrame.grid_slaves, i, j
def makegrid10():
mFrame.grid_forget()
makegrid100()
def makegrid100():
for i in range(13):
for j in range (13):
if i == 0 and j == 0:
grids10 = tk.Button(mFrame, bg='blue', text = (12 - i) + (12 - j), fg = 'white', state = 'disabled', highlightcolor="black", highlightthickness=1, width = 4, height = 2, command=lambda x = i, y = j: changecolo(x, y))
grids10.grid(row = i, column = j)
elif i == 12 and j == 12:
grids10 = tk.Button(mFrame, bg='red', text = (12 - i) + (12 - j), fg = 'white', state = 'disabled',highlightcolor="black", highlightthickness=1, width = 4, height = 2, command=lambda x = i, y = j: changecolo(x, y))
grids10.grid(row = i, column = j)
else:
grids10 = tk.Button(mFrame, bg='black', text = (12 - i) + (12 - j), fg = 'white', highlightcolor="black", highlightthickness=1, width = 4, height = 2, command=lambda x = i, y = j: changecolo(x, y))
grids10.grid(row = i, column = j)
return mFrame.grid_slaves, i, j
def play():
if diffVar.get() == "sim":
butons, l, k = makegrid66()
Greedy(butons, l, k)
else:
butons, l, k = makegrid100()
Greedy(butons, l, k)
def aStar():
print(1000010)
def Greedy(butons, k, l):
print(k, l)
def UCS():
print(99)
mFrame = tk.Frame(root, height = 500, width = 500, bg = "lightgrey")
mFrame.place(x= 10, y = 10)
diffVar = tk.StringVar()
dif = tk.Label(root, text = "Problem Difficulty", bg = "Lightgrey")
dif.place (x = 550, y = 30)
simp = tk.Radiobutton(root, text = "Simple", value = "sim", bg = "Lightgrey", variable = diffVar, command = makegrid6)
simp.place(x = 550, y = 60)
comp = tk.Radiobutton(root, text = "Complex", value = "com", bg = "Lightgrey", variable = diffVar, command = makegrid10)
comp.place(x = 550, y = 90)
algVar = tk.IntVar()
algVar.set(1)
dif = tk.Label(root, text = "Choose an Algorithm", bg = "Lightgrey")
dif.place (x = 550, y = 180)
alg1 = tk.Radiobutton(root, text = "A*", value = 1, bg = "Lightgrey", variable = algVar, command = setalg)
alg1.place(x = 550, y = 210)
alg2 = tk.Radiobutton(root, text = "Greedy", value = 2, bg = "Lightgrey", variable = algVar, command = setalg)
alg2.place(x = 550, y = 240)
alg3 = tk.Radiobutton(root, text = "UCS", value = 3, bg = "Lightgrey", variable = algVar, command = setalg)
alg3.place(x = 550, y = 270)
playbu = tk.Button(root, text = "Play", bg = "White", width = 15, command = play)
playbu.place(x = 10, y = 550)
nextbu = tk.Button(root, text = "Next", bg = "White", width = 15)
nextbu.place(x = 140, y = 550)
fasterbu = tk.Button(root, text = "Faster", bg = "White", width = 15)
fasterbu.place(x = 270, y = 550)
resetbu = tk.Button(root, text = "Reset", bg = "White", width = 15)
resetbu.place(x = 400, y = 550)
root.mainloop()
is their any possible way that the buttons will resize themself in a way that they fit in the same size as the canvas, without me adjusting the width and the height of the button

First I used this to remove old Frame with all buttons and to create new Frame for new buttons
def makegrid6():
global mFrame
mFrame.destroy()
mFrame = tk.Frame(root, height = 500, width = 500, bg = "lightgrey")
mFrame.place(x= 10, y = 10)
makegrid66()
but it had one problem - new Frame was created on top of other widgets so then were hidden and unavaliable.
So I created xFrame in which I put mFrame and xFrame will be all time in window so it will be no moved on top of other widgets
root = tk.Tk()
root.geometry('700x700')
# parent `root`
xFrame = tk.Frame(root, height = 500, width = 500, bg = "lightgrey")
xFrame.place(x= 10, y = 10)
# parent `xFrame`
mFrame = tk.Frame(xFrame, height = 500, width = 500, bg = "lightgrey")
mFrame.pack()
and then it show new frame behind checkbox and other buttons.
To put mFrame in xFrame I use pack() instead of place() because it doesn't neeed options and there will be no other widgets so there is no need to set x,y.
You said that you put mFrame in Canvas (but I don't see it in code) so you could use Canvas instead of xFrame.
BTW: There is suggestion to not use spaces around = inside functions.
See PEP 8 -- Style Guide for Python Code.
Here code with xFrame
I changed also makegrid100() to make it shorter and more readable.
import tkinter as tk
from tkinter import filedialog, Text
import os
import time, sys
from time import sleep
# --- functions ---
def changecolo(i, j):
if not ((i == 0 and j == 0) or (i == 12 and j == 12)):
if mFrame.grid_slaves(row=i, column=j)[0].cget('bg') == 'black':
mFrame.grid_slaves(row=i, column=j)[0].configure(bg='white')
elif mFrame.grid_slaves(row=i, column=j)[0].cget('bg') == 'white':
mFrame.grid_slaves(row=i, column=j)[0].configure(bg='grey')
elif mFrame.grid_slaves(row=i, column=j)[0].cget('bg') == 'grey':
mFrame.grid_slaves(row=i, column=j)[0].configure(bg='black')
def setalg():
value = 6
def makegrid6():
global mFrame # inform function to use external/global variable instead of locla one when it will assign value (`=`)
mFrame.destroy()
mFrame = tk.Frame(xFrame, height=500, width=500, bg="lightgrey")
mFrame.pack()
makegrid66()
def makegrid66():
for i in range(6):
for j in range (6):
if i == 0 and j == 0:
grids6=tk.Button(mFrame, bg='blue', text=(5 - i) + (5 - j), state='disabled', highlightcolor="black", highlightthickness=1, width=11, height=5)
grids6.grid(row=i, column=j)
elif i == 5 and j == 5:
grids6=tk.Button(mFrame, bg='red', text=(5 - i) + (5 - j) , state='disabled', highlightcolor="black", highlightthickness=1, width=11, height=5)
grids6.grid(row=i, column=j)
elif (((i == 0 or i == 1 or i == 2) and (j == 2)) or (i == 4 and j == 1)):
grids6=tk.Button(mFrame, bg='white', text=(5 - i) + (5 - j) , highlightcolor="black", highlightthickness=1, width=11, height=5, state='disabled')
grids6.grid(row=i, column=j)
elif (i == 3 and j == 2):
grids6=tk.Button(mFrame, bg='grey', text=(5 - i) + (5 - j) , highlightcolor="black", highlightthickness=1, width=11, height=5, state='disabled')
grids6.grid(row=i, column=j)
else:
grids6=tk.Button(mFrame, bg='black', text=(5 - i) + (5 - j), fg='white', highlightcolor="black", highlightthickness=1, width=11, height=5, state='disabled')
grids6.grid(row=i, column=j)
return mFrame.grid_slaves, i, j
def makegrid10():
global mFrame # inform function to use external/global variable instead of locla one when it will assign value (`=`)
mFrame.destroy()
mFrame = tk.Frame(xFrame, height=500, width=500, bg="lightgrey")
mFrame.pack()
makegrid100()
def makegrid100():
for i in range(13):
for j in range (13):
if i == 0 and j == 0:
bg_color = 'blue'
state = 'disabled'
elif i == 12 and j == 12:
bg_color = 'red'
state = 'disabled'
else:
bg_color = 'black'
state = 'normal'
b = tk.Button(mFrame, bg=bg_color, text=(12-i)+(12-j), state=state, fg='white', highlightcolor="black", highlightthickness=1, width=4, height=2, command=lambda x=i, y=j: changecolo(x, y))
b.grid(row=i, column=j)
return mFrame.grid_slaves, i, j
def play():
if diffVar.get() == "sim":
butons, l, k=makegrid66()
Greedy(butons, l, k)
else:
butons, l, k=makegrid100()
Greedy(butons, l, k)
def aStar():
print(1000010)
def Greedy(butons, k, l):
for i in range(k + 1):
for j in range(l + 1):
print(i, j)
mini=butons(row=i, column=j)[0].cget('text')
m, n=i, j
if i - 1 > -1:
if butons(row=i - 1, column=j)[0].cget('text') < mini:
mini=butons(row=i - 1, column=j)[0].cget('text')
m=i - 1
if i + 1 < 6:
if butons(row=i + 1, column=j)[0].cget('text') < mini:
mini=butons(row=i + 1, column=j)[0].cget('text')
m=i + 1
if j - 1 > -1:
if butons(row=i, column=j - 1)[0].cget('text') < mini:
mini=butons(row=i, column=j - 1)[0].cget('text')
n=j - 1
if j + 1 < 6:
if butons(row=i, column=j + 1)[0].cget('text') < mini:
mini=butons(row=i, column=j + 1)[0].cget('text')
n=j + 1
i, j=m, n
butons(row=m, column=n)[0].configure(bg='brown')
def UCS():
print(99)
# --- main ---
root = tk.Tk()
root.geometry('700x700')
xFrame = tk.Frame(root, height=500, width=500, bg="lightgrey")
xFrame.place(x= 10, y=10)
mFrame = tk.Frame(xFrame, height=500, width=500, bg="lightgrey")
mFrame.pack()
diffVar = tk.StringVar()
dif = tk.Label(root, text="Problem Difficulty", bg="Lightgrey")
dif.place (x=550, y=30)
simp = tk.Radiobutton(root, text="Simple", value="sim", bg="Lightgrey", variable=diffVar, command=makegrid6)
simp.place(x=550, y=60)
comp = tk.Radiobutton(root, text="Complex", value="com", bg="Lightgrey", variable=diffVar, command=makegrid10)
comp.place(x=550, y=90)
algVar = tk.IntVar()
algVar.set(1)
dif = tk.Label(root, text="Choose an Algorithm", bg="Lightgrey")
dif.place (x=550, y=180)
alg1 = tk.Radiobutton(root, text="A*", value=1, bg="Lightgrey", variable=algVar, command=setalg)
alg1.place(x=550, y=210)
alg2 = tk.Radiobutton(root, text="Greedy", value=2, bg="Lightgrey", variable=algVar, command=setalg)
alg2.place(x=550, y=240)
alg3 = tk.Radiobutton(root, text="UCS", value=3, bg="Lightgrey", variable=algVar, command=setalg)
alg3.place(x=550, y=270)
f2 = tk.Canvas(root, height=30, width=30, bg="White")
playbu = tk.Button(root, text="Play", bg="White", width=15, command=play)
playbu.place(x=10, y=550)
nextbu = tk.Button(root, text="Next", bg="White", width=15)
nextbu.place(x=140, y=550)
fasterbu = tk.Button(root, text="Faster", bg="White", width=15)
fasterbu.place(x=270, y=550)
resetbu = tk.Button(root, text="Reset", bg="White", width=15)
resetbu.place(x=400, y=550)
root.mainloop()

Related

TypeError: knapSack() missing 3 required positional arguments

I just start learning tkinter python for knapsack program. When I try to calculate, it doesn't do anything. And I am getting this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/init.py", line 1921, in call
return self.func(*args)
TypeError: knapSack() missing 3 required positional arguments: 'W', 'wt', and 'val'
My code looks like this
import tkinter as tk
window = tk.Tk()
window.title("0/1 Knapsack")
canvas = tk.Canvas(window, height=1000, width=1000, bg = "#ADD8E6")
canvas.pack()
frame = tk.Frame(window, bg="white")
frame.place(relwidth=0.8, relheight=0.8,relx=0.1,rely=0.1)
def on_submit():
num_entries = int(num_entries_entry.get())
for i in range(num_entries):
Title_label = tk.Label(frame, text = "Items information")
Title_label.grid(row=5, column=1)
Title_label.config(font=("Arial", 18))
entry = tk.Entry(frame)
entry_label = tk.Label(frame, text = " Weight of items : " )
entry_label.grid(row=6,column=0)
entry.grid(row=7+i, column=0)
entry2 = tk.Entry(frame)
entry2_label = tk.Label(frame, text = " Value of each items")
entry2_label.grid(row=6, column=1)
entry2.grid(row=7+i, column=1)
capacity_label = tk.Label(frame, text =" Please select the capacity of your bag :")
capacity_spinbox = tk.Spinbox(frame, from_=1, to=100 )
capacity_label.grid(row=6, column=2)
capacity_spinbox.grid(row=7,column=2)
calculate_button =tk.Button(frame,text="Calculate", command = knapSack)
calculate_button.grid(row=7,column=3)
def calculate(weights, values, capacity):
result = knapSack(capacity, weights, values)
# Create a label to display the result
result_label = tk.Label(frame, text="Result: " + str(result))
result_label.grid(row=14, column=0)
def print_value_table(table):
print("Value Table:")
for row in table:
print(row)
def print_keep_table(table):
print("Keep Table:")
for row in table:
print(row)
def knapSack(W, wt, val):
n=len(val)
value_table = [[0 for x in range(W + 1)] for x in range(n + 1)]
keep_table = [[0 for x in range (W+1)] for x in range (n+1)]
for i in range(n + 1):
for j in range(W + 1):
if i == 0 or j == 0:
value_table[i][j] = 0
keep_table[i][j] = 0
elif wt[i-1] <= j:
if(val[i-1] + value_table[i-1][j-wt[i-1]]) > value_table[i-1][j]:
value_table[i][j] = val [i-1]+ value_table[i-1][j-wt[i-1]]
keep_table [i][j] = 1
else:
value_table[i][j] = value_table[i-1][j]
keep_table[i][j] = 0
else:
value_table[i][j] = value_table[i-1][j]
keep_table[i][j] = 0
print_value_table(value_table)
print_keep_table(keep_table)
return value_table[n][W]
num_entries_label = tk.Label(frame, text="Enter the number of items:")
num_entries_label.grid(row=1, column=1)
num_entries_entry = tk.Entry(frame)
num_entries_entry.grid(row=2, column=1)
next_button = tk.Button(frame, text="Next", command=on_submit)
next_button.grid(row=3, column=1)
title_label = tk.Label(frame, text = "Hi! Please follow the instructions!")
title_label.config(font=("Arial", 18))
window.mainloop()

Stuck in while loop in GUI

I'm building a GUI that first accepts an input number from user and makes the corresponding button green. Now I run another python script that scans an apriltag(sort of QR Code) and returns an ID and writes it into a file placed in same folder. The code I've attached includes print statement at various point("Done", "phew","haha"). On running the GUI the command Done is printed first, followed by phew and haha(multiple times). However the button does not change its colour to green, it only changes its colour when the apriltag is detected by the camera. The code is attached. The function is called when I press the OK button in my GUI.
I have tried to include delays and also tried to use threading. But none of these methods worked.
import Tkinter
def action3():
f = open("test.txt","r")
data = f.read()
y = int(str(data))
f.close()
f = open("test.txt","w")
f.write("0")
f.close()
x = int(e.get())
f = open("test.txt","r")
data = f.read()
y = int(str(data))
f.close()
print("Done")
if (x == 1):
b1['bg'] = 'green'
b2['bg'] = 'white'
b3['bg'] = 'white'
b4['bg'] = 'white'
print("phew")
#time.sleep(2)
elif (x == 2):
b1['bg'] = 'white'
b2['bg'] = 'green'
b3['bg'] = 'white'
b4['bg'] = 'white'
print("phew")
elif (x == 3):
b1['bg'] = 'white'
b2['bg'] = 'white'
b3['bg'] = 'green'
b4['bg'] = 'white'
print("phew")
elif (x == 4):
b1['bg'] = 'white'
b2['bg'] = 'white'
b3['bg'] = 'white'
b4['bg'] = 'green'
print("phew")
#time.sleep(5)
while(y==0): ##Update y
f = open("test.txt","r")
data = f.read()
y=int(str(data))
print("Haha")
f.close()
time.sleep(2)
##Code for GUI
b1 = Button(window, text="Box1", bg='white', width=30, height=13)
b1.grid(row=1, sticky=W)
b2 = Button(window, text="Box2", bg = 'white', width = 30,height = 13)
b2.grid(row=2, sticky=W)
b3 = Button(window, text="Box3", bg = 'white', width = 30,height = 13)
b3.grid(row=1, column=1, sticky=W)
b4 = Button(window, text="Box4", bg = 'white', width = 30,height = 13)
b4.grid(row=2, column=1, sticky=W)
bget = Button(window, text="OK", bg='pink', width = 10,height =
2,command=action3)
bget.grid(row=3, column=0, sticky=E)
e = Entry(window)
e.grid(row=3, column=1)
window.mainloop()

How to make text widget static

After changing the font size of the widget text increases , how to make it static?
I'm giving you all the code so you can run the program. So do not swear
from tkinter import*
import tkinter as tk
from tkinter import Toplevel, Listbox, StringVar, BooleanVar, TclError
from tkinter import filedialog, scrolledtext,Menu,END,messagebox
from tkinter.ttk import Checkbutton, Frame, Label, Button, Scrollbar, Style, Entry
from tkinter.font import families, Font
from locale import getdefaultlocale
import PIL
from PIL import Image, ImageTk
__version__ = "2.0.2"
# --- translation
EN = {"Cancel": "Cancel", "Bold": "Bold", "Italic": "Italic",
"Underline": "Underline", "Overstrike": "Strikethrough"}
FR = {"Cancel": "Annuler", "Bold": "Gras", "Italic": "Italique",
"Underline": "Souligné", "Overstrike": "Barré"}
LANGUAGES = {"fr": FR, "en": EN}
if getdefaultlocale()[0][:2] == "fr":
TR = LANGUAGES["fr"]
else:
TR = LANGUAGES["en"]
class FontChooser(Toplevel):
""".Font chooser dialog."""
def __init__(self, master, font_dict={}, text="Abcd", title="Font Chooser",
**kwargs):
"""
Create a new FontChooser instance.
Arguments:
master: master window
font_dict: dictionnary, like the one returned by the .actual
method of a Font object:
{'family': 'DejaVu Sans',
'overstrike': False,
'size': 12,
'slant': 'italic' or 'roman',
'underline': False,
'weight': 'bold' or 'normal'}
text: text to be displayed in the preview label
title: window title
**kwargs: additional keyword arguments to be passed to
Toplevel.__init__
"""
Toplevel.__init__(self, master, **kwargs)
self.title(title)
self.resizable(False, False)
self.protocol("WM_DELETE_WINDOW", self.quit)
self._validate_family = self.register(self.validate_font_family)
self._validate_size = self.register(self.validate_font_size)
# --- variable storing the chosen font
self.res = ""
style = Style(self)
style.configure("prev.TLabel", background="white")
bg = style.lookup("TLabel", "background")
self.configure(bg=bg)
# --- family list
self.fonts = list(set(families()))
self.fonts.append("TkDefaultFont")
self.fonts.sort()
for i in range(len(self.fonts)):
self.fonts[i] = self.fonts[i].replace(" ", "\ ")
max_length = int(2.5 * max([len(font) for font in self.fonts])) // 3
self.sizes = ["%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2)))]
# --- font default
font_dict["weight"] = font_dict.get("weight", "normal")
font_dict["slant"] = font_dict.get("slant", "roman")
font_dict["underline"] = font_dict.get("underline", False)
font_dict["overstrike"] = font_dict.get("overstrike", False)
font_dict["family"] = font_dict.get("family",
self.fonts[0].replace('\ ', ' '))
font_dict["size"] = font_dict.get("size", 10)
# --- creation of the widgets
# ------ style parameters (bold, italic ...)
options_frame = Frame(self, relief='groove', borderwidth=2)
self.font_family = StringVar(self, " ".join(self.fonts))
self.font_size = StringVar(self, " ".join(self.sizes))
self.var_bold = BooleanVar(self, font_dict["weight"] == "bold")
b_bold = Checkbutton(options_frame, text=TR["Bold"],
command=self.toggle_bold,
variable=self.var_bold)
b_bold.grid(row=0, sticky="w", padx=4, pady=(4, 2))
self.var_italic = BooleanVar(self, font_dict["slant"] == "italic")
b_italic = Checkbutton(options_frame, text=TR["Italic"],
command=self.toggle_italic,
variable=self.var_italic)
b_italic.grid(row=1, sticky="w", padx=4, pady=2)
self.var_underline = BooleanVar(self, font_dict["underline"])
b_underline = Checkbutton(options_frame, text=TR["Underline"],
command=self.toggle_underline,
variable=self.var_underline)
b_underline.grid(row=2, sticky="w", padx=4, pady=2)
self.var_overstrike = BooleanVar(self, font_dict["overstrike"])
b_overstrike = Checkbutton(options_frame, text=TR["Overstrike"],
variable=self.var_overstrike,
command=self.toggle_overstrike)
b_overstrike.grid(row=3, sticky="w", padx=4, pady=(2, 4))
# ------ Size and family
self.var_size = StringVar(self)
self.entry_family = Entry(self, width=max_length, validate="key",
validatecommand=(self._validate_family, "%d", "%S",
"%i", "%s", "%V"))
self.entry_size = Entry(self, width=4, validate="key",
textvariable=self.var_size,
validatecommand=(self._validate_size, "%d", "%P", "%V"))
self.list_family = Listbox(self, selectmode="browse",
listvariable=self.font_family, highlightthickness=0, exportselection=False, width=max_length)
self.list_size = Listbox(self, selectmode="browse",
listvariable=self.font_size, highlightthickness=0, exportselection=False, width=4)
scroll_family = Scrollbar(self, orient='vertical', command=self.list_family.yview)
scroll_size = Scrollbar(self, orient='vertical', command=self.list_size.yview)
self.preview_font = Font(self, **font_dict)
if len(text) > 30:
text = text[:30]
self.preview = Label(self, relief="groove", style="prev.TLabel", text=text, font=self.preview_font, anchor="center")
self.list_family.configure(yscrollcommand=scroll_family.set)
self.list_size.configure(yscrollcommand=scroll_size.set)
self.entry_family.insert(0, font_dict["family"])
self.entry_family.selection_clear()
self.entry_family.icursor("end")
self.entry_size.insert(0, font_dict["size"])
try:
i = self.fonts.index(self.entry_family.get().replace(" ", "\ "))
except ValueError:
i = 0
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
self.list_family.see(i)
try:
i = self.sizes.index(self.entry_size.get())
self.list_size.selection_clear(0, "end")
self.list_size.selection_set(i)
self.list_size.see(i)
except ValueError:
pass
self.entry_family.grid(row=0, column=0, sticky="ew", pady=(10, 1), padx=(10, 0))
self.entry_size.grid(row=0, column=2, sticky="ew", pady=(10, 1), padx=(10, 0))
self.list_family.grid(row=1, column=0, sticky="nsew", pady=(1, 10), padx=(10, 0))
self.list_size.grid(row=1, column=2, sticky="nsew", pady=(1, 10), padx=(10, 0))
scroll_family.grid(row=1, column=1, sticky='ns', pady=(1, 10))
scroll_size.grid(row=1, column=3, sticky='ns', pady=(1, 10))
options_frame.grid(row=0, column=4, rowspan=2, padx=10, pady=10, ipadx=10)
self.preview.grid(row=2, column=0, columnspan=5, sticky="eswn", padx=10, pady=(0, 10), ipadx=4, ipady=4)
button_frame = Frame(self)
button_frame.grid(row=3, column=0, columnspan=5, pady=(0, 10), padx=10)
Button(button_frame, text="Ok", command=self.ok).grid(row=0, column=0, padx=4, sticky='ew')
Button(button_frame, text=TR["Cancel"], command=self.quit).grid(row=0, column=1, padx=4, sticky='ew')
self.list_family.bind('<<ListboxSelect>>', self.update_entry_family)
self.list_size.bind('<<ListboxSelect>>', self.update_entry_size, add=True)
self.list_family.bind("<KeyPress>", self.keypress)
self.entry_family.bind("<Return>", self.change_font_family)
self.entry_family.bind("<Tab>", self.tab)
self.entry_size.bind("<Return>", self.change_font_size)
self.entry_family.bind("<Down>", self.down_family)
self.entry_size.bind("<Down>", self.down_size)
self.entry_family.bind("<Up>", self.up_family)
self.entry_size.bind("<Up>", self.up_size)
self.bind_class("TEntry", "<Control-a>", self.select_all)
self.wait_visibility(self)
self.grab_set()
self.entry_family.focus_set()
self.lift()
def select_all(self, event):
event.widget.selection_range(0, "end")
def keypress(self, event):
key = event.char.lower()
l = [i for i in self.fonts if i[0].lower() == key]
if l:
i = self.fonts.index(l[0])
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
self.list_family.see(i)
self.update_entry_family()
def up_family(self, event):
try:
i = self.list_family.curselection()[0]
self.list_family.selection_clear(0, "end")
if i <= 0:
i = len(self.fonts)
self.list_family.see(i - 1)
self.list_family.select_set(i - 1)
except TclError:
self.list_family.selection_clear(0, "end")
i = len(self.fonts)
self.list_family.see(i - 1)
self.list_family.select_set(i - 1)
self.list_family.event_generate('<<ListboxSelect>>')
def up_size(self, event):
"""Navigate in the size listbox with up key."""
try:
s = self.var_size.get()
if s in self.sizes:
i = self.sizes.index(s)
elif s:
sizes = list(self.sizes)
sizes.append(s)
sizes.sort(key=lambda x: int(x))
i = sizes.index(s)
else:
i = 0
self.list_size.selection_clear(0, "end")
if i <= 0:
i = len(self.sizes)
self.list_size.see(i - 1)
self.list_size.select_set(i - 1)
except TclError:
i = len(self.sizes)
self.list_size.see(i - 1)
self.list_size.select_set(i - 1)
self.list_size.event_generate('<<ListboxSelect>>')
def down_family(self, event):
"""Navigate in the family listbox with down key."""
try:
i = self.list_family.curselection()[0]
self.list_family.selection_clear(0, "end")
if i >= len(self.fonts):
i = -1
self.list_family.see(i + 1)
self.list_family.select_set(i + 1)
except TclError:
self.list_family.selection_clear(0, "end")
self.list_family.see(0)
self.list_family.select_set(0)
self.list_family.event_generate('<<ListboxSelect>>')
def down_size(self, event):
"""Navigate in the size listbox with down key."""
try:
s = self.var_size.get()
if s in self.sizes:
i = self.sizes.index(s)
elif s:
sizes = list(self.sizes)
sizes.append(s)
sizes.sort(key=lambda x: int(x))
i = sizes.index(s) - 1
else:
s = len(self.sizes) - 1
self.list_size.selection_clear(0, "end")
if i < len(self.sizes) - 1:
self.list_size.selection_set(i + 1)
self.list_size.see(i + 1)
else:
self.list_size.see(0)
self.list_size.select_set(0)
except TclError:
self.list_size.selection_set(0)
self.list_size.event_generate('<<ListboxSelect>>')
def toggle_bold(self):
"""Update font preview weight."""
b = self.var_bold.get()
self.preview_font.configure(weight=["normal", "bold"][b])
def toggle_italic(self):
"""Update font preview slant."""
b = self.var_italic.get()
self.preview_font.configure(slant=["roman", "italic"][b])
def toggle_underline(self):
"""Update font preview underline."""
b = self.var_underline.get()
self.preview_font.configure(underline=b)
def toggle_overstrike(self):
"""Update font preview overstrike."""
b = self.var_overstrike.get()
self.preview_font.configure(overstrike=b)
def change_font_family(self, event=None):
"""Update font preview family."""
family = self.entry_family.get()
if family.replace(" ", "\ ") in self.fonts:
self.preview_font.configure(family=family)
def change_font_size(self, event=None):
"""Update font preview size."""
size = int(self.var_size.get())
self.preview_font.configure(size=size)
def validate_font_size(self, d, ch, V):
"""Validation of the size entry content."""
l = [i for i in self.sizes if i[:len(ch)] == ch]
i = None
if l:
i = self.sizes.index(l[0])
elif ch.isdigit():
sizes = list(self.sizes)
sizes.append(ch)
sizes.sort(key=lambda x: int(x))
i = min(sizes.index(ch), len(self.sizes))
if i is not None:
self.list_size.selection_clear(0, "end")
self.list_size.selection_set(i)
deb = self.list_size.nearest(0)
fin = self.list_size.nearest(self.list_size.winfo_height())
if V != "forced":
if i < deb or i > fin:
self.list_size.see(i)
return True
if d == '1':
return ch.isdigit()
else:
return True
def tab(self, event):
"""Move at the end of selected text on tab press."""
self.entry_family = event.widget
self.entry_family.selection_clear()
self.entry_family.icursor("end")
return "break"
def validate_font_family(self, action, modif, pos, prev_txt, V):
"""Completion of the text in the entry with existing font names."""
if self.entry_family.selection_present():
sel = self.entry_family.selection_get()
txt = prev_txt.replace(sel, '')
else:
txt = prev_txt
if action == "0":
txt = txt[:int(pos)] + txt[int(pos) + 1:]
return True
else:
txt = txt[:int(pos)] + modif + txt[int(pos):]
ch = txt.replace(" ", "\ ")
l = [i for i in self.fonts if i[:len(ch)] == ch]
if l:
i = self.fonts.index(l[0])
self.list_family.selection_clear(0, "end")
self.list_family.selection_set(i)
deb = self.list_family.nearest(0)
fin = self.list_family.nearest(self.list_family.winfo_height())
index = self.entry_family.index("insert")
self.entry_family.delete(0, "end")
self.entry_family.insert(0, l[0].replace("\ ", " "))
self.entry_family.selection_range(index + 1, "end")
self.entry_family.icursor(index + 1)
if V != "forced":
if i < deb or i > fin:
self.list_family.see(i)
return True
else:
return False
def update_entry_family(self, event=None):
"""Update family entry when an item is selected in the family listbox."""
# family = self.list_family.get("#%i,%i" % (event.x , event.y))
family = self.list_family.get(self.list_family.curselection()[0])
self.entry_family.delete(0, "end")
self.entry_family.insert(0, family)
self.entry_family.selection_clear()
self.entry_family.icursor("end")
self.change_font_family()
def update_entry_size(self, event):
"""Update size entry when an item is selected in the size listbox."""
# size = self.list_size.get("#%i,%i" % (event.x , event.y))
size = self.list_size.get(self.list_size.curselection()[0])
self.var_size.set(size)
self.change_font_size()
def ok(self):
"""Validate choice."""
self.res = self.preview_font.actual()
self.quit()
def get_res(self):
"""Return chosen font."""
return self.res
def quit(self):
self.destroy()
def askfont(master=None, text="Abcd", title="Font Chooser", **font_args):
chooser = FontChooser(master, font_args, text, title)
chooser.wait_window(chooser)
return chooser.get_res()
def edit_font():
font = askfont(root, title="Choose a font")
if font:
font['family'] = font['family'].replace(' ', '\ ')
font_str = "%(family)s %(size)i %(weight)s %(slant)s" % font
if font['underline']:
font_str += ' underline'
if font['overstrike']:
font_str += ' overstrike'
text.configure(font=font_str)
root=tk.Tk()
root.geometry("1423x800")
# added weights so the widget resizes correctly with window
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
image = ImageTk.PhotoImage(file="0.png")
lab=tk.Label(root, image = image)
lab.grid(row=0, column=0)
text=tk.Text(root,width = 60,height=15, font=Font(family="Helvetica", size=10))
text.grid(row=0, column=0)
king=tk.Menu(root)
root.config(menu=king)
view=tk.Menu(king, tearoff=0)
view2=tk.Menu(view, tearoff=0)
view2.add_command(label='Font',command=edit_font)
view.add_cascade(label='Text', menu=view2)
king.add_cascade(label='View', menu=view)
root.mainloop()
This is the code you will most likely need to fix my problem:
def askfont(master=None, text="Abcd", title="Font Chooser", **font_args):
chooser = FontChooser(master, font_args, text, title)
chooser.wait_window(chooser)
return chooser.get_res()
def edit_font():
font = askfont(root, title="Choose a font")
if font:
font['family'] = font['family'].replace(' ', '\ ')
font_str = "%(family)s %(size)i %(weight)s %(slant)s" % font
if font['underline']:
font_str += ' underline'
if font['overstrike']:
font_str += ' overstrike'
text.configure(font=font_str)
root=tk.Tk()
root.geometry("1423x800")
# added weights so the widget resizes correctly with window
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
image = ImageTk.PhotoImage(file="0.png")
lab=tk.Label(root, image = image)
lab.grid(row=0, column=0)
text=tk.Text(root,width = 60,height=15, font=Font(family="Helvetica", size=10))
text.grid(row=0, column=0)
king=tk.Menu(root)
root.config(menu=king)
view=tk.Menu(king, tearoff=0)
view2=tk.Menu(view, tearoff=0)
view2.add_command(label='Font',command=edit_font)
view.add_cascade(label='Text', menu=view2)
king.add_cascade(label='View', menu=view)
root.mainloop()
This will probably include setting the frame size and frame, as well as banning distribution, one of my friends said. Hope this helps you
If you give the Text widget a fixed height and width and wrap it in a Frame with the same width and height and use grid_propagate(False), when the text is made bigger the Text widget stays the same size.
import tkinter as tk
def fontUp():
text.config(font = ("30"))
root = tk.Tk()
root.geometry("800x800")
frm = tk.Frame(root, height = 500, width = 500)
frm.grid(row = 0, column = 0)
frm.grid_propagate(False)
text = tk.Text(frm, height = 500, width = 500)
text.grid(row = 0, column = 0)
btn = tk.Button(root, text="Font bigger", command = fontUp)
btn.grid(row = 2, column = 0)

tkinter: pull down menu un-clickable

I am creating a tkinter window that updates a matrix multiplication result every second. I wish to use pull down menus to create options for users.
However, since the entire window is re-drawn every second for the matrix update, the pull down menus are re-initialized every second, rendering them pretty much useless.
I am wondering if there is any way around this problem.
Thanks in advance.
from tkinter import *
import time
import sys
def update(a):
root.title("Matrix Multiplication")
menu = Menu(root)
root.config(menu= menu)
subMenu = Menu(menu)
menu.add_cascade(label="Options", menu=subMenu)
subMenu.add_command(label="Opt1...",command=win2)
exitMenu = Menu(menu)
menu.add_cascade(label="Exit", menu=exitMenu)
exitMenu.add_command(label="Exit",command=root.destroy)
X0 = [[8,7,3],[4 ,5,6],[7 ,8,9]]
Y0 = [[5,8,1,2],[6,7,3,0],[4,5,9,1]]
result0 = [[0,0,0,0],[0,0,0,0],[0,0,0,0]]
if a == 0:
cpfg = ["magenta", "blue", "green", "purple"]
cpbg = ["white", "white", "white", "white"]
button1 = Button(root, text="Button-1", fg=cpfg[0], bg=cpbg[0])
button2 = Button(root, text="Button-2", fg=cpfg[1], bg=cpbg[1])
button3 = Button(root, text="Button-3", fg=cpfg[2], bg=cpbg[2])
button4 = Button(root, text="Button-4", fg=cpfg[3], bg=cpbg[3])
button1.grid(row=0, column=0)
button2.grid(row=0, column=1)
button3.grid(row=0, column=2)
button4.grid(row=0, column=3)
a = 1
elif a >= 1 and a <= 3:
for b in range(len(X0)):
for c in range(len(X0[0])):
X0[b][c] *= a
a += 1
else:
for b in range(len(X0)):
for c in range(len(X0[0])):
X0[b][c] *= a
a = 1
for i in range(len(X0)):
for j in range(len(Y0[0])):
for k in range(len(Y0)):
result0[i][j] += X0[i][k] * Y0[k][j]
agrp = LabelFrame(root, text="Process-0", padx=5, pady=5)
agrp.grid(row=2, column=1)
for r in range(3):
for c in range(4):
Label(agrp, text=result0[r][c],
borderwidth=4 ).grid(row=r,column=c)
root.after(1000, lambda x = a: update(x))
def win2():
board = Toplevel()
board.title("Message")
S = Scrollbar(board)
T = Text(board, height=4, width=50)
T.pack()
S.pack(side=RIGHT, fill=Y)
T.pack(side=LEFT, fill=Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
quote = """Yep, this is text"""
T.insert(END, quote)
root = Tk()
a=0
update(a)
root.mainloop()
The update method should only calculate and display changes.
def update(a):
if a == 0:
a = 1
elif a >= 1 and a <= 3:
for b in range(len(X0)):
for c in range(len(X0[0])):
X0[b][c] *= a
a += 1
else:
for b in range(len(X0)):
for c in range(len(X0[0])):
X0[b][c] *= a
a = 1
for i in range(len(X0)):
for j in range(len(Y0[0])):
for k in range(len(Y0)):
result0[i][j] += X0[i][k] * Y0[k][j]
for r in range(3):
for c in range(4):
Label(agrp, text=result0[r][c],
borderwidth=4 ).grid(row=r,column=c)
root.after(1000, lambda x = a: update(x))

Cosinus drawing

I'd like to make a program which draws a cosinus graph in orderd range. But there is an error which I'm not able to repair. Error Message: "z = int(self.entry.get())
AttributeError: program instance has no attribute 'entry" Here is my code:
# -*- coding: utf-8 -*-
from Tkinter import Tk, W, E
from ttk import Label, Button, Frame, Entry,Style
import math
import sys
import matplotlib as mp
class program(Frame):
def __init__(self,main):
Frame.__init__(self,main)
self.main = main
self.initUI()
def initUI(self):
self.main.title('COSINUSEK')
Style().configure('TFrame', background = 'black')
Style().configure('TLabel', background = 'black', foreground = 'blue')
Style().configure("TButton", background = 'red', foreground = 'blue')
self.rowconfigure(0, pad = 3)
self.rowconfigure(1, pad = 3)
self.rowconfigure(2, pad = 3)
self.rowconfigure(3, pad = 3)
self.rowconfigure(4, pad = 3)
self.columnconfigure(0,pad =3)
self.columnconfigure(1,pad =3)
self.columnconfigure(2,pad =3)
self.columnconfigure(3,pad =3)
self.columnconfigure(4,pad =3)
label = Label(self, text = 'Podaj zakres w stopniach').grid(row = 0,column = 3)
od = Label(self, text = ' OD').grid(row = 1, column =0)
do = Label(self, text = ' DO').grid(row = 1, column =4 )
entry = Entry(self, justify = 'center').grid(row = 2,column = 0,columnspan = 2 ,sticky = E+ W)
entry1 = Entry(self, justify = 'center').grid(row = 2,column = 4,columnspan = 2, sticky = E)
button = Button(self, text = 'Ok',command = self.ok).grid(row = 3,column = 3)
button1 = Button(self, text = 'Draw', command = self.dra).grid(row = 4, column = 3)
self.pack()
def run(self):
self.main.mainloop()
def ok(self):
x = []
y = []
z = int(self.entry.get())
w = int(self.entry1.get())
i = w
while i in range(w,z):
x.append(i)
for a in x:
y[a] = math.cos((x[a]*math.pi)/180)
i = i + 0.01
def dra(self):
self.mp.ion()
self.mp.plot(self.x,self.y)
self.mp.title('Wykres')
self.mp.xlabel('x')
self.mp.ylabel('y')
self.mp.draw()
program(Tk()).run()
Replace:
entry = Entry(self, justify = 'center').grid(row = 2,column = 0,columnspan = 2 ,sticky = E+ W)
entry1 = Entry(self, justify = 'center').grid(row = 2,column = 4,columnspan = 2, sticky = E)
to
self.entry = Entry(self, justify = 'center')
self.entry.grid(row = 2,column = 0,columnspan = 2 ,sticky = E+ W)
self.entry1 = Entry(self, justify = 'center')
self.entry1.grid(row = 2,column = 4,columnspan = 2, sticky = E)
Otherwise, at line z = int(self.entry.get()), self.entry would not exist. Also, the grid method doesn't return anything so, if you do everything in one line as you did, you lose your Entry object and affect None to entry.
When making the variables, you'll have to set them as instance variables:
self.entry = Entry(self, justify = 'center').grid(row = 2,column = 0,columnspan = 2 ,sticky = E+ W)
self.entry1 = Entry(self, justify = 'center').grid(row = 2,column = 4,columnspan = 2, sticky = E)

Categories

Resources