tkinter key binding causes image to disappear - python-3.x

I'm trying to bind arrow keys to buttons or at least the functions of the buttons (button_forward and button_back). The function of the buttons works, however, when I bind a key to the button the image just disappears.
It would also be awesome if someone could help me figure out how to create a loop to define the images and put them into a list. I'm just so lost when it comes to that.
The main purpose of the code is to be an image viewer that flashes an LED strip when an image changes.
I want to be able to control it using arrow keys to move forward and back between the images.
from tkinter import Tk, Button,Label, DISABLED
from PIL import ImageTk,Image
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
root= Tk()
root.configure(bg='black')
root.title("please work")
# define, load, show
my_img1 = ImageTk.PhotoImage(Image.open("1.bmp"))
my_img2 = ImageTk.PhotoImage(Image.open("2.bmp"))
my_img3 = ImageTk.PhotoImage(Image.open("3.bmp"))
my_img4 = ImageTk.PhotoImage(Image.open("4.bmp"))
my_img5 = ImageTk.PhotoImage(Image.open("5.bmp"))
my_img6 = ImageTk.PhotoImage(Image.open("6.bmp"))
my_img7 = ImageTk.PhotoImage(Image.open("7.bmp"))
my_img8 = ImageTk.PhotoImage(Image.open("8.bmp"))
image_list = [my_img1, my_img2, my_img3, my_img4, my_img5, my_img6, my_img7, my_img8]
my_label = Label(image=my_img1)
my_label.grid(row = 0, column = 0, columnspan= 3, rowspan = 25, padx=440, pady= 5)
def forward(image_number, event = None):
global my_label
global button_forward
global button_back
my_label.grid_forget()
my_label = Label(image = image_list[image_number-1])
button_forward = Button(root, text = "next", command=lambda: forward(image_number+1))
button_back = Button(root, text = "previous", command = lambda: back(image_number-1))
if image_number == 7:
button_forward = Button(root, text = "next", state = DISABLED)
my_label.grid(row = 0, column = 0, columnspan = 3, rowspan = 25, padx=440, pady= 5)
button_back.grid(row = 23, column = 0)
button_forward.grid(row = 23, column = 2)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
def back(image_number,):
global my_label
global button_forward
global button_back
my_label.grid_forget()
my_label = Label(image = image_list[image_number-1])
button_forward = Button(root, text = "next", command=lambda: forward(image_number+1))
button_back = Button(root, text = "previous", command = lambda: back(image_number-1))
my_label.grid(row = 0, column = 0, columnspan = 3, rowspan = 25, padx=440, pady= 5)
if image_number == 1:
button_back = Button(root, text = "previous", state = DISABLED)
button_back.grid(row=23, column = 0 )
button_exit.grid(row=23, column = 1 )
button_forward.grid(row=23, column = 2)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
button_back = Button(root, text = "previous", command = back)
button_exit = Button(root, text = "Exit", command = root.quit)
button_forward = Button(root, text = "next", command =lambda:forward(2))
root.bind('<Left>', back)
root.bind('<Right>', forward)
button_back.grid(row=23, column = 0 )
button_exit.grid(row=23, column = 1 )
button_forward.grid(row=23, column = 2)
root.mainloop()

