Getting a list variable out of Tkinter window - python-3.x

I am trying to get a list out of Tkinter and I want to add a Y-axis scroll bar to the list box but don't know-how. My code is as follows:
window = Tk()
window.title('Select Multiple Industries')
window.geometry('400x800')
def showindowelected():
industries = []
iname = lb.curselection()
for i in iname:
op = lb.get(i)
industries.append(op)
print (industries)
window.destroy()
#for val in industries:
#print(val)
show = Label(window, text = "Select Multiple Industries", font = ("Times", 14), padx = 10, pady = 10)
show.pack()
lb = Listbox(window, selectmode = "multiple")
lb.pack(padx = 10, pady = 10, expand = YES, fill = "both")
x = ["Brewing","Papermills","Cheese Manufacturing","Steel Mill", "Salt Making"]
for item in range(len(x)):
lb.insert(END, x[item])
lb.itemconfig(item, bg = "whitesmoke" if item % 2 == 0 else "silver")
Button(window, text=" Select > ", command=showindowelected, bg='green', fg='white').pack()
window.mainloop()
Once the window is destroyed, I want the selected variables stored in a list.

Related

Tkinter How to make listbox appear over a frame

making an F1 application where users can type in a driver from the current grid [supported via autofill/suggestions], and then API fetches relevant stats
The issue I'm having is that I want the listbox to appear over another frame (called left_frame). However, what this does is that the listbox goes under left_frame , and not over it. Any thoughts of how to make it appear over the frame?
some approaches that I tried:
used .lift(), but .lift() only seems to work when it's relative to objects in the same frame
since I currently use .grid and placed the listbox in the root frame, I initially tried to put it in top_frame, but it then expands the top_frame. Since I have positioned all frames using .place(), I don't think I can use propagate(False) (I tried it , didn't work)
Here's a picture of the issues
Here's my code so far:
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
#set up main window components
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#since same directory, can just use filename
root.iconbitmap("formula1_logo.ico")
#images
#creating canvas for image to go into
#canvas_f1_logo = Canvas(top_frame, width = 5, height = 5)
#canvas.grid(row = 0, column = 1)
#acquire image
#formula1_logo = ImageTk.PhotoImage(Image.open("formula1_logo.png"))
#resize image
#resized_formula1_logo = formula1_logo.resize((3,3), Image.ANTIALIAS)
#new_formula1_logo = ImageTK.PhotoImage(resized_formula1_logo)
#canvas.create_image(5,5, anchor = NW, image = new_formula1_logo)
#functions
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#set up frames [main frames, can put frames within frames if needed]
#frame for search bar + magnifying glass
top_frame = LabelFrame(root, padx = 80, pady = 15)
top_frame.place(relx = 0.5, rely = 0.2, anchor = CENTER)
header_label = Label(top_frame, text = "F1 2022 Drivers App", pady = 20, font = ("Arial bold",14))
header_label.grid(row = 0, column = 0, pady = 2 )
search_button = Button(top_frame, text = "search", padx = 2, pady = 2)
search_button.grid(row = 1, column = 1)
# Update the Entry widget with the selected item in list
def check(e):
v= entry.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry.delete(0,END)
entry.insert(0,menu.get(menu.curselection()))
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
# Create an Entry widget
entry= Entry(top_frame)
entry.grid(row = 1, column = 0)
entry.bind('<KeyRelease>',check)
# Create a Listbox widget to display the list of items
menu= Listbox(root)
menu.grid(row = 2, column = 0, padx = 165, pady = 165)
menu.bind("<<ListboxSelect>>",fillout)
menu.lift()
# Add values to our combobox
hide_button(menu)
left_frame = LabelFrame(root, padx = 30, pady = 30)
left_frame.place(relx = 0.24, rely = 0.5, anchor = CENTER)
bottom_left_frame = LabelFrame(root, padx = 30, pady = 30)
bottom_left_frame.place(relx = 0.24, rely = 0.82, anchor = CENTER)
bottom_right_frame = LabelFrame(root, padx = 30, pady = 30)
bottom_right_frame.place(relx = 0.6, rely = 0.82)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0, pady = 3)
full_name = Label(left_frame, text = "Full Name : ")
full_name.grid(row = 1, column = 0, pady = 2)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, pady = 2)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, pady = 2)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0, pady = 3)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, pady = 2)
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, pady = 2)
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 3, column = 0 , pady = 2)
F1_22_stats = Label(bottom_right_frame, text = "F1 22 Stats", font = ("Arial bold",14))
F1_22_stats.grid(row = 0, column = 0, pady = 3)
root.mainloop()
would appreciate the help!

