I get error like this in the title when I run this code. I want to make TODO list but I'm getting many errors on my way :(. I can't call array (tab) in other function and I can't change column in checkbox grid.
from tkinter import *
from tkinter import messagebox as msb
win = Tk()
win.title("Checkbutton")
win.geometry("300x600")
win.resizable("False","False")
task_name = StringVar()
tab = []
tab.append("")
tab.append("")
r = 2
c = 1
cc = IntVar
def checking():
tab[r].grid(row=r, column=1, padx=(10, 10), pady=(5, 5))
def addcheck():
global r
global c
global cc
if r < 16:
tab.append(Checkbutton(variable = cc, text = task_name.get(), command = checking))
tab[r].grid(row=r, column=0, padx=(10, 10), pady=(5, 5))
r = r + 1
task_entry.delete(0, 20)
else:
msb.showwarning(title="DANGER", message="TOO MUCH TASKS, TAKE A REST")
text1 = Label(win, text = "TO DO:").grid(row = 1, column = 0, padx = (10, 10), pady = (30, 10))
text2 = Label(win, text = "DONE: ").grid(row = 1, column = 1, padx = (10, 10), pady = (30, 10))
task_entry = Entry(width = "20", textvariable = task_name)
task_entry.grid(row = 0, column = 0, padx = (30, 10))
add = Button(win, text = "add task", command = addcheck).grid(row = 0, column = 1, padx = (10, 10))
mainloop()
Full error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\matib\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "D:\pythonprojekty\pythonProject\main.py", line 18, in checking
tab[r].grid(row=r, column=1, padx=(10, 10), pady=(5, 5))
IndexError: list index out of range
You're getting the IndexError because of trying to use the global variable r in the checking() function — and the way to fix it is by explicitly passing the row value as an argument when calling it. In the code below this is being done by using a lambda expression to define the callback command= function.
There were a number of other mistakes in your code, and I have attempted to correct them all and reformat the code to follow the PEP 8 - Style Guide for Python Code recommendations for readability.
import tkinter as tk
from tkinter import messagebox as msb
from tkinter.constants import *
win = tk.Tk()
win.title("Checkbutton")
win.geometry("300x600")
win.resizable(FALSE, FALSE)
task_name = tk.StringVar()
tab = [None, None]
r = len(tab)
def checking(row):
tab[row].grid(row=row, column=1, padx=(10, 10), pady=(5, 5))
def addcheck():
global r
if r > 16:
msb.showwarning(title="DANGER", message="TOO MANY TASKS, TAKE A REST")
else:
cb_var = tk.IntVar()
tab.append(tk.Checkbutton(variable=cb_var, text=task_name.get(),
command=lambda row=r: checking(row)))
tab[r].grid(row=r, column=0, padx=(10, 10), pady=(5, 5))
r += 1
task_entry.delete(0, END)
tk.Label(win, text="TO DO:").grid(row=1, column=0, padx=(10, 10), pady=(30, 10))
tk.Label(win, text="DONE: ").grid(row=1, column=1, padx=(10, 10), pady=(30, 10))
task_entry = tk.Entry(width="20", textvariable=task_name)
task_entry.grid(row=0, column=0, padx=(30, 10))
tk.Button(win, text="add task", command=addcheck).grid(row=0, column=1, padx=(10, 10))
task_entry.focus_set()
win.mainloop()
Here's a screenshot of it running on my system:
Related
So...
I have this python tkinter code which is a pizza program.
What I must add to this program is multi choice (multiple pizzas). Managed to do that as you will see in the code down below. The problem is that the prices won't add up when multiple pizzas selected - the price displayed is of the most expensive pizza selected.
Also, I must add text box which will be email input.
from tkinter import *
class App(Frame):
def __init__(self, win):
self.win = win
self.win.title('Pizzerija')
super().__init__(self.win)
self.grid()
self.Sucelje()
return
def Sucelje(self):
f = ('Verdana', 12, 'bold')
self.Pizze = {'Vesuvio' : 42, 'Funhgi' : 42, 'Capriciosa' : 42,
'Margerita' : 40, 'Picante' : 44, 'Plodovi mora' : 44, 'Slavonska' : 46}
self.Vrste = Listbox(self, selectforeground='red', selectmode=MULTIPLE,
font=f, fg='blue')
self.Vrste.bind('<<ListboxSelect>>', self.Klik)
self.Vrste.grid(row=1, column=1, rowspan=7)
for t in self.Pizze.keys():
self.Vrste.insert(END, t)
self.Velicine = [('Mala', 0.75), ('Srednja', 1), ('Velika', 1.5)]
self.tV = IntVar()
self.tV.set(1)
self.V = []
for t in enumerate(self.Velicine):
self.V.append(Radiobutton(self, text=t[1][0], font=f, fg='green',
variable=self.tV, value=t[0],
command=self.Klik))
self.V[t[0]].grid(row=2 * t[0] + 1, column=2, rowspan=2, sticky=W)
self.Dodaci = [('Jaje', 4), ('Gorgonzola', 16), ('Masline', 8), ('Kulen', 16),
('Feferoni', 10), ('Vrhnje', 8), ('Mozzarella', 10),]
self.tD = []
self.D = []
for t in enumerate(self.Dodaci):
self.tD.append(BooleanVar())
self.D.append(Checkbutton(self, text=t[1][0], fg='blue', font=f,
variable=self.tD[t[0]] , command=self. Klik))
self.D[t[0]].grid(row=t[0] + 1, column=3, sticky=W)
self.tC = StringVar()
self.tC.set('0.00 kn')
self.C = Label(self, textvariable=self.tC,
font=('Calibri', 20, 'bold italic'), fg='red')
self.C.grid(row=8, column=1, columnspan=3)
def Klik(self, e=None):
c = 0
t = self.Vrste.curselection()
if len(t) > 0:
p = self.Vrste.get(t[0])
c = self.Pizze[p]
odabrana_velicina = self.tV.get()
c *= self.Velicine[odabrana_velicina][1]
for i in range(len(self.Dodaci)):
if self.tD[i].get():
c += self.Dodaci[i][1]
self.tC.set(f'{c:.2f} kn')
def main():
p = App(Tk())
p.mainloop()
main()
I managed to make multi selection. From now on I don't know how to add up prices of multiple selection and how to add text input box.
I am relatively new to tkinter, and very new to coding with classes. My GUI will have a step that asks user to enter in an integer with any number of digits to an Entry(). After the last digit keypress (no keypress in 2000 ms) another function will activate that uses the integer entered. It seems very simple but I cannot seem to get this right. I haven't figured out the .after() part, for now I am just using a binding on the ENTER key. Details on the problems, then the code below. I feel like I am struggling way too much on something that can't be that difficult. Please help.
(Some?) Details:
I am getting a bunch of errors leading up to entry input, regarding 'val' not being defined, despite it being defined.
Pressing ENTER does not result in any return value (I added a print command to the mouse clicks just to see if 'val' was being assigned)
Losing sleep from trying to apply after() function
Code (I tried to strip down to essentials best I could, my problem is near the bottom):
'''
import tkinter as tk
import tkinter.messagebox
kk = 1
class App(tk.Tk):
WIDTH = 1000
HEIGHT = 520
def __init__(self):
super().__init__()
self.geometry(f"{App.WIDTH}x{App.HEIGHT}")
self.protocol("WM_DELETE_WINDOW", self.on_closing) # call .on_closing() when app gets closed
self.fr0 = tk.Frame(master=self, background = 'grey')
self.fr0.pack(fill = 'both', expand = True, padx = 20, pady = 20)
# configure grid layout (2x1)
self.fr0.columnconfigure(0, weight = 1)
self.fr0.columnconfigure(1, weight = 1)
self.fr0.rowconfigure((1,2,3), weight = 1)
# Title
self.lab_bcwt = tk.Label(self.fr0, text = 'Title', font=("Roboto Medium", 40), justify = 'center')
self.lab_bcwt.grid(row = 0,rowspan = 2, columnspan = 2)
# ===============================
self.fr1 = tk.Frame(self.fr0)#, fg_color=("black","grey"))
self.fr1.grid(row=2, rowspan = 2, columnspan = 2, sticky = 'nsew', padx = 10, pady = 10)
self.fr1.columnconfigure(0, weight = 1)
self.fr1.columnconfigure(1, weight = 1)
self.fr1.rowconfigure((0,1,2,3,4,5), weight = 1)
# ===============================
self.fr2 = tk.Frame(self.fr1)
self.fr2.grid(row=0, columnspan = 2, sticky = 'new', padx = 10, pady = 10)
self.fr2.grid_rowconfigure(0, weight = 1)
self.fr2.grid_columnconfigure(0, weight = 1)
# ===============================
self.lab1 = tk.Label(self.fr2, text = 'This text appears first\n (click to continue)', font=("Ariel", -22), justify = 'center')
self.lab1.grid( row = 0, columnspan = 2, padx = 10, pady = 5)
self.bind("<Button-1>",self.click)
def on_closing(self, event=0):
self.destroy()
def exmp_gps(self):
self.lab1.destroy()
self.lab2 = tk.Label(self.fr2, text = 'Then this text appears second,\n telling you to input an integer', font=('Ariel', -22))
self.lab2.grid(row = 0, column = 0, sticky = 'new', padx = 10, pady = 10)
self.lab3 = tk.Label(self.fr1, text = 'Any Integer', borderwidth = 2, font = ('Ariel', 12))
self.lab3.grid(row = 1, column = 0, sticky = 'ne', padx = 10)
self.entry1 = tk.Entry(self.fr1, text = 'any integer', justify = 'center')
self.entry1.grid(row = 1, column = 1, sticky = 'nw',padx = 10)
self.entry1.configure(font = ('Arial Rounded MT Bold', 13))
def key_pressed(event):
global val
val = int(self.entry1.get())
# print(val)
self.entry1.bind("<KeyRelease>", key_pressed)
# Ideally
self.entry1.bind("<Return>", print(['Function using', val+1]))
def click(self,event):
global kk
if kk == 1:
self.exmp_gps()
if kk > 1:
print(['Function using', val+1])
if __name__ == "__main__":
app = App()
app.mainloop()
'''
There is few problems in code.
bind needs function's name without () but you use print() so it first runs print() (which returns None) and later it binds None to <Return>. You could bind lambda event:print(...) to run print() when you press Enter.
Code could be more readable if you would use normal self.val instead of global val and if normal function in class def key_pressed(self, event): instead of nested function.
Everytime when you click button then it runs clik() and it runs self.exmp_gps() and it creates new Entry. You should increase kk in click() to run self.exmp_gps() only once. And to make it more readable you could use ie. self.visible = False and later set self.visible = True
You think it can be simple to activate function 2000ms after last keypress - but it is not. It would have to use after() and remeber its ID and time when it was created (to delete it if next key will be pressed before 2000ms, and use new after()).
Using Enter is much, much simpler.
Full code with changes.
I added after() but I didn't test it - maybe in some situations it may run function many times.
import tkinter as tk
import tkinter.messagebox
class App(tk.Tk):
WIDTH = 1000
HEIGHT = 520
def __init__(self):
super().__init__()
self.geometry(f"{App.WIDTH}x{App.HEIGHT}")
self.protocol("WM_DELETE_WINDOW", self.on_closing) # call .on_closing() when app gets closed
self.fr0 = tk.Frame(master=self, background='grey')
self.fr0.pack(fill='both', expand=True, padx=20, pady=20)
# configure grid layout (2x1)
self.fr0.columnconfigure(0, weight=1)
self.fr0.columnconfigure(1, weight=1)
self.fr0.rowconfigure((1, 2, 3), weight=1)
# Title
self.lab_bcwt = tk.Label(self.fr0, text='Title', font=("Roboto Medium", 40), justify='center')
self.lab_bcwt.grid(row=0, rowspan=2, columnspan=2)
# ===============================
self.fr1 = tk.Frame(self.fr0)#, fg_color=("black","grey"))
self.fr1.grid(row=2, rowspan=2, columnspan=2, sticky='nsew', padx=10, pady=10)
self.fr1.columnconfigure(0, weight=1)
self.fr1.columnconfigure(1, weight=1)
self.fr1.rowconfigure((0, 1, 2, 3, 4, 5), weight=1)
# ===============================
self.fr2 = tk.Frame(self.fr1)
self.fr2.grid(row=0, columnspan=2, sticky='new', padx=10, pady=10)
self.fr2.grid_rowconfigure(0, weight=1)
self.fr2.grid_columnconfigure(0, weight=1)
# ===============================
self.lab1 = tk.Label(self.fr2, text='This text appears first\n (click to continue)', font=("Ariel", -22), justify='center')
self.lab1.grid(row=0, columnspan=2, padx=10, pady=5)
self.bind("<Button-1>", self.click)
self.val = 0
self.visible = False
self.after_id = None
def on_closing(self, event=0):
self.destroy()
def key_pressed(self, event):
self.val = int(self.entry1.get())
print('[key_pressed]', self.val)
if self.after_id:
print('[key_pressed] cancel after:', self.after_id)
self.after_cancel(self.after_id)
self.after_id = None
self.after_id = self.after(2000, self.process_data)
print('[key_pressed] create after:', self.after_id)
def process_data(self):
print('[process_data]')
def exmp_gps(self):
self.lab1.destroy()
self.lab2 = tk.Label(self.fr2, text='Then this text appears second,\n telling you to input an integer', font=('Ariel', -22))
self.lab2.grid(row=0, column=0, sticky='new', padx=10, pady=10)
self.lab3 = tk.Label(self.fr1, text='Any Integer', borderwidth=2, font=('Ariel', 12))
self.lab3.grid(row=1, column=0, sticky='ne', padx=10)
self.entry1 = tk.Entry(self.fr1, text='any integer', justify='center')
self.entry1.grid(row=1, column=1, sticky='nw', padx=10)
self.entry1.configure(font=('Arial Rounded MT Bold', 13))
self.entry1.bind("<KeyRelease>", self.key_pressed)
self.entry1.bind("<Return>", lambda event:print('[Return] Function using', self.val))
def click(self, event):
if not self.visible:
self.visible = True
self.exmp_gps()
else:
print('[click] Function using', self.val)
if __name__ == "__main__":
app = App()
app.mainloop()
I am trying to create flashcard game, but I have problem when trying to export dict to csv using pandas.
My dictionary has contained some Chinese letters and pinyin.
When I have played with multiple encodings, seem sometime Chinese letter can be read but pinyin is unreadable, sometimes its vice versa.
I'm not sure what is the issue about my code. please help me.
Thank you very much
Remark
for pinyin Im using slash or back-slash or dash to indicate tone
Ex. bàn tiān,
when import to csv, the program still can read those tone symbol, but not when export.
Example
export csv is on line 109-110
import random
import pandas as pd
from tkinter import *
from PIL import Image, ImageTk
windows = Tk()
windows.geometry(r"300x360")
windows.config(bg='#f7f5dd')
my_pic = Image.open(r"C:\\Users\\xx\\PycharmProjects\\flashcard\\Picture1.png")
scale_factor = 0.3
resized = my_pic.resize((int(712 * scale_factor), int(667 * scale_factor)))
img = ImageTk.PhotoImage(resized)
canvas = Canvas(width=235, height=235, bg="#f7f5dd", highlightthickness=0)
canvas.create_image(120, 120, image=img)
canvas.grid(column=1, row=1, pady=20, padx=30, columnspan=3)
know_button = Button()
dont_know_button = Button()
already_know_list = []
pix1 = Image.open(r"C:\Users\xx\PycharmProjects\flashcard\correct.png")
pix2 = Image.open(r"C:\Users\xx\PycharmProjects\flashcard\wrong.png")
scale_factor2 = 0.15
resized1 = pix1.resize((int(274 * scale_factor2), int(275 * scale_factor2)))
resized2 = pix2.resize((int(274 * scale_factor2), int(275 * scale_factor2)))
img1 = ImageTk.PhotoImage(resized1)
img2 = ImageTk.PhotoImage(resized2)
know_button.config(image=img1, bg="#f7f5dd", highlightthickness=0)
dont_know_button.config(image=img2, bg="#f7f5dd", highlightthickness=0)
know_button.grid(column=0, row=2, columnspan=2)
dont_know_button.grid(column=3, row=2, columnspan=2)
data = pd.read_csv(r"C:\\Users\\xx\\PycharmProjects\\flashcard\\hsk_vocabs_1_5.csv")
custom_data = data
number = random.randint(0, len(data))
chn_obj = canvas.create_text(120, 140, text=f"{data['Chinese'][number]}\n{data['Pinyin'][number]}", fill="white",
font=('Dosis SemiBold', 20, 'bold'), anchor='center')
five_sec_label = Label()
five_sec_label.config(text="3", font=('Dosis SemiBold', 20, 'bold'), bg="#f7f5dd")
five_sec_label.grid(column=1, row=2, columnspan=3)
init_sec = 3
timer = None
def clock(total_second):
global chn_obj, timer, init_sec
if total_second >= 0:
timer = windows.after(1000, clock, total_second - 1)
five_sec_label.config(text=f"{total_second}", font=('Corrier', 20, 'bold'))
else:
canvas.itemconfig(chn_obj, text="")
chn_obj = canvas.create_text(120, 140, text=f"{data['English'][number]}", fill="black",
font=('Dosis SemiBold', 15, 'bold'), anchor='center')
init_sec = 0
def next_word():
global number, chn_obj, timer, init_sec
init_sec = 3
canvas.itemconfig(chn_obj, text="")
chn_obj = canvas.create_text(120, 140, text=f"{data['Chinese'][number]}\n{data['Pinyin'][number]}", fill="white",
font=('Dosis SemiBold', 20, 'bold'), anchor='center')
windows.after_cancel(timer)
five_sec_label.config(text="")
clock(init_sec)
unknown_word = []
def already_know():
global already_know_list, number
already_know_list.append(number)
while number in already_know_list:
number = random.randint(0, len(data))
next_word()
def append_unknown_words():
global number, init_sec
if init_sec != 0:
return
else:
unknown_word.append(data['Chinese'][number])
number = random.randint(0, len(data))
next_word()
chinese_list = []
pinyin_list = []
english_list = []
def export_when_finished():
global unknown_word, chinese_list, pinyin_list, english_list
unknown_file = {
"Chinese": chinese_list,
"Pinyin": pinyin_list,
"English": english_list
}
for item in unknown_word:
chinese_list.append(data[data["Chinese"] == item]["Chinese"].values[0])
pinyin_list.append(data[data["Chinese"] == item]["Pinyin"].values[0])
english_list.append(data[data["Chinese"] == item]["English"].values[0])
df = pd.DataFrame(unknown_file)
df.to_csv('Unknown_Words.csv', encoding="utf-8")
exit()
know_button.config(command=already_know)
dont_know_button.config(command=append_unknown_words)
stop_game_n_export = Button()
stop_game_n_export.config(text="Stop and Export Unknown Words", font=('Dosis SemiBold', 10, 'bold'),
command=export_when_finished)
stop_game_n_export.grid(column=0, row=0, columnspan=3, rowspan=1)
clock(init_sec)
windows.mainloop()
I'm pretty new to python and Tkinter. I want to create 6 buttons and when you click on one of the buttons, the button text changes. I'm getting this error: AttributeError: 'str' object has no attribute 'configure'.
from tkinter import *
root = Tk()
root.resizable(width=False, height=False)
b1 = Button(root, text = '', width = 10, height = 5, command = lambda: main(1))
b1.grid(row = 0, column = 1)
b2 = Button(root, text = '', width = 10, height = 5, command = lambda: main(2))
b2.grid(row = 0, column = 2)
b3 = Button(root, text = '', width = 10, height = 5, command = lambda: main(3))
b3.grid(row = 0, column = 3)
b4 = Button(root, text = '', width = 10, height = 5, command = lambda: main(4))
b4.grid(row = 1, column = 1)
b5 = Button(root, text = '', width = 10, height = 5, command = lambda: main(5))
b5.grid(row = 1, column = 2)
b6 = Button(root, text = '', width = 10, height = 5, command = lambda: main(6))
b6.grid(row = 1, column = 3)
def main(num):
something = 'b' + str(num)
something.configure(text = 'hi')
I did this before so maybe there is a small mistake I made.
Thx in advance!
Looks like you are trying to create a vairable name by making a string.
So your variable 'something' ends up being "b2" for example which isn't the variable b2.
There's a couple of ways you could do this, one would be put your variables into a dict.
buttons = {'b2': Button(root, text='', width=10, height=5, command=lambda: main(1))}
# or like this once buttons is declared as a dict
buttons['b2'] = Button(root, text='', width=10, height=5, command=lambda: main(1))
Then to access the buttons you would do
buttons['b2'].grid(row = 0, column = 1)
buttons['b2'].configure(text = 'hi')
A faster way as suggested by TheLizzard (I've not tested it)
buttons = []
buttons.append(Button(root, text='', width=10, height=5, command=lambda: main(1)))
Then access by
buttons[0].grid(row=0, column=1)
I guess it is faster but maybe if you're dealing with lots of buttons having a readable key value could win out over performance?
I'm coding a GUI for inputting parameters, images and text all associated with a particular step (One single row per step) and then outputting it as JavaScript code to be used in another program. But this is beside my point:
I am having trouble forcing the column widths. It seems that both canv_1.grid_columnconfigure(6, weight=2) and canv_1.grid_columnconfigure(1, weight=0) do nothing. I'm trying to keep the width of the column 2nd from the left to a minimum. And I want column 6 to be twice as wide as the others.
import tkinter as tk
from tkinter import simpledialog,filedialog,colorchooser,messagebox,Frame,Button
from PIL import ImageTk, Image
import textwrap
root = tk.Tk()
load1 = Image.open("example.jpg")
root.render1 = ImageTk.PhotoImage(load1)
canv_1 = tk.Canvas(root, bg="gray")
canv_1.grid_rowconfigure(0, weight=1)
canv_1.grid_columnconfigure(6, weight=2)
canv_1.grid_columnconfigure(2, weight=0)
canv_1.grid(row=0, column=0, sticky="news")
canv_1.grid(row=1, column=0, sticky="news")
labels = ["Image", "Chapter #", "Chapter Title", "Step", "Slide", "Sequence Step", "Instructions"]
root.label_wid = []
font1 = ("arial", 15, "bold")
ch_text = []
def exportCode():
# Gather text input for each chapter
for i in range(0,5):
# Get the text (unwrapped) from a single input cell:
a_temp = instruction_col[i].get('1.0','10.0')
# Wrap the text at 54 characters, then append it to the list ch_text
ch_text.append(textwrap.wrap(a_temp,54))
# Create a new file
f = open("demofile2.js", "w")
# For each chapter
for i in range(1,5):
# Write to this file line by line
#
# stepID = str()
# stepHeading = "if(place==\""
for j in range(1,11):
tnum = str(j)
nline1st = " scopeSet(\"T"+tnum+"\",\"text\",\""
if (len(ch_text[i-1])<j):
nline2nd = ""
else:
nline2nd = ch_text[i-1][j-1]
f.write(nline1st+nline2nd+"\")\n")
f.close()
print("Code exported.")
for i in range(len(labels)):
root.label_wid.append(tk.Label(canv_1, font=font1, relief="raised", text=labels[i]).grid(row=0, column=i, sticky="we"))
root.images = [
ImageTk.PhotoImage(Image.open("example.jpg"))
for y in range(1,6)
]
def change_img(y):
#print(y)
#print(len(root.images))
root.img1 = filedialog.askopenfilename()
root.load_img1 = Image.open(root.img1)
root.render_img1 = ImageTk.PhotoImage(root.load_img1)
image_col[y]['image'] = root.render_img1
print(image_col[y]['image'])
print(image_col[y-1]['image'])
print(root.render_img1)
c1 = "#a9d08e"
c2 = "#8dd1bf"
image_col = [
tk.Button(
canv_1,
image=root.render1,
relief="raised",
bg="light gray",
command = lambda y=y: change_img(y),
)
for y in range(0, 5)
]
ChNum_col = [
tk.Entry(
canv_1,
bg = c1,
font = ("arial", 15))
for y in range(0, 5)
]
Title_col = [
tk.Entry(
canv_1,
bg = c1,
font = ("arial", 15))
for y in range(0, 5)
]
Step_col = [
tk.Entry(
canv_1,
bg = c1,
font = ("arial", 15))
for y in range(0, 5)
]
Slide_col = [
tk.Entry(
canv_1,
bg = c2,
font = ("arial", 15))
for y in range(0, 5)
]
SeqS_col = [
tk.Entry(
canv_1,
bg = c2,
font = ("arial", 15))
for y in range(0, 5)
]
instruction_col = [
tk.Text(
canv_1,
bg="white",
wrap="word",
font=("arial",15), width=20, height=10)
for y in range(0, 5)
]
example_text_1 = "The purpose of this app is for the user to select an image and designate the associated parameters and text before exporting it as a JavaScript file to be used in a separate program."
example_text_2 = " Here is another example of text that might be used. This can be used for a specific chapter to test this code. It's getting closer to being ready for use"
instruction_col[0].insert(1.0,example_text_1)
instruction_col[1].insert(1.0,example_text_2)
# for y, image_cell in enumerate(image_col, 1):
# image_cell.grid(row=y, column=0, sticky='news')
# for y, image_cell in enumerate(instruction_col, 1):
# image_cell.grid(row=y, column=6, sticky='news')
# above is same as below
for y in range(0,5):
image_col[y].grid(row=y + 1, column=0, sticky='news')
ChNum_col[y].grid(row=y + 1, column=1, sticky='news')
Title_col[y].grid(row=y + 1, column=2, sticky='news')
Step_col[y].grid(row=y + 1, column=3, sticky='news')
Slide_col[y].grid(row=y + 1, column=4, sticky='news')
SeqS_col[y].grid(row=y + 1, column=5, sticky='news')
instruction_col[y].grid(row=y+1, column=6, sticky='news')
# ================================================================================================
bt1 = tk.Button(canv_1, text="Export", font=font1, command=exportCode).grid(row=0, column=7)
load2 = Image.open("scroll-up.png")
root.render2 = ImageTk.PhotoImage(load2)
load3 = Image.open("scroll-down.png")
root.render3 = ImageTk.PhotoImage(load3)
scroll_up = tk.Button(canv_1, image=root.render2).grid(row=1, column=7, rowspan=2) # , sticky="n")
scroll_up = tk.Button(canv_1, image=root.render3).grid(row=3, column=7, rowspan=2) # , sticky="s")
root.mainloop()
First
As mentioned by
#jizhihaoSAMA
width must be set.
I configured all Entry widths as width = 1, that seemed to shrink the column the to minimum width that matches the width of the accompanying Label above it.
Second
In addition to weight, it seems you need uniform = 999 (or any number / string) that will identify the column as part of a group that will proportion the width according to weight = 1, wieght = 2 per respective column.
In the modified script I made column 7 as 5 times the width of column 1
import tkinter as tk
from tkinter import simpledialog,filedialog,colorchooser,messagebox,Frame,Button,PhotoImage
#from PIL import ImageTk, Image
import textwrap
root = tk.Tk()
#load1 = Image.open("example.jpg")
root.render1 = PhotoImage(file="yes.png")
canv_1 = tk.Canvas(root, bg="red")
## Here uniform = ... must be set ##
canv_1.grid_rowconfigure(0, weight=1,uniform = 999)
canv_1.grid_columnconfigure(6, weight=5, uniform = 999)
canv_1.grid_columnconfigure(2, weight=0, uniform = 999)
canv_1.grid(row=0, column=0, sticky="news")
canv_1.grid(row=1, column=0, sticky="news")
labels = ["Image", "Chapter #", "Chapter Title", "Step", "Slide", "Sequence Step", "Instructions"]
root.label_wid = []
font1 = ("arial", 15, "bold")
ch_text = []
def exportCode():
# Gather text input for each chapter
for i in range(0,5):
# Get the text (unwrapped) from a single input cell:
a_temp = instruction_col[i].get('1.0','10.0')
# Wrap the text at 54 characters, then append it to the list ch_text
ch_text.append(textwrap.wrap(a_temp,54))
# Create a new file
#f = open("demofile2.js", "w")
# For each chapter
for i in range(1,5):
# Write to this file line by line
#
# stepID = str()
# stepHeading = "if(place==\""
for j in range(1,11):
tnum = str(j)
nline1st = " scopeSet(\"T"+tnum+"\",\"text\",\""
if (len(ch_text[i-1])<j):
nline2nd = ""
else:
nline2nd = ch_text[i-1][j-1]
#f.write(nline1st+nline2nd+"\")\n")
#f.close()
print("Code exported.")
for i in range(len(labels)):
tmp = tk.Label(canv_1, font=font1, relief="raised", text=labels[i])
tmp.grid(row=0, column=i, sticky="we")
root.label_wid.append(tmp)
print(root.label_wid[0].winfo_reqwidth())
root.images = [PhotoImage(file="yes.png") for y in range(1,6)]
def change_img(y):
#print(y)
#print(len(root.images))
root.img1 = filedialog.askopenfilename()
root.load_img1 = Image.open(root.img1)
root.render_img1 = PhotoImage(root.load_img1)
image_col[y]['image'] = root.render_img1
print(image_col[y]['image'])
print(image_col[y-1]['image'])
print(root.render_img1)
c1 = "#a9d08e"
c2 = "#8dd1bf"
image_col = [ tk.Button(canv_1, image=root.render1,relief="raised",bg="light gray",command = lambda y=y: change_img(y),width = 1) for y in range(0, 5) ]
ChNum_col = [tk.Entry(canv_1,bg = c1,font = ("arial", 15),width = 1) for y in range(0, 5) ]
Title_col = [tk.Entry(canv_1,bg = c1,font = ("arial", 15),width = 1) for y in range(0, 5) ]
Step_col = [tk.Entry(canv_1,bg = c1,font = ("arial", 15),width = 1) for y in range(0, 5)]
Slide_col = [tk.Entry( canv_1, bg = c2,font = ("arial", 15),width = 1) for y in range(0, 5)]
SeqS_col = [tk.Entry(canv_1,bg = c2,font = ("arial", 15),width = 1) for y in range(0, 5)]
instruction_col = [ tk.Text( canv_1, bg="white",wrap="word", font=("arial",15), width=5, height=10) for y in range(0, 5)
]
example_text_1 = "The purpose of this app is for the user to select an image and designate the associated parameters and text before exporting it as a JavaScript file to be used in a separate program."
example_text_2 = " Here is another example of text that might be used. This can be used for a specific chapter to test this code. It's getting closer to being ready for use"
instruction_col[0].insert(1.0,example_text_1)
instruction_col[1].insert(1.0,example_text_2)
# for y, image_cell in enumerate(image_col, 1):
# image_cell.grid(row=y, column=0, sticky='news')
# for y, image_cell in enumerate(instruction_col, 1):
# image_cell.grid(row=y, column=6, sticky='news')
# above is same as below
for y in range(0,5):
image_col[y].grid(row=y + 1, column=0, sticky='news')
ChNum_col[y].grid(row=y + 1, column=1, sticky='news')
Title_col[y].grid(row=y + 1, column=2, sticky='news')
Step_col[y].grid(row=y + 1, column=3, sticky='news')
Slide_col[y].grid(row=y + 1, column=4, sticky='news')
SeqS_col[y].grid(row=y + 1, column=5, sticky='news')
instruction_col[y].grid(row=y+1, column=6, sticky='news')
# ================================================================================================
bt1 = tk.Button(canv_1, text="Export", font=font1, command=exportCode).grid(row=0, column=7)
#load2 = Image.open("scroll-up.png")
root.render2 = PhotoImage(file="yes.png")
#load3 = Image.open("scroll-down.png")
root.render3 = PhotoImage(file="yes.png")
scroll_up = tk.Button(canv_1, image=root.render2).grid(row=1, column=7, rowspan=2) # , sticky="n")
scroll_up = tk.Button(canv_1, image=root.render3).grid(row=3, column=7, rowspan=2) # , sticky="s")
root.mainloop()
Use width
I tried width earlier, but it didn't seem to work- possibly because I had empty columns? Now the code is working though:
ChNum_col = [
tk.Entry(
canv_1,
bg = c1,
width = 10,
font = ("arial", 15))
for y in range(0, 5)
]