Your bindings cannot work because the event corresponding to the keypress will be passed instead of the image_number argument in back() and forward().
Also, you are recreating the widgets every time while you should only reconfigure them. So to change the label's image, you can do: my_label.configure(image=<new image>). Also instead of passing image_number as an argument, I would rather use a global variable, so that it will be easier to use the functions in the key bindings:
from tkinter import Tk, Button, Label, DISABLED, NORMAL
from PIL import ImageTk, Image
import board
import time
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
root = Tk()
root.configure(bg='black')
root.title("please work")
# define, load, show
my_img1 = ImageTk.PhotoImage(Image.open("1.bmp"))
my_img2 = ImageTk.PhotoImage(Image.open("2.bmp"))
my_img3 = ImageTk.PhotoImage(Image.open("3.bmp"))
my_img4 = ImageTk.PhotoImage(Image.open("4.bmp"))
my_img5 = ImageTk.PhotoImage(Image.open("5.bmp"))
my_img6 = ImageTk.PhotoImage(Image.open("6.bmp"))
my_img7 = ImageTk.PhotoImage(Image.open("7.bmp"))
my_img8 = ImageTk.PhotoImage(Image.open("8.bmp"))
image_list = [my_img1, my_img2, my_img3, my_img4, my_img5, my_img6, my_img7, my_img8]
image_number = 1
# create the label only once
my_label = Label(root, image=image_list[image_number - 1])
my_label.grid(row=0, column=0, columnspan= 3, rowspan=25, padx=440, pady= 5)
def forward(event=None):
global image_number # global variable to keep track of the displayed image
image_number += 1
# change image in label
my_label.configure(image=image_list[image_number - 1])
if image_number == 8:
# last image, disable forward button
button_forward.configure(state=DISABLED)
elif image_number == 2:
# no longer first image, re-enable back button
button_back.configure(state=NORMAL)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
def back(event=None):
global image_number
image_number -= 1
my_label.configure(image=image_list[image_number - 1])
if image_number == 1:
# first image, disable back button
button_back.configure(state=DISABLED)
elif image_number == 7:
# no longer last image, re-enable forward button
button_forward.configure(state=NORMAL)
pixels.fill((255,0,0))
time.sleep(0.1)
pixels.fill((0,0,0))
time.sleep(0.5)
button_back = Button(root, text="previous", command=back, state=DISABLED)
button_exit = Button(root, text="Exit", command=root.quit)
button_forward = Button(root, text="next", command=forward)
root.bind('<Left>', back)
root.bind('<Right>', forward)
button_back.grid(row=23, column=0)
button_exit.grid(row=23, column=1)
button_forward.grid(row=23, column=2)
root.mainloop()

Related

All other widgets are affected when one of the widgets move in a GUI (using the tkinter library in python 3)

Whenever I try to move individual widgets or click a button that produces words effectively moving other widgets that had nothing to do those both specified actions above.
Here is my code:
import tkinter as tk
# Create the main window
window = tk.Tk()
window.title("Price Calculator")
window.geometry("800x600")
window.config(background = "#777474")
def calculate_price():
global input_field
input_field_value = input_field.get()
try:
input = int(input_field_value)
price = input* 0.1
answer.config(text = (f"Your price is ","%.3f"%price,"KWD"))
except ValueError as ve:
answer.config(text = 'What you have just entered are not numbers whatsoever, try again!', fg = "#CD5F66")
price_input = tk.Label(window, text = "Total Pages:", font = "Arial", bg = "#777474", fg = "#FEFCF2")
price_input.grid(column = 0, row = 0)
input_field = tk.Entry(window, font = "Arial", bg = "#FEFCF2")
input_field.grid(column = 1, row = 0, padx = 0,pady = 10)
answer = tk.Label(window, bg = "#777474")
answer.grid(pady = 20)
button_return = tk.Button(window, text = "Calculate Price", command = calculate_price).grid()
# Run the main loop
window.mainloop()
This is my GUI before I click on the button which is called "Calculate Price":
This is my GUI after I have clicked on the button:
The problem here is that I don't want the Total Pages and the entry field to move away from each other whenever I click on the button.
I would suggest to put price_input and input_field into a frame for easier layout management. I also use sticky="w" on the frame, answer and button_return so that they are aligned at the left.
Below is the modified code:
import tkinter as tk
FGCOLOR = "#FEFCF2"
BGCOLOR = "#777474"
ERRCOLOR = "#FF5F66"
# Create the main window
window = tk.Tk()
window.title("Price Calculator")
window.geometry("800x600")
window.config(background="#777474")
def calculate_price():
input_field_value = input_field.get()
try:
input = int(input_field_value)
price = input * 0.1
answer.config(text=f"Your price is {price:.3f} KWD", fg=FGCOLOR)
except ValueError as ve:
answer.config(text='What you have just entered are not numbers whatsoever, try again!', fg=ERRCOLOR)
# create a frame for price_input and input_field
frame = tk.Frame(window, bg=BGCOLOR)
frame.grid(column=0, row=0, padx=10, pady=10, sticky="w")
price_input = tk.Label(frame, text="Total Pages:", font="Arial", bg=BGCOLOR, fg=FGCOLOR)
price_input.grid(column=0, row=0)
input_field = tk.Entry(frame, font="Arial", bg=FGCOLOR)
input_field.grid(column=1, row=0)
answer = tk.Label(window, bg=BGCOLOR)
answer.grid(column=0, row=1, padx=10, pady=10, sticky="w")
button_return = tk.Button(window, text="Calculate Price", command=calculate_price)
button_return.grid(column=0, row=2, sticky="w", padx=10, pady=10)
# Run the main loop
window.mainloop()