Print from Tk Listbox on selection

I am able to select items from my list but once I click the item I am not able to print the contents back to the terminal. I am also trying to figure out how to close the prompt once the user makes a selection. Any help would be greatly appreciated.
window.title('UTC Time Selection')
# for scrolling vertically
yscrollbar = Scrollbar(window)
yscrollbar.pack(side = RIGHT, fill = Y)
label = Label(window,
text = "Select the UTC Time for Scanning to Start : ",
font = ("Times New Roman", 12),
padx = 10, pady = 10)
label.pack()
list = Listbox(window, selectmode = "single",
yscrollcommand = yscrollbar.set)
# Widget expands horizontally and
# vertically by assigning both to
# fill option
list.pack(padx = 10, pady = 10,
expand = YES, fill = "both")
x =["0000", "0100", "0200", "0300", "0400",
"0500", "0600", "0700", "0800", "0900",
"1000", "1100", "1200", "1300", "1400",
"1500", "1600", "1700", "1800", "1900",
"2000", "2100", "2200", "2300"]
for each_item in range(len(x)):
list.insert(END, x[each_item])
list.itemconfig(each_item, bg = "white")
# Attach listbox to vertical scrollbar
yscrollbar.config(command = list.yview)
Button(window, text="Save & Exit", command=window.destroy).pack()
window.mainloop()
the_response = list.get(list.curselection())
print (the_response)

How to set a default cursor selection in a Listbox py3

this is my code, and it works fine When the program starts there is no selection in the listbox and I want to set a default selection in the listbox, for the case when a selection is not made by the user. any help, please!
### frame_3 widgets.
frame_3 = Frame(frame_2)
label_1a = Label(frame_3, relief = 'solid', width = 17)
label_1a.configure(text = "Start of Period month")
### listbow_1 and static attributes.
listbox_1 = Listbox(frame_3, exportselection=0, width = 12, height = 12)
for item in ['January','Febuary','March',
'April','May','June',
'July','August','September',
'October','November','December']:
listbox_1.insert(END,item)
label_2a = Label(frame_3, relief = 'groove', width = 10)
label_2a.configure(text = "Start day")
entry_1 = Entry(frame_3, width = 2)
### geometry frame_3
label_1a.grid (column = 0, row = 2)
frame_3.grid (column = 0, row = 2)
listbox_1.grid(column = 0, row = 3)
label_2a.grid (column = 0, row = 5)
entry_1.grid (column = 1, row = 5)
You can use listbox.selection_set(0) to select first item on list
More in documentation: Listbox.selection_set
Full example
import tkinter as tk
def test():
# here you can get selected element
print('previous:', listbox.get('active'))
print(' current:', listbox.get(listbox.curselection()))
# --- main ---
root = tk.Tk()
listbox = tk.Listbox(root)
listbox.pack()
listbox.insert(1, 'Hello 1')
listbox.insert(2, 'Hello 2')
listbox.insert(3, 'Hello 3')
listbox.insert(4, 'Hello 4')
listbox.selection_set(0)
button = tk.Button(root, text="Test", command=test)
button.pack()

How to change background color in ttk python

