Cannot print array elements in listbox using tkinter - python-3.x

I'm trying to print array elements in console and in listbox (using tKinter), when a button is clicked. The elements are being printed on console, but not in the GUI. Below is the code.
from tkinter import *
from tkinter.ttk import *
from dbprocessor import DbProcessor
window = Tk()
window.title("Welcome To Pin Finder")
lbl = Label(window, text="Search for PCBa_Cards", font=("Arial Bold", 8))
lbl.grid(column=0, row=1)
search = Entry(window, width=20)
search.focus()
search.grid(column=0, row=4)
listbox = Listbox(window)
dp = DbProcessor()
def clicked():
res = "WELCOME " + search.get()
lbl.configure(text=res)
records = dp.connectandread(search.get())
for row in records:
print(str(row))
listbox.insert(END, str(row))
# lbl.configure(text=str(records))
#listbox.pack(fill=BOTH, expand=YES)
lbl.grid(column=1, row=5)
btn = Button(window, text="Search", command=clicked)
btn.grid(column=1, row=4)
window.mainloop()
I can see the array elements in the console, but not in the listbox. How can I fix this?

You never add the listbox to the display. You need to call the grid method of listbox.

Related

Tkinter dialog's elements position

I am building custom Tkinter dialog window with Entry and Combobox. I am stuck with placing text and enter frames. Currently I am placing them manually. I am looking for the way to let tkinter do it automatically (maybe with pack() method). And also configure TopLevel size automatically.
My code:
def ask_unit_len():
values = ['millimeters', 'micrometers', 'nanometers']
top = Toplevel()
top.geometry('170x100')
top.resizable(False, False)
top.focus_set()
top.grab_set()
top.title('Enter length and units')
label_length = Label(top, text='Length:')
label_length.place(x=0, y=0)
units_type = StringVar()
length = StringVar()
answer_entry = Entry(top, textvariable=length, width=10)
answer_entry.place(x=55, y=0)
label_units = Label(top, text='Units:')
label_units.place(x=0, y=30)
combo = Combobox(top, width=10, textvariable=units_type,
values=values)
combo.place(x=50, y=30)
button = Button(top, text='Enter',
command=lambda:
mb.showwarning("Warning",
"Enter all parameters correctly")
if (units_type.get() == "" or not length.get().isdigit()
or int(length.get()) <= 0)
else top.destroy())
button.place(x=65, y=70)
top.wait_window(top)
return int(length.get()), units_type.get()
So, is there any way to perform this?

How to get input from tkinter Entry widget on second window while the first window continues to run

from tkinter import *
def first():
root1 = Tk()
Button(root1, text = 'get Second', command= second).pack()
root1.mainloop()
def second():
root2 = Tk()
user_input = StringVar()
Entry(root2, text = user_input).pack()
Button(root2, text = 'submit', command = lambda : print(user_input.get(), '\t printed')).pack()
root2.mainloop()
first()
You are making a few basic mistakes in here -
You if want to use a second window, it should be Toplevel not root Tk window. There should be only one root window in the program. This should act as parent to all the windows.
Its a good practice in most of the cases to define the widgets like Button, Entry separately and then pack() them.
Entry should have 'textvariable' not 'text'
Following is the updated code which may help you -
from tkinter import *
root = Tk()
def first():
button = Button(root, text = 'get Second', command= second)
button.pack()
root.mainloop()
def second():
window2 = Toplevel(root)
user_input = StringVar()
entry = Entry(window2, textvariable=user_input)
entry.pack()
button = Button(window2, text = 'submit', command = lambda: print(user_input.get()))
button.pack()
first()

Extracting string variable from tkinter curselection