Tkinter Scrollbar inactive untill the window is manually resized

The scrollbar activates only when the window is rezised, despite reconfiguring the scrollregion everytime a widget(Button in this case) is added.
class Editor:
def __init__(self,master):
self.master = master
self.master.resizable(True,False)
self.edit_frame = tk.Frame(self.master)
self.edit_frame.pack(fill="none")
self.elem_frame = tk.Frame(self.master,width=700)
self.elem_frame.pack(fill="y", expand=1)
self.my_canvas = tk.Canvas(self.elem_frame, width = 700)
self.my_canvas.pack(side = "left", fill="both", expand=1)
my_scrollbar = ttk.Scrollbar(self.elem_frame, orient = "vertical", command =self.my_canvas.yview)
my_scrollbar.pack(side = "right",fill="y")
self.my_canvas.configure(yscrollcommand=my_scrollbar.set)
self.my_canvas.bind('<Configure>', self.movescroll )
self.second_frame = tk.Frame(self.my_canvas, bg = "black", width=700)
self.my_canvas.create_window((0,0), window=self.second_frame, anchor="nw")
self.naz = Nazioni()
paesi = [*self.naz.iso3]
print(paesi)
self.comb_paese = ttk.Combobox(self.edit_frame, value = paesi)
self.comb_paese.current(1)
self.kwordvar= tk.StringVar()
entry_keyword = tk.Entry(self.edit_frame, textvariable=self.kwordvar)
entry_keyword.bind("<FocusOut>", self.callback)
writer = tk.Text(self.edit_frame)
self.edit_frame.pack(side="left")
writer.pack()
self.comb_paese.pack()
entry_keyword.pack()
def callback(self, *args):
kword = self.kwordvar.get()
self.colonnarisultati(kword)
def colonnarisultati(self, keyword):
#TROVA IL VALORE CODICE ISO A 3CHAR IN BASE ALLA NAZIONE NEL COMBOBOX
p = self.comb_paese.get()
paese = self.naz.iso3[p]
ricerca = Ricerca(paese, keyword)
"""
for label in self.elem_frame.winfo_children():
label.destroy()
"""
self.count = 0
print("ciao")
for x in ricerca.listaricerca:
tit = str(x['titolo']).lstrip("<h4>").rstrip("</h4>")
print(tit)
self.elementotrovato(tit,self.count)
self.count +=1
self.my_canvas.configure(scrollregion=self.my_canvas.bbox("all"))
def movescroll(self, *args):
self.my_canvas.configure(scrollregion=self.my_canvas.bbox("all"))
def elementotrovato(self, testobottone, conta):
Bott_ecoifound = tk.Button(self.second_frame, text = testobottone,width = 100 ,height = 30, font = ("Helvetica", 12, "bold"), wraplength=200, justify="left")
print("CIAONE")
Bott_ecoifound.pack(fill="both", expand=1)
self.my_canvas.configure(scrollregion=self.my_canvas.bbox("all"))
The last method is the one adding button to the scrollable frame.
After the window is manually resized, no matter if back to its original size, the scrollbar activates and works fine.