I've made a simple gui age converter app but i want to change its bg color to black.
The problem is in the ttk frame.i don't know how to configure its bg color.
I have tried different methods but that didn't work.
i would be grateful if you guys could help.
here is the code
from tkinter import *
from tkinter import ttk
from PIL import Image
def calculate(*args):
try:
age_sec = int(age.get())
age_sec = age_sec * 12 * 365 * 24 * 60 * 60
age_seconds.set(age_sec)
except:
age_seconds.set('Either the field is empty or \n value is not numeric.')
root = Tk()
root.title("Converter")
root.configure(background="black")
mainframe = ttk.Frame(root, padding = "6 6 12 12")
mainframe.grid(column = 0, row = 0, sticky = (N, W, E, S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
#mainframe['borderwidth'] = 2
#mainframe['relief'] = 'groove'
age = StringVar()
age_seconds = StringVar()
ttk.Label(mainframe, foreground = "#4D4E4F", text = "Enter your Age: ").grid(column = 1, row = 1, sticky = E)
age_entry = ttk.Entry(mainframe, width = 30, textvariable = age)
age_entry.grid(column = 2, row = 1, sticky = (W, E))
ttk.Label(mainframe, foreground = "#4D4E4F", text = "your age in seconds is ").grid(column = 1, row = 2, sticky = (E))
ttk.Label(mainframe, textvariable = age_seconds, background = "lightyellow", foreground = "#727475", width = 30).grid(column = 2, row = 2, sticky = W)
#Mouse Events...\\
butt_image = PhotoImage(file = 'images.gif')
ttk.Button(mainframe, compound = TOP, text = "Hit Now", image =butt_image, cursor = "hand2", width= 30, command = calculate).grid(column = 2, row = 4, sticky = W)
l2 = ttk.Label(mainframe,foreground = "#4D4E4F", text = "Mouse Events: ").grid(column = 1, row = 3, sticky = E)
l = ttk.Label(mainframe,background = "lightyellow", foreground = "#727475", text = 'Measurement is starting...', width = 30)
l.grid(column = 2, row = 3, sticky = W)
l.bind('<Enter>', lambda e: l.configure(text = 'Moved Mouse Inside'))
l.bind('<Leave>', lambda e: l.configure(text = 'Mouse Moved Out'))
l.bind('<1>', lambda e: l.configure(text = 'left Mouse clicked'))
l.bind('<Double-1>', lambda e: l.configure(text = 'Double clicked'))
l.bind('<B1-Motion>', lambda e: l.configure(text = 'Left button drag to %d, %d' %(e.x, e.y)))
image = PhotoImage(file = 'waves.gif')
ttk.Label(mainframe, compound = CENTER, text = "Image text", font = ('roman', 9, 'normal'), foreground ='green', image = image).grid(column = 3, row = 1, sticky = (N, E))
#if '__name__' == '__main__':
for child in mainframe.winfo_children(): child.grid_configure(padx = 15, pady = 15)
age_entry.focus()
root.bind('<Return>', calculate)
root.mainloop()
A ttk.Frame does not have a background / bg option. To change it you need to use style.
See ttk.Frame Info
If you don't really need to use a ttk.Frame you can just switch to a tkinter.Frame

updating tkinter window for text background changes

Trying to show a green or red background in the text field of the answer to the simple addition quizzer.
Currently in PyCHarm complains that:
Entry.grid_configure(background = "red")
TypeError: grid_configure() missing 1 required positional argument: 'self'
0
I can't seem to figure this out. Any help is appreciated.
Here's the code so far:
from tkinter import *
import random
class MainGUI:
def __init__(self):
window = Tk() # Create the window
window.title("Addition Quizzer") # Set the title
#window.width(len(window.title()))
self.number1 = random.randint(0, 9)
self.number2 = random.randint(0, 9)
Label(window, text = "+").grid(row = 2, column = 1, sticky = E)
Label(window, text = "Answer").grid(row = 3, column = 1, sticky = W)
self.firstNumber = StringVar()
Label(window, text = self.number1, justify = RIGHT).grid(row = 1, column = 2)
self.secondNumber = StringVar()
Label(window, text = self.number2, justify = RIGHT).grid(row = 2, column = 2)
self.entry = StringVar()
Entry(window, textvariable = self.entry, justify = CENTER, width = 4, background = "grey").grid(row = 3, column = 2)
Button(window, text = "Answer:", command = self.computeAnswer).grid(row = 4, column = 1, sticky = E)
self.result = StringVar()
Label(window, textvariable = self.result).grid(row = 4, column = 2)
window.mainloop() # Create the event loop
def computeAnswer(self):
self.result.set(format(self.number1 + self.number2))
if self.entry == self.result:
self.displayCorrect()
else:
self.displayIncorrect()
def displayCorrect(self):
# self.correctAnswer = "Correct"
# Label(self.window, text = self.correctAnswer, background = "green", justify = RIGHT).grid(row = 5, column = 2)
Entry.grid_configure(background = "green")
def displayIncorrect(self):
# self.incorrectAnswer = "Incorrect"
# Label(self.window, text = self.incorrectAnswer, background = "red", justify = RIGHT).grid(row = 5, column = 2)
Entry.grid_configure(background = "red")
MainGUI()
If you had read and followed this in the Help Center material, you would have reduced your code to the following, which still gets the same error message.
from tkinter import *
Entry.grid_configure()
The message refers to the fact that Python instance methods require an instance. This is usually done by calling the method on an instance instead of the class. Otherwise, an instance must be given as the first argument. Consider
mylist = []
mylist.append(1)
list.append(mylist, 2)
print(mylist)
# [1, 2]
You need to save a reference to your Entry box. Change
Entry(window, ..., background = "grey").grid(...)
to
self.entry = Entry(window, ..., background = "grey").grid(...)
I do not know if calling .grid_configure(background=color will do what you want.
This will, I am sure.
self.entry['background'] = 'red'

Resources