Quick question :
I run a TKinter prompt on Python 3.6 and I would like to create a variable from the curselection function inside my listbox. I would like to keep the string of that variable so that I could use it later for naming other variables for instance.
Here's my code :
#Extracting municipalities from shapefile
MunList = []
MunMap = arcpy.env.workspace +'\munic_s.shp'
cursor = arcpy.SearchCursor(MunMap)
for row in cursor:
MunVar = row.getValue("munic_s_24")
MunList.append(MunVar)
del cursor
MunList = sorted(MunList)
print(MunList)
def test(event=None):
#print(listbox.get(ACTIVE))
print(listbox.get(listbox.curselection()))
root = Tk()
root.title("Scrolldown Menu")
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(root, selectmode=SINGLE)
for lines in MunList:
listbox.insert(END, lines)
listbox.pack(side=LEFT,fill=BOTH)
listbox.config(yscrollcommand=scrollbar.set)
listbox.config(borderwidth=3, exportselection=0, height=20, width=50)
print(listbox.bbox(0))
(listbox.bind("<Double-Button-1>", test))
scrollbar.config(command=listbox.yview)
mainloop()
I create a 'test' function that selects the ACTIVE item on my cursor and bind it to my listbox with a double-click. When I run it and double-click any name in my list, it prints it. However, I can't seem to be able to make a string variable out of it. When I try something like this :
test_var = (listbox.bind("<Double-Button-1>", test))
print(test_var)
I get some sort of index :
257891528test
But I need the actual string of the variable (example : Washington)
Thanks!
In case anyone has the same question, I found the answer :
root = Tk()
root.title("TEST_TK_Scroll menu")
# Add a grid
mainframe = Frame(root)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
mainframe.pack(pady=100, padx=100)
def close_window ():
root.destroy()
button = Button (text= 'Confirm selection', command=close_window)
button.pack()
sel=[]
def selection(event):
selected = (listbox.get(listbox.curselection()))
print(selected)
sel.append(selected)
scrollbar = Scrollbar(mainframe)
scrollbar.pack(side=RIGHT, fill=Y)
listbox = Listbox(mainframe, selectmode=SINGLE)
for lines in MunList:
listbox.insert(END, lines)
listbox.pack(side=LEFT,fill=BOTH)
listbox.config(yscrollcommand=scrollbar.set)
listbox.config(borderwidth=3, exportselection=0, height=20, width=50)
#cur1 = listbox.get(selected)
#index1 = listbox.get(0, "end").index(cur1)
(listbox.bind("<Double-Button-1>", selection))
print(listbox.bbox(0))
root.mainloop()
print('answer :')
print(sel)
def attempt2(string):
for v in ("[", "]", "'"):
string = string.replace(v, "")
return string
select=sel[0]
attempt2(select)
print(select)

Dynamic Form Widget interaction in python tkinter

I am trying to generate a blank GUI, with 1 menu Item.
I then use a function to generate a label, a button and an entry widget on the same form when the selection is made from the menu item.
However when I try to use the get() method to get the value of the input in the generated textbox, I get an error. I may have missed some core concept here and this may not be possible, but I would like to know. Following is my code,
from tkinter import Tk, Label, Button, Entry, Menu
def btn_clientadd():
print(txt1.get())
def addclient():
lbl1 = Label(window, text="Client Name :")
lbl1.grid(row=1,column=1,padx=7,pady=7,sticky='e')
txt1 = Entry(window)
txt1.grid(row=1, column=2)
txt1.focus()
btn = Button(window, text="Add Client", command=btn_clientadd)
btn.grid(row=2,column=2,padx=7,pady=7)
window = Tk()
window.geometry('400x200')
menu = Menu(window)
new_item1 = Menu(menu)
menu.add_cascade(label='ClientMaster', menu=new_item1)
new_item1.add_command(label='Add New Client', command=addclient)
window.config(menu=menu)
window.mainloop()
The entry txt1 is created inside a function and the reference to it is garbage collected when the function ends. One way you can get around this it to declare a StringVar() in the global scope and then associate it to the entry.
Examine the example below:
from tkinter import Tk, Label, Button, Entry, Menu, StringVar
def btn_clientadd():
print(client_string.get()) # Get contents of StringVar
def addclient():
lbl1 = Label(window, text="Client Name :")
lbl1.grid(row=1,column=1,padx=7,pady=7,sticky='e')
# Create entry and associate it with a textvariable
txt1 = Entry(window, textvariable=client_string)
txt1.grid(row=1, column=2)
txt1.focus()
btn = Button(window, text="Add Client", command=btn_clientadd)
btn.grid(row=2,column=2,padx=7,pady=7)
window = Tk()
window.geometry('400x200')
menu = Menu(window)
new_item1 = Menu(menu)
menu.add_cascade(label='ClientMaster', menu=new_item1)
new_item1.add_command(label='Add New Client', command=addclient)
window.config(menu=menu)
client_string = StringVar() # StringVar to associate with entry
window.mainloop()

How to get these tkinter scrollbars working?

Hi cant get these scrollbars working even though this code comes from a very advanced user on this site I have tried everything. No errors they just dont show up
import tkinter as tk
#Make Window
root = tk.Tk()
root.geometry("612x417")
root.title("Exchange Rates")
root.resizable(0,0)
root.configure(background='lightgrey')
#End
#Create listboxes for currency selection
listbox1 = tk.Listbox(root, font="Helvetica 11 bold", height=3, width=10)
listbox2 = tk.Listbox(root, font="Helvetica 11 bold", height=3, width=10)
#Try to create a scroll bar
scrollbar1 = tk.Scrollbar(root, orient="vertical", command=listbox1.yview)
listbox1.configure(yscrollcommand=scrollbar1.set)
scrollbar2 = tk.Scrollbar(root, orient="vertical", command=listbox2.yview)
listbox2.configure(yscrollcommand=scrollbar2.set)
listbox1.place(x=300,y=50)
listbox2.place(x=300,y=125)
scrollbar3 = Scrollbar(root)
scrollbar3.pack(side="right", fill="y")
listbox = Listbox(root, yscrollcommand=scrollbar3.set)
listbox.pack()
scrollbar3.config(command=listbox.yview)
root.mainloop()
I don't know how you managed to run it without an error because you imported tkinter as tk but for listbox you put Listbox (not tk.Listbox) or for scrollbar3 you put Scrollbar (not tk.Scrollbar). Also they don't show up because you haven't packed/placed them! And... you have to use either place, pack or grid you can't use them together. You used .place() for your listbox1 and 2 but then you used .pack() for your scrollbar3 and listbox. Whatever you use first (here it's place) will work but the others just simply won't show up.
The below script should hopefully show you how Scrollbars work in a clear and concise way and how they are affected by the number of items entered into a listbox
from tkinter import *
class App:
def __init__(self, master):
self.master = master
self.top = Toplevel(self.master)
self.frame = Frame(self.top)
self.entry = Entry(self.master)
self.button = Button(self.master, text="Ok", command=self.command)
self.entry.pack()
self.button.pack()
self.top.withdraw()
self.frame.pack()
def command(self):
self.frame.destroy()
self.frame = Frame(self.top)
self.listbox = Listbox(self.frame)
self.scroll = Scrollbar(self.frame, orient="vertical", command=self.listbox.yview)
self.listbox.configure(yscrollcommand=self.scroll.set)
for i in range(int(self.entry.get())):
self.listbox.insert(END, "Col"+str(i))
self.frame.pack()
self.listbox.pack(side="left")
self.scroll.pack(side="left", expand=True, fill=Y)
self.top.deiconify()
root = Tk()
app = App(root)
root.mainloop()
Also please take into account that in order for us to review a problem and help you work through it, we need to be able to run and review the code in an easy and digestible fashion.
Hello people answering my own question, here is a working Listbox within a Frame with a Scrollbar.
import tkinter as tk
#Make Window
root = tk.Tk()
root.geometry("612x417")
root.title("Exchange Rates")
root.resizable(0,0)
root.configure(background='lightgrey')
#End
#Try to create a listbox with a scroll bar within a frame
#Create elements
frame = tk.Frame(root, bd=1, relief='sunken', width=150, height=300)
scrollbar = tk.Scrollbar(frame)
listbox = tk.Listbox(frame)
#Attach listbox to scrollbar
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)
#Poulate listbox
for i in range(100):
listbox.insert('end', i)
#Pack elements
frame.pack(side='top')
scrollbar.pack(side='right', fill='y')
listbox.pack()
root.mainloop()

Resources