I'm currently trying to make a Listbox with a Scroll bar on the side appear on my Tkinter Window. I can't figure out how to make the Scrollbar size the same size as my listbox. Heres my code:
global R3
global lb
R3 = Tk()
gg = "white"
g = "blue"
R3.geometry('720x720')
R3.title(username + " Dropbox")
R3.resizable(width=False, height=False)
logoutbt = Button(R3, text="Logout", width=10, height=2, bg=g, fg=gg, font="5", relief=RAISED, overrelief=RIDGE, command=rectologout)
upload = Button(R3, text="Upload", width=10, height=2, bg=g, fg=gg, font="5", relief=RAISED, overrelief=RIDGE, command=rectoupload)
logoutbt.place(x=220, y=500)
upload.place(x=480, y=500)
button1 = Button(R3, text='Receive file', width=10, height=2, bg=g, fg=gg, font="5", relief=RAISED, overrelief=RIDGE,command = get_file)
lb = Listbox(R3, height=6,width = 15)
s.send("RETREIVEA-"+username)
file_list = s.recv(1024).split("-")
if file_list == [""]:
button1.config(state = DISABLED)
for file in file_list:
lb.insert("end", file)
yscroll = Scrollbar(R3, orient=VERTICAL)
lb['yscrollcommand'] = yscroll.set
yscroll['command'] = lb.yview
lb.place(x=280,y=200)
yscroll.place(x=370,y=200)
button1.place(x=400, y=200)
R3.mainloop()
Any suggestions on how to do it?
First of all, please read how to create a Minimal, Complete and Verifiable example.
Your code lacks imports and references non-initialized objects / variables / functions.
How to achieve what you want?
Either use grid instead of place or pass height parameters to lb.place(..., height=<whatever you want>) and yscroll.place(..., height=<whatever you want>)
Related
I am attempting to create a GUI that allows for users to copy and paste data straight into the interface. There will be three columns and anywhere between 1 - 500 rows with the possibility of 3,000+ The raw text will come via email, word, PDF, or excel so I need the user input field to be similar to excel in that you can copy/paste more than 1 line at a time.
I have followed a couple YouTube guides on creating tables/grids with tkinter however I cannot figure out a way to allow text entry via copy/paste.
One of the only ways I found to make tables with tkinter since tktable isn't a part of it is the following example. This still does not allow for user input via copy/paste.
class Table:
def __init__(self,root):
# code for creating table
for i in range(total_rows):
for j in range(total_columns):
self.e = Entry(root, width=20, fg='blue',
font=('Arial',16,'bold'))
self.e.grid(row=i, column=j)
self.e.insert(END, lst[i][j])
# take the data
lst = [(1,'Raj','Mumbai',19),
(2,'Aaryan','Pune',18),
(3,'Vaishnavi','Mumbai',20),
(4,'Rachna','Mumbai',21),
(5,'Shubham','Delhi',21)]
# find total number of rows and
# columns in list
total_rows = len(lst)
total_columns = len(lst[0])
# create root window
root = Tk()
t = Table(root)
root.mainloop()
Can anyone suggest an alternative to tkinter or point me in the direction of a guide for this type of user input?
I finally figured out why I couldn't get python to allow me to use tkinter and was able to do what I was trying to do, more or less.
import tkinter as tk
from tkinter import *
from tkinter import BOTH, END, LEFT
HEIGHT = 970
WIDTH = 1500
root = tk.Tk()
root.title( 'Daves Generator')
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
background_image = tk.PhotoImage(file='david.png')
background_label = tk.Label(root, image=background_image)
background_label.place(relwidth=1, relheight=1)
frame_one = tk.Frame(root, bg='#003d70',bd=5)
frame_one.place(relx=0.17, rely=.15, relwidth=0.3,relheight=0.8, anchor='n')
customer_description = tk.Text(frame_one, state=NORMAL, width=125, wrap=WORD, height=500,font=("Courier", 8))
customer_description.place(relwidth=1, relheight=1)
frame_two = tk.Frame(root, bg='#003d70',bd=5)
frame_two.place(relx=0.5, rely=.15, relwidth=0.3,relheight=0.8, anchor='n')
dave_description = tk.Text(frame_two, width=125, height=500,font=("Courier", 8))
dave_description.place(relwidth=1, relheight=1)
frame_three = tk.Frame(root, bg='#003d70',bd=5)
frame_three.place(relx=0.83, rely=.15, relwidth=0.3,relheight=0.8, anchor='n')
sap_code = tk.Label(frame_three, width=125, height=500,font=("Courier", 8))
sap_code.place(relwidth=1, relheight=1)
header_frame_one = tk.Label(root, text="Customer Descriptions", font=("Courier", 14), fg='#003d70')
header_frame_one.place(relx=0.17, rely=0.13, relwidth=0.2, relheight=0.025, anchor='n')
header_frame_two = tk.Label(root, text="PJ Descriptions", font=("Courier", 14), fg='#003d70')
header_frame_two.place(relx=0.5, rely=0.13, relwidth=0.2, relheight=0.025, anchor='n')
header_frame_three = tk.Label(root, text="SAP Code", font=("Courier", 14), fg='#003d70')
header_frame_three.place(relx=0.83, rely=0.13, relwidth=0.2, relheight=0.025, anchor='n')
generate_button = tk.Button(root,text="Generate!", font=("Courier", 14), fg='white', bg='#003d70', command=lambda: get_customer_description())
generate_button.place(relx=0.5, rely=0.08, relwidth=0.15, relheight=0.025, anchor='n')
In my tkinter program I'm collecting text from the user using Text widget, this is later printed on the screen using a label widget. Although I'm able to print it onto the screen, the text is all center aligned. Since what I'm collecting is a procedure for something it gets difficult to read, so I need it to be left aligned.
This is my Procedure method -
Once the procedure is collected it is stored into a dictionary
def Procedure(self):
textfield = Text(gui, height=30, width=82)
textfield.place(x="20", y="100")
procedure_label = LabelWidget(self.screen, "Procedure", "Courier", 40)
procedure_label.Call().place(x="220", y="20")
button_save = Button(gui, text="Next", padx="50", pady="20", bg="lightgrey",
command=partial(self.CheckPage, 4, procedure=textfield))
button_save.place(x="250", y="600")
This is how I'm printing my proceudre
proc_text_label = ""
for i in fullDictProc:
proc_text_label_temp = Label(root, text=i, wraplength=900)
proc_text_label = proc_text_label_temp
proc_text_label.config(font=("Courier", 12))
proc_text_label.place(x=70, y=250)
Here is a minimal reproducible code to demonstrate the problem
Run it and see the alignment of the text.
from tkinter import *
from functools import partial
gui = Tk()
gui.geometry("700x700")
def printit(textfield):
procedure_list = [textfield.get("1.0", "end-1c")]
textfield.place_forget()
proc_text_label = ""
for i in procedure_list:
proc_text_label_temp = Label(gui, text=i, wraplength=900)
proc_text_label = proc_text_label_temp
proc_text_label.config(font=("Courier", 12))
proc_text_label.place(x=70, y=250)
textfield = Text(gui, height=30, width=82)
textfield.place(x="20", y="100")
button_save = Button(gui, text="Next", padx="50", pady="20", bg="lightgrey",
command=partial(printit, textfield))
button_save.place(x=500, y=600)
gui.mainloop()
I think what you are looking for might be justify:
proc_text_label.config(justify='left')
Have a look at The Tkinter Label Widget
I think what you're looking for is the anchor parameter.
This is how it worked with your minimal example:
from tkinter import *
from functools import partial
gui = Tk()
gui.geometry("700x700")
def printit(textfield):
procedure_list = [textfield.get("1.0", "end-1c")]
textfield.place_forget()
proc_text_label = ""
for i in procedure_list:
proc_text_label_temp = Label(gui, text=i, wraplength=900,
anchor='w',
bg='blue',
width=50)
proc_text_label = proc_text_label_temp
proc_text_label.config(font=("Courier", 12))
proc_text_label.place(x=70, y=250)
textfield = Text(gui, height=30, width=82)
textfield.place(x="20", y="100")
button_save = Button(gui, text="Next", padx="50", pady="20", bg="lightgrey",
command=partial(printit, textfield))
button_save.place(x=500, y=600)
gui.mainloop()
I am trying to create a side menubar and use multiple labels as click buttons. But when I execute the program, only one label is clicked and event is shown in mainarea. Other event doesn't work.
Please provide me with a useful solution. Here is the code I have written:
from Tkinter import *
import ttk
root = Tk()
def MainScreen(self):
label4 = Label(mainarea,width=100,height=80,text="Prapti Computer
Solutions")
label4.pack(expand=True,fill='both')
def ClientData(self):
label4 = Label(mainarea,width=100,height=80,text="Yo this is client data")
label4.pack(expand=True,fill='both')
def Report(self):
label6 = Label(mainarea,width=100,height=80,text="Report is onnnnn!")
label6.pack(expand=True,fill='both')
# sidebar
sidebar = Frame(root, width=400, bg='white', height=500, borderwidth=2)
sidebar.pack( fill='y', side='left', anchor='nw')
#submenus
label1 = Label( sidebar,width=45,height = 2 , text="HOME", relief=FLAT )
label1.bind("<Button-1>",MainScreen)
label1.grid(row=0)
ttk.Separator(sidebar,orient=HORIZONTAL).grid(row=1, columnspan=5)
label2 = Label( sidebar,width=45,height = 2 , text="CLIENT", relief=FLAT )
label2.bind("<Button-1>",ClientData)
label2.grid(row=2)
ttk.Separator(sidebar,orient=HORIZONTAL).grid(row=3, columnspan=5)
label3 = Label( sidebar,width=45,height = 2 , text="REPORT", relief=FLAT )
label3.bind("<Button-1>",Report)
label3.grid(row=4)
# main content area
mainarea = Frame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')
root.attributes('-alpha', 0.98)
root.mainloop()
Thank you.
You keep packing things but you never remove them. You need to remove the current page before switching to the new page.
For example:
current_page = None
def MainScreen(self):
global current_page
if current_page is not None:
current_page.pack_forget()
label4 = Label(mainarea,width=100,height=80,text="Prapti Computer Solutions")
label4.pack(expand=True,fill='both')
current_page = label4
l would like to create a control system for administrator on Tkinter and some functions (add, delete, update and load) are main part of control system but when l run the code , these functions do not work and there is no error message. But ,l could not figure out where the problem is. My code is still not completed yet. İf l solve it, then l will move to another step.
import tkinter
from tkinter import *
userlist = [
['Meyers', '12356'],
['Smith','abcde'],
['Jones','123abc34'],
['Barnhart','12//348'],
['Nelson','1234'],
["Prefect",'1345'],
["Zigler",'8910'],
['Smith','1298']]
def domain():
def whichSelected () :
print ("At %s of %d" % (select.curselection(), len(userlist)))
return int(select.curselection()[0])
def addEntry():
userlist.append ([nameVar.get(), passwordVar.get()])
setSelect()
def updateEntry():
userlist[whichSelected()] = [nameVar.get(), passwordVar.get()]
setSelect()
def deleteEntry():
del userlist[whichSelected()]
setSelect()
def loadEntry():
name, password = userlist[whichSelected()]
nameVar.set(name)
passwordVar.set(password)
def makeWindow():
win=Tk()
global nameVar, passwordVar, select
frame1 = Frame(win)
frame1.pack()
Label(frame1, text="Name").grid(row=0, column=0, sticky=W)
nameVar = StringVar()
name = Entry(frame1, textvariable=nameVar)
name.grid(row=0, column=1, sticky=W)
Label(frame1, text="Password").grid(row=1, column=0, sticky=W)
passwordVar= StringVar()
password= Entry(frame1, textvariable=passwordVar)
password.grid(row=1, column=1, sticky=W)
frame2 = Frame(win) # Row of buttons
frame2.pack()
b1 = Button(frame2,text=" Add ",command=addEntry)
b2 = Button(frame2,text="Update",command=updateEntry)
b3 = Button(frame2,text="Delete",command=deleteEntry)
b4 = Button(frame2,text=" Load ",command=loadEntry)
b1.pack(side=LEFT); b2.pack(side=LEFT)
b3.pack(side=LEFT); b4.pack(side=LEFT)
frame3 = Frame(win) # select of names
frame3.pack()
scroll = Scrollbar(frame3, orient=VERTICAL)
select = Listbox(frame3, yscrollcommand=scroll.set, height=6)
scroll.config (command=select.yview)
scroll.pack(side=RIGHT, fill=Y)
select.pack(side=LEFT, fill=BOTH, expand=1)
return win
def setSelect():
userlist.sort()
select.delete(0,END)
for name in userlist:
select.insert(END,name)
win=makeWindow()
setSelect()
win.mainloop()
page1=Tk()
but1=Button(page1,text="Domain",command=domain).pack()
It is bad practice to define your functions in a function and makes debugging pretty difficult. I would start by using an object to create this GUI. Object variables:
passwordVar and nameVar,
select
userlist
win
There's a lot going wrong for your code.
For instance, you don't need to import tkinter twice. Your casing of the variable names doesn't follow PEP8. You could benefit from an OOP approach.
I would suggest finding a good IDE to code in that can highlight your formatting and errors.
Take a look at the provided code:
import tkinter as tk
user_list = [
['Meyers', '12356'],
['Smith','abcde'],
['Jones','123abc34'],
['Barnhart','12//348'],
['Nelson','1234'],
["Prefect",'1345'],
["Zigler",'8910'],
['Smith','1298']]
class Domain(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.name_var = tk.StringVar()
self.password_var = tk.StringVar()
self.make_window()
def which_selected(self):
print("At %s of %d" % (self.select.curselection(), len(user_list)))
return int(self.select.curselection()[0])
def add_entry(self):
user_list.append([self.name_var.get(), self.password_var.get()])
self.set_select()
def update_entry(self):
user_list[self.which_selected()] = [
self.name_var.get(), self.password_var.get()]
self.set_select()
def delete_entry(self):
del user_list[self.which_selected()]
self.set_select()
def load_entry(self):
name, password = user_list[self.which_selected()]
self.name_var.set(name)
self.password_var.set(password)
def make_window(self):
frame1 = tk.Frame(self.parent)
frame1.pack()
tk.Label(frame1, text="Name").grid(row=0, column=0, sticky=tk.W)
name = tk.Entry(frame1, textvariable=self.name_var)
name.grid(row=0, column=1, sticky=tk.W)
tk.Label(frame1, text="Password").grid(row=1, column=0, sticky=tk.W)
password = tk.Entry(frame1, textvariable=self.password_var)
password.grid(row=1, column=1, sticky=tk.W)
frame2 = tk.Frame(self.parent) # Row of buttons
frame2.pack()
b1 = tk.Button(frame2, text=" Add ", command=self.add_entry)
b2 = tk.Button(frame2, text="Update", command=self.update_entry)
b3 = tk.Button(frame2, text="Delete", command=self.delete_entry)
b4 = tk.Button(frame2, text=" Load ", command=self.load_entry)
b1.pack(side=tk.LEFT)
b2.pack(side=tk.LEFT)
b3.pack(side=tk.LEFT)
b4.pack(side=tk.LEFT)
frame3 = tk.Frame(self.parent) # select of names
frame3.pack()
scroll = tk.Scrollbar(frame3, orient=tk.VERTICAL)
self.select = tk.Listbox(frame3, yscrollcommand=scroll.set, height=6)
scroll.config(command=self.select.yview)
scroll.pack(side=tk.RIGHT, fill=tk.Y)
self.select.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
def set_select(self):
user_list.sort()
self.select.delete(0, tk.END)
for name in user_list:
self.select.insert(tk.END, name)
if __name__ == '__main__':
root = tk.Tk()
Domain(root)
root.mainloop()
Note:
There's still errors here, but I don't exactly know what you're trying to do so I've just restructured it here so you can start on a better path.
I am getting the error mentioned in the title of the post I really just want this to work. Been working on this problem for a while now and it is frustrating. My ultimate goal is to obtain the values for the varables text, chkvar, and v.
Thanks to anyone who can reply and help on this!!
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
def killwindow():
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = ""
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
tk1 = text.get(text)
tk2 = chkvar.get(chkvar)
tk3 = v.get(v)
print tk1
print tk2
print tk3
Once mainloop exits, the widgets no longer exist. When you do text.get(text), you're trying to access a deleted widget. Tkinter simply isn't designed to allow you to access widgets after the main window has been destroyed.
The quick solution is to modify killwindow to get the values before it destroys the window, and store them in a global variable which you can access after mainloop exits.
The program didn't make it through the variable getting, so it never reported the incorrect method calls. I made a few changes to the original code (added a textval StringVar, and changed the v variable to another IntVar). I had a feeling the "associated variables" wouldn't have a problem, and didn't need to be included in the killwindow code. The only variable I grab in killwindow is the text data.
Working code (changed lines marked with #++) :
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
textval = StringVar() #++ added
def killwindow():
textval.set(text.get('1.0',END)) #++ grab contents before destruction
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = IntVar() #++ changed
v.set(1) #++ initial value
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
# windows are destroyed at this point
tk1 = textval.get() #++ changed
tk2 = chkvar.get() #++ changed
tk3 = v.get() #++ changed
print tk1
print tk2
print tk3