tkinter scrollbar with grid, it doesn't get linked

I'm studying GUI, so please understand my poor codes below.
I was trying to make a program which gets game-character's information. So if you press the 'search' button, the list would be shown below. But... it only shows about 11 names due to the window size. So i wanted to put a scrollbar for that area, but I just don't know how to link the scroll bar to control the area. I meant, the scroll bar itself has created, and it does scroll itself, but it doesn't scroll the window I wanted. I must have linked it wrong but... not sure.
Below is the minimized example code, but it's still quite long and crude. Sorry for that again.
If anyone can enlighten me, it would be really great help for this and my future works as well.
import tkinter as tk
import requests
from bs4 import BeautifulSoup
import webbrowser
import time
global var_dict, input_id, output
var_dict = {}
def enter_call_back(event=None):
output.grid(column = 0, row = 2, columnspan = 5 , sticky='w')
output.insert(tk.END,"Text_Something")
output.update()
search_chr()
def open_browse(url_list):
for url in url_list:
time.sleep(0.3)
webbrowser.open(url)
def search_inven(ch_id):
if ch_id == "ch1" or ch_id == "ch13" or ch_id == "ch15" :
num = 5
url_list = ["something.url","something2.url"]
self_count = 1
else:
num = 0
url_list = []
self_count = 0
masterset = []
masterset.append(num)
masterset.append(url_list)
masterset.append(self_count)
return masterset
def search_chr():
global var_dict, output
for things in var_dict.keys():
var_dict[things].destroy()
chr_list = ["ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch9","ch10","ch11","ch12","ch13","ch14","ch15"]
output.insert(tk.END," Done! \n\n")
var_dict = {}
num = -1
for ch in chr_list:
num += 1
var_dict["output%s" %num] = tk.Entry(frame_buttons, width = 125)
result = search_inven(ch)
if result[0] == 0:
var_dict["output"+str(num)].insert(0, "Clean "+ch+"\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
else:
url_list = result[1]
var_dict["o-button%s" %num] = tk.Button(frame_buttons, command=lambda url_list = url_list : open_browse(url_list))
var_dict["o-button"+str(num)].grid(column = 1, row = num, sticky='e')
var_dict["o-button"+str(num)].config(text="URL")
var_dict["output"+str(num)].insert(0, "Not Clean "+str(result[0])+" Self : "+str(result[2])+" Ch_id : "+ch+")\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
vsb = tk.Scrollbar(frame_canvas, orient="vertical")
vsb.grid(row=0, column=1, sticky='ns')
vsb.config(command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
frame_canvas.config(height = 300)
canvas.config(scrollregion=canvas.bbox("all"))
root = tk.Tk()
root.geometry("760x710")
root.resizable(width=False, height=False)
root.title("Minimum v.1.2")
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')
intro = tk.Text(frame_main, height = 17, bg="#E3D5F3")
intro.option_add("*Font", "명조 10")
intro.insert(tk.CURRENT,"Text_something")
intro.config(state='disabled')
intro.grid(row=0, column=0, pady=(5, 0), columnspan = 5, sticky='nw')
input_id = tk.Entry(frame_main, width = 35)
input_id.option_add("*Font","명조 10")
input_id.insert(0,"Ch_name")
input_id.grid(row=1, column=0, pady=(5, 0), sticky='w')
search_btn = tk.Button(frame_main)
search_btn.config(text="Search")
search_btn.option_add("*Font","명조 10")
search_btn.config(width=5,height=1)
search_btn.grid(row = 1, column = 0, pady=(5, 0), sticky='e')
output = tk.Text(frame_main, height = 10)
output.option_add("*Font","명조 10")
output.grid(row = 2, column = 0,pady=(5,0),sticky='nw')
frame_canvas = tk.Frame(frame_main, width = 565)
frame_canvas.grid(row=3, column=0, pady=(5, 0), columnspan = 3 ,sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
frame_canvas.grid_propagate(False)
canvas = tk.Canvas(frame_canvas, bg="gray", height=500,scrollregion=(0,0,500,1800))
canvas.grid(row=0, column=0, sticky="news")
frame_buttons = tk.Frame(canvas, bg="gray")
frame_buttons.grid(row = 0, column = 0,sticky='e')
root.bind('<Return>',enter_call_back)
search_btn.config(command = enter_call_back)
root.mainloop()
First, using grid() to put frame_buttons into the canvas will not affect the scrollregion of the canvas. Use canvas.create_window() instead.
Second, it is better to bind <Configure> event on frame_buttons and update canvas' scrollregion inside the bind callback. Then adding widgets to frame_buttons will automatically update the scrollregion.
Also note that you have created new scrollbar and put it at same position whenever search_chr() is executed. Better create the scrollbar only once outside the function.

Trouble with place_forget()

I have been trying to get .place_forget() to work in my test application but I am having some difficulty.
I am trying to get the widgets in "def select_1:" to show when R1 "Yes" checkbox is checked and then have the widgets not show when the check is removed.
The widgets show when I check the box but will not forget(hide) when it is then unchecked.
Any assistance would be greatly appreciated.
import os, sys
import pywintypes
from tkinter import *
#================================= MAIN WINDOW =================================
root = Tk()
w = 750
h = 325
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.title('Test Application')
root.geometry('750x325')
root.config(bg='#000000')
pass_entry=StringVar()
pass_1=StringVar()
var1 = IntVar()
var2 = IntVar()
selection = StringVar()
#=================================== HEADER ====================================
header = Label(root, font = ('Times New Roman','25','bold'), text='Test Application',
bg = ('#000000'), fg = ('#B3CDE0'))
header.place(x=250,y=15)
#================================ RESULT WINDOW ================================
result_window = Text(root, width = 80, height = 10)
result_window.place(x=50, y=75)
#=========================== CHECK BUTTON SELECTION ============================
def select_1():
if var1.get()==1:
pass_entry = Entry(root, width = 20, textvariable = pass_1, bg='#000000', fg='#B3CDE0')
pass_entry.place(x=250,y=275)
pass_entry.focus_set()
selection = Label(root, text='Enter OS Password:', bg='#000000', fg='#B3CDE0')
selection.place(x=140,y=275)
elif var1.get()==0:
pass_entry.place_forget()
selection.place_forget()
else:
return
#========================= ACCESS CREDENTIAL MANAGER ===========================
def getpass():
if var1.get()==1:
os.system('explorer.exe')
else:
return
def close():
root.destroy()
#=============================== RADIO BUTTONS =================================
R1 = Checkbutton(root, text="Yes", variable = var1, onvalue = 1, offvalue = 0, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R1.place(x=350,y=250)
R2 = Checkbutton(root, text="No ", variable = var2, onvalue = 1, offvalue = 0, height=1, width = 15, bg='#000000', fg='#B3CDE0', activebackground = '#000000')
R2.place(x=350,y=275)
#=========================== RADIO BUTTON SELECTION ============================
cancel_button = Button(root, text='Cancel', width = 12, bg=('#000000'), fg = ('#B3CDE0'), activebackground = '#000000', command = close)
cancel_button.place(x=590,y=270)
recover_button = Button(root, text='Open', width = 12, bg=('#000000'), fg = ('#B3CDE0'), activebackground = '#000000',command = getpass)
recover_button.place(x=480,y=270)
root.mainloop()
When you want to make a widget disappear and then appear again, you don't actually have to define it and all it's options again.
#=========================== CHECK BUTTON SELECTION ============================
pass_entry = Entry(root, width = 20, textvariable = pass_1, bg='#000000', fg='#B3CDE0')
selection = Label(root, text='Enter OS Password:', bg='#000000', fg='#B3CDE0')
def select_1():
if var1.get()==1:
pass_entry.place(x=250,y=275)
pass_entry.focus_set()
selection.place(x=140,y=275)
elif var1.get()==0:
pass_entry.place_forget()
selection.place_forget()
else:
return
Notice how pass_entry and selection are defined outside of the function and only placed inside the function.
What's a bit confusing though is why you're using two separate buttons for "yes" and "no" if checking them doesn't automatically uncheck the other one (i assume that's the purpose of the two buttons).
If that's what you want to do, you should use the Radiobutton widget instead. Notice how both of them affect the same variable and each of them have one value.
#=============================== RADIO BUTTONS =================================
R1 = Radiobutton(root, text="Yes", variable = var1, value = 1, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R1.place(x=350,y=250)
R2 = Radiobutton(root, text="No", variable = var1, value = 0, height=1, width = 15, activebackground = '#000000', bg='#000000', fg='#B3CDE0', command=select_1)
R2.place(x=350,y=275)
I also tidied up the other options a bit too, you had some random spacing in there.

Tkinter background color issue at scrollbar

I am working on a tkinter script which has a vertical and horizontal scrollbar.
A portion of the window below the vertical scrollbar is not picking up the background color I'm applying.
I have tried the following color options still the small portion is not picking up.
Image:
Sample window snapshot
Full Code:
from tkinter.tix import *
from tkinter import *
import collections
root = Tk()
root.configure(background='steel blue')
# Global variables
fname = ''
# Variables for setting the height and width of widget
# Variables to set Height
actualRootHeight = 300
rootHScale = 25
rootHOffset = 100
canvasHeight = 300
root2CanvasHMargin =65
# Variables to set Width
rootWScale = 10
rootWOffset = 200
canvasWidth = 300
root2CanvasWMargin = 20
inpWidth = 0
# Lists to save configs
inpParamList = collections.OrderedDict()
paramListRef = collections.OrderedDict()
updatedParamList = collections.OrderedDict()
entryList = []
labels = []
# All widget coding is done here
class guiList(Frame):
global root
# Constructor - Use as a control structure
def __init__(self,parent):
Frame.__init__(self,parent)
self.parent = parent
self.readParams()
self.setGeometry()
self.initUI()
self.controlUI()
def onFrameConfigure(self, event, Canvas1):
# Reset the scroll region to encompass the inner frame
Canvas1.configure(scrollregion=Canvas1.bbox("all"), background='steel blue')
# All widget edition is done here
def initUI(self):
global paramListRef
titleStr = sys.argv[1]
self.parent.title(titleStr)
self.grid(row=0, column=0)
inpConfigs = inpParamList.items()
# Add a canvas and call Frame as it's child widget
# Scrollbar can be added to Canvas
Canvas1 = Canvas(self, width=canvasWidth, height=canvasHeight, borderwidth=0, bg="light steel blue")
vsb = Scrollbar(self, orient="vertical", command=Canvas1.yview, bg="light steel blue", troughcolor="steel blue", highlightcolor="light steel blue", activebackground="light steel blue", highlightbackground="light steel blue")
Canvas1.configure(yscrollcommand=vsb.set)
vsb.grid(column=2, sticky='NS')
hsb = Scrollbar(self, orient="horizontal", command=Canvas1.xview, bg="light steel blue", troughcolor="steel blue")
Canvas1.configure(xscrollcommand=hsb.set)
hsb.grid(column=0, sticky='EW')
Canvas1.grid(row=0, column=0, sticky='NWES')
# Create new Frame for input configs
Frame1 = Frame(Canvas1, width=canvasWidth, height=canvasHeight, bg="light steel blue")
Canvas1.create_window((1,1),window=Frame1, anchor="nw", tags="Frame1")
Frame1.bind("<Configure>", lambda event, arg=Canvas1: self.onFrameConfigure(event, arg))
# Loop through the input configs
i = 0
# Add label and combobox in loop
for k,v in inpConfigs:
# Label widgets
lbl1 = Label(Frame1, text=k, bg="light steel blue", font=("Helvetica", 12, "bold"), fg="steel blue")
lbl1.grid(row = i, column = 0, padx=10, pady=5, sticky='W')
labels.append(lbl1)
# Combo-box widget for configurations
tkvar = StringVar(Frame1)
tkvar.set(v[0])
entry1 = OptionMenu(Frame1, tkvar, *v)
entry1.configure(width=20, anchor=W, bg="steel blue", fg="white", font=("Helvetica", 11, "bold"))
entry1.grid(row = i, column=1, padx=10, pady=5, sticky='E')
#entry1.grid_columnconfigure(2, weight=2)
paramListRef[k] = tkvar
i += 1
# Read the updated configs after the button click
def readUpdatedParams(self):
global updatedParamList
for k,v in paramListRef.items():
updatedParamList[k] = v.get()
root.destroy()
self.writeBack()
# Seperate Frame for buttons
# Upon clicking read updted params
def controlUI(self):
Frame2 = Frame(self, bg="steel blue")
Frame2.grid(row=2, column = 0, sticky="EW")
b = Button(Frame2, text="OK", command=self.readUpdatedParams, bg="light steel blue", fg="steel blue", font=("Helvetica", 11, "bold"))
#b.grid(row=1, column=1, pady=10)
b.pack(fill="none", expand=True, pady = 10)
# Read the file and create a key, value pair for configs
# Lines in file is split with space as delimiter
# First column is the config name and rest are all possible value
def readParams(self):
global inpParamList
global inpWidth
f = open(fname)
for line in f:
val = {}
val = line.split()
key = val.pop(0)
# Get the max width of key to adjust widget width
inpWidth = len(key) if (len(key) > inpWidth) else inpWidth
inpParamList[key] = val
# Geometry ( X-width x Y-width + X-position + Y-position)
# Based on the number of elements in the config list
# the height of the widget is set (Max is 75% of screen size)
def setGeometry(self):
global actualRootHeight
global canvasWidth
global canvasHeight
listLen = len(inpParamList)
rootWinwidth = int(inpWidth *rootWScale) + rootWOffset
rootWinheight = (listLen * rootHScale ) + rootHOffset
screenWidth = self.winfo_screenwidth()
screenHeight = int(self.winfo_screenheight() * 0.75)
if rootWinheight < screenHeight :
actualRootHeight = rootWinheight
else :
actualRootHeight = screenHeight
canvasWidth = rootWinwidth - root2CanvasWMargin
canvasHeight = actualRootHeight - root2CanvasHMargin
rootWinresolution = str(rootWinwidth)+'x'+str(actualRootHeight)+'+'+'0'+'+'+'0'
root.geometry(rootWinresolution)
# Sub routine to write back the config file.
def writeBack(self):
fr = open("bt_top.param.config",'w')
for k,v in updatedParamList.items():
print(k,v)
fr.write(k)
fr.write(" ")
fr.write(v)
fr.write("\n")
fr.close()
# Main Function
# Define Window geometry and other top level stuff here
# Do not go into widget coding here
def main():
global fname
# Get File name from command line argument
fname = sys.argv[2]
app = guiList(root)
root.mainloop()
# The __name__ variable decides what to run
# Below lines make this file run stand-alone
if __name__ == '__main__':
Any suggestions are welcome. Thanks
-Vinay
The piece of black is the background of self, your guiList class. Add a line self.config(bg="steel blue") to its __init__() function (or to initUI() I suppose) to fix it.

Resources