Python GUI with user input area similar to excel - python

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')

Related

Incomplete label in a tkinter window

i am currently making an app which displays information about NBA players using an API called data.nba.net, i am trying to display information such as a player's last affiliation, height, jersey number, etc. But at some point in the process the labels cut off and it stops showing the rest of them.
I've tried messing around with the dimensions of both the window and the canvas, but it doesn't seem to solve the problem. I am not an expert on tkinter, so i am not sure how do canvases and frames work, pls help :,).
What it should look like
What it looks like at the end
from tkinter import *
from turtle import position
from weakref import WeakSet
import nba_now
from nba_now import *
from tkinter import ttk
main_window = Tk()
main_window.geometry("420x420")
main_window.title("NBA NOW")
def players_windowP():
n = 0.030
win = Tk()
win.title('Player Info')
win.geometry("820x520")
win.resizable(False, False)
wrapper1= LabelFrame(win)
mycanvas = Canvas(wrapper1, width=800, height=520)
mycanvas.pack(side=LEFT)
yscrollbar = ttk.Scrollbar(wrapper1, orient="vertical", command= mycanvas.yview)
yscrollbar.pack(side=RIGHT, fill="y")
mycanvas.configure(yscrollcommand=yscrollbar.set)
mycanvas.bind('<Configure>', lambda e: mycanvas.configure(scrollregion = mycanvas.bbox('all')))
myframe = Frame(mycanvas)
mycanvas.create_window((0,0), window=myframe, anchor="nw")
wrapper1.pack(fill="both", expand="yes", padx=0, pady=0)
stats = get_links()['leagueRosterPlayers']
players = get(BASE_URL + stats).json()['league']['standard']
for player in players:
fname = player['firstName']
lname = player['lastName']
jersey = player['jersey']
pos = player ['pos']
height = player['heightFeet']
team = player['lastAffiliation']
data = Label(myframe, text=f"{fname} {lname} - {team}\n Number: {jersey}\n Height: {height} feet\n Position: {pos}",
font=('Arial', 25, 'bold'),
relief = RIDGE,
bd=6,
padx=0,
pady=30,
borderwidth= 5,
justify= LEFT)
data.place(relx= 0, rely= n, anchor=N)
n+= 0.45
data.pack()
players = Button(main_window, text= "Player Info",
font=('Arial', 12, 'bold'),
justify=CENTER,
state=ACTIVE,
bd=1,
command=players_windowP)
players.place(relx=0.5, rely=0.8, anchor=S)
main_window.mainloop()

How to format the text input from Text Widget in Tkinter

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()

problem with tkinter under defined function

Can you please help me with follwing issue I face:
When I am creating radiobutton with tkinter, I don't have a problem to select from the list.
However, if I put the same script under a menu, then selected option is always the default one, ("Python",1) in this specific case. Do you have any idea how to overcome this? Thanks in advance!
import tkinter as tk
root_m = tk.Tk()
root_m.geometry("400x200")
frame_m = tk.Frame(root_m)
root_m.title("NUMERIC UNIVERSE")
frame_m.pack()
def chars_merging():
languages = [
("Python",1),
("Perl",2),
("Java",3),
("C++",4),
("C",5)
]
root = tk.Tk()
root.geometry("400x200")
frame = tk.Frame(root)
root.title("SELECT SOMETHING")
frame.pack()
v = tk.IntVar()
v.set(0) # initializing the choice, i.e. Python
label = tk.Label(frame,
text="""Choose your favourite
programming language:""",
justify = tk.LEFT,
padx = 20)
label.pack()
def ShowChoice():
global data_sel
data_sel = v.get()
print(data_sel)
for val, language in enumerate(languages):
tk.Radiobutton(frame,
text=language,
indicatoron = 0,
width = 20,
padx = 20,
variable=data_sel,
command=ShowChoice,
value=val).pack(anchor=tk.W)
root.mainloop()
#return(languages[v.get()])
print("You selected", languages[v.get()])
button3 = tk.Button(frame_m,
text="3.Prepare and merge chars",
command=chars_merging,
width=25)
button3.pack()
# CLOSING THE WINDOW ---------------------------------------------------------
def finish():
root_m.destroy()
button_n = tk.Button(frame_m,
text="Finish",
command=finish,
width=25)
button_n.pack()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
root_m.mainloop()

Making a Tkinter Listbox with Scrolll

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>)

How to clear part of a tkinter Canvas and show something when submit is pressed?

I'm creating a simple madlib style game and I've come into a bit of a problem. I cannot get the canvas to clear and show the results.
The following code places an image as the background of a canvas. It then places labels and entry fields in 2 columns for all of the words to be inserted. There is a submit button at the bottom of the page. I can't figure out how to get it clear everything except the background image, so that it can display the story, with the users words inserted. If i place it in the callback(), it clears just the background and keeps everything else. I want the opposite.
from tkinter import *
from PIL import Image, ImageTk
canvas_width = 360
canvas_height = 525
file = r"C:\Users\kraak\Desktop\PyCharm Community Edition 2017.1.2\borderedpaper.GIF"
master = Tk()
canvas = Canvas(master, width=canvas_width, height=canvas_height)
old_img = PhotoImage(file=file)
new_img = old_img.subsample(3, 3)
canvas.create_image(-11, -10, anchor=NW, image=new_img)
canvas.create_window(0, 0, height=1, width=1, anchor=NW)
canvas.create_text(0, 0, text="Test")
e1 = Entry(canvas)
canvas.create_window(250, 60, window=e1, height=15, width=100)
label = Label(text="Enter an adjective.")
label.place(x=40, y=50)
e1.focus_set()
e2 = Entry(canvas)
canvas.create_window(250, 85, window=e2, height=15, width=100)
label = Label(text="Enter a nationality.")
label.place(x=40, y=75)
e2.focus_set()
def callback():
print("Pizza was invented by a " + (e1.get()) + " " + (e2.get()))
def answer():
button = Button(text="Submit.", command=callback)
button.place(x=150, y=460)
answer()
canvas.pack()
mainloop()
As Bryan Oakley suggested you can store the id's of the widgets you want to get rid of in a list to make it easier to destroy() them all in the callback() function. Here's showing the modification to your code that would do that—note the lines with a # ADDED comments.
from tkinter import *
from PIL import Image, ImageTk
canvas_width = 360
canvas_height = 525
file = r"C:\Users\kraak\Desktop\PyCharm Community Edition 2017.1.2\borderedpaper.GIF"
master = Tk()
canvas = Canvas(master, width=canvas_width, height=canvas_height)
canvas_entry_widgets = [] # ADDED
old_img = PhotoImage(file=file)
new_img = old_img.subsample(3, 3)
canvas.create_image(-11, -10, anchor=NW, image=new_img)
canvas.create_window(0, 0, height=1, width=1, anchor=NW)
canvas.create_text(0, 0, text="Test")
e1 = Entry(canvas)
canvas.create_window(250, 60, window=e1, height=15, width=100)
label = Label(text="Enter an adjective.")
label.place(x=40, y=50)
e1.focus_set()
canvas_entry_widgets.append(e1) # ADDED
e2 = Entry(canvas)
canvas.create_window(250, 85, window=e2, height=15, width=100)
label = Label(text="Enter a nationality.")
label.place(x=40, y=75)
e2.focus_set()
canvas_entry_widgets.append(e2) # ADDED
def callback():
print("Pizza was invented by a " + (e1.get()) + " " + (e2.get()))
# destroy the canvas entry widgets and clear the list # ADDED
while canvas_entry_widgets: # ADDED
widget = canvas_entry_widgets.pop() # ADDED
widget.destroy() # ADDED
def answer():
button = Button(text="Submit.", command=callback)
button.place(x=150, y=460)
answer()
canvas.pack()
mainloop()
Every widget has a destroy method which can be used to delete the widget. In your callback you can simply call this method for every widget:
def callback():
e1.destroy()
e2.destroy()
...
In your specific case, if you want to delete all the labels you will have to give them unique names. Or, to make this even easier, you can store all of your widgets and iterate over the list.

Categories