Select, copy and paste form Tkinter Python Layout Grid - python

I need to select, to copy and to paste some information of my form tkinter. But I cant do it. I want to copy the name 'Angelina Jolie' and paste anywhere. How I can do it? I need to do this with Grid Layout. I found some tutorials with pack and place. But I'm only interested in the Lyaout Grid
from tkinter import *
from tkinter import ttk
import tkinter as tk
class Form:
def __init__(self):
pass
def form(self):
self.root = Tk()
self.root.geometry('850x600')
self.root.title("PVE - Formulário Estudar")
self.canvas = tk.Canvas(bg='light blue', scrollregion=(0, 0, 1500, 3300))
self.canvas.bind('<Enter>', self._bound_to_mousewheel)
self.canvas.bind('<Leave>', self._unbound_to_mousewheel)
self.canvas.pack(fill='both', expand=True)
f = tk.Frame(self.canvas, background="light blue")
# you need to create a window into the canvas for the widget to scroll
self.canvas.create_window((5, 5), window=f, anchor="nw")
yvbar = ttk.Scrollbar(self.canvas, orient='vertical', command=self.canvas.yview)
xvbar = ttk.Scrollbar(self.canvas, orient='horizontal', command=self.canvas.xview)
yvbar.pack(side='right', fill='y')
yvbar.config(command=self.canvas.yview)
xvbar.pack(side='bottom', fill='x')
xvbar.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=yvbar.set, xscrollcommand=xvbar.set)
ttk.Label(f, width=20, text='Name: ', font='Arial 12 bold', background="light blue", anchor='w')\
.grid(column=0, row=1, padx=20, pady=10)
ttk.Label(f, width=40, text='Angelina Jolie', font='Arial 12 bold', foreground="blue",
background="light blue").grid(column=1, row=1, padx=20, pady=10)
self.root.mainloop()
def _bound_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
def _unbound_to_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
def _on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
if __name__ == '__main__':
a = Form()
a.form()

I'm not sure if you want to copy the value to the clipboard or you meant to ask how to set the value of another element to the value of an existing element, however, I added a copy button that does both, take a look at the code below for how I did it.
from tkinter import *
from tkinter import ttk
import tkinter as tk
import pyperclip
class Form:
def __init__(self):
pass
def copy_name(self):
# Get the current label value
user_name = self.name_label['text']
# Copy the value to the clipboard
pyperclip.copy(user_name)
# Update "paste" the value to the second label
self.copy_name_label.config(text=user_name)
print("{} was copied to your clipboard".format(user_name))
def form(self):
self.root = Tk()
self.root.geometry('850x600')
self.root.title("PVE - Formulário Estudar")
self.canvas = tk.Canvas(bg='light blue', scrollregion=(0, 0, 1500, 3300))
self.canvas.bind('<Enter>', self._bound_to_mousewheel)
self.canvas.bind('<Leave>', self._unbound_to_mousewheel)
self.canvas.pack(fill='both', expand=True)
f = tk.Frame(self.canvas, background="light blue")
# you need to create a window into the canvas for the widget to scroll
self.canvas.create_window((5, 5), window=f, anchor="nw")
yvbar = ttk.Scrollbar(self.canvas, orient='vertical', command=self.canvas.yview)
xvbar = ttk.Scrollbar(self.canvas, orient='horizontal', command=self.canvas.xview)
yvbar.pack(side='right', fill='y')
yvbar.config(command=self.canvas.yview)
xvbar.pack(side='bottom', fill='x')
xvbar.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=yvbar.set, xscrollcommand=xvbar.set)
ttk.Label(f, width=20, text='Name: ', font='Arial 12 bold', background="light blue", anchor='w') \
.grid(column=0, row=1, padx=20, pady=10)
self.name_label = ttk.Label(f, width=40, text='Angelina Jolie', font='Arial 12 bold', foreground="blue",
background="light blue")
self.name_label.grid(column=1, row=1, padx=20, pady=10)
self.copy_name_label = ttk.Label(f, width=40, text='', font='Arial 12 bold', foreground="blue",
background="light blue")
self.copy_name_label.grid(column=2, row=1, padx=20, pady=10)
copy_button = tk.Button(f, text="Copy", command=self.copy_name)
copy_button.grid(column=3, row=1, padx=20, pady=10)
self.root.mainloop()
def _bound_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
def _unbound_to_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
def _on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
if __name__ == '__main__':
a = Form()
a.form()

I finally find a solution for my problem in this tutorial:
http://www.booneputney.com/development/tkinter-copy-to-clipboard/
from tkinter import *
from tkinter import ttk
import tkinter as tk
class Form:
name = "Angelina Jolie"
def __init__(self):
pass
def copy_text_to_clipboard(self, event):
self.name = event.widget.get("1.0", 'end-1c') # get field value from event, but remove line return at end
self.root.clipboard_clear() # clear clipboard contents
self.root.clipboard_append(self.name) # append new value to clipbaord
def form(self):
self.root = Tk()
self.root.geometry('850x600')
self.root.title("PVE - Formulário Estudar")
self.canvas = tk.Canvas(bg='light blue', scrollregion=(0, 0, 1500, 3300))
self.canvas.bind('<Enter>', self._bound_to_mousewheel)
self.canvas.bind('<Leave>', self._unbound_to_mousewheel)
self.canvas.pack(fill='both', expand=True)
f = tk.Frame(self.canvas, background="light blue")
# you need to create a window into the canvas for the widget to scroll
self.canvas.create_window((5, 5), window=f, anchor="nw")
yvbar = ttk.Scrollbar(self.canvas, orient='vertical', command=self.canvas.yview)
xvbar = ttk.Scrollbar(self.canvas, orient='horizontal', command=self.canvas.xview)
yvbar.pack(side='right', fill='y')
yvbar.config(command=self.canvas.yview)
xvbar.pack(side='bottom', fill='x')
xvbar.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=yvbar.set, xscrollcommand=xvbar.set)
ttk.Label(f, width=20, text='Name: ', font='Arial 12 bold', background="light blue", anchor='w')\
.grid(column=0, row=1, padx=20, pady=10)
text_name = Text(f, width=40, height=1, font='Arial 12 bold', background="light blue", foreground="blue",
borderwidth=0)
text_name.insert(1.0, self.name)
text_name.grid(row=1, column=1)
# Bind left click on text widget to copy_text_to_clipboard() function
text_name.bind("<Button-1>", self.copy_text_to_clipboard)
self.root.mainloop()
def _bound_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
def _unbound_to_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
def _on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
if __name__ == '__main__':
a = Form()
a.form()

Related

scrollbar not working for an inner frame inside a canvas

I am trying to build a pattern for question paper...
I created a canvas in a frame and added a scrollbar. I created another frame inside and set the scrollbar to it. THe pattern for a question is in a frames which is repeated on the inner frame as per choice of user.
But the scrollbar is not working here, so after the question pattern has crossed the page, I cannot view them.
Here is a shortened form of my code.....
from tkinter import *
from tkinter import ttk
home = Tk()
width = home.winfo_screenwidth() - 20
height = home.winfo_screenheight() - 100
home.wm_geometry(f"{width}x{height}")
home.state("zoomed")
frame1 = Frame(home, bg='RED')
frame2 = Frame(home, bg='yellow')
frame1.pack(fill=Y, side=LEFT)
frame2.pack(fill=BOTH, expand=YES, side=LEFT)
label1 = Label(frame1, text="Label for Frame1", bg='light blue')
label1.grid(row=0, column=0)
def handle_resize(event):
canvas = event.widget
canvas_frame = canvas.nametowidget(canvas.itemcget("canvas_frame", "window"))
min_width = canvas_frame.winfo_reqwidth()
min_height = canvas_frame.winfo_reqheight()
if min_width < event.width:
canvas.itemconfigure("canvas_frame", width=event.width)
if min_height < event.height:
canvas.itemconfigure("canvas_frame", height=event.height)
canvas.configure(scrollregion=canvas.bbox("all"))
question_type_canvas = Canvas(frame2, bg='light green')
question_type_canvas.pack(side=LEFT, expand=YES, fill=BOTH)
inner_question_type_frame = Frame(question_type_canvas)
question_type_canvas.create_window((0, 0), window=inner_question_type_frame, anchor='nw', tags=("canvas_frame",))
vbar = Scrollbar(frame2, orient=VERTICAL, command=question_type_canvas.yview())
vbar.pack(side=RIGHT, fill=Y)
question_type_canvas.configure(yscrollcommand=vbar.set)
question_type_canvas.bind('<Configure>', handle_resize)
def clone_question_types(ques_index, row_number):
question_type_frame = Frame(inner_question_type_frame, bg='light pink')
question_type_frame.grid(row=row_number, column=0)
question_types_dict = dict({'Multiple Choice Questions': 1,
'Fill in the Blanks': 2})
question_types_combo_values = list(question_types_dict.keys())
question_no_label = Label(question_type_frame, text=f'Q {ques_index + 1}', bg='light pink', width=5)
type_label = Label(question_type_frame, text='Type: ', width=20, padx=5, bg='light pink')
type_selected = StringVar(question_type_frame)
type_menu = ttk.Combobox(question_type_frame, textvariable=type_selected,
values=list(question_types_combo_values), width=20, state="readonly")
next_question_button = Button(question_type_frame, text='Next Question',
command=lambda: [next_question_button.configure(state=DISABLED),
clone_question_types(ques_index + 1, row_number + 1)])
question_no_label.grid(row=0, column=0, sticky='w')
type_label.grid(row=0, column=1, sticky='w')
type_menu.grid(row=0, column=2, sticky='w')
next_question_button.grid(row=3, column=1)
clone_question_types(0, 0)
home.mainloop()

Tkinter: binding mousewheel to scrollbar when dragging widget in a drag and drop app

I'm working on a drag and drop app using tkinter; both of my frames have a scrollbar and, right now, when the text in the right is dragged is the right frame that scroll when using the mouse wheel, what I'd like to do is that when someone drag a text above the left frame then the left frame is the one that need to scroll when using the mouse wheel, while the right frame needs to be where it is without moving. I've really not idea how do so. This is my code:
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.first_frame = tk.LabelFrame(root, text="")
self.first_frame.pack(padx=15, pady=15, fill="both", expand="true", side="left", anchor="w")
self.first_canvas = tk.Canvas(self.first_frame, highlightthickness=0)
self.first_canvas.pack(side="left", fill="both", expand="true")
self.first_canvas.bind("<Enter>", lambda _: self.first_canvas.bind_all('<MouseWheel>', self.on_mousewheel_left))
self.first_canvas.bind("<Leave>", lambda _: self.first_canvas.unbind_all('<MouseWheel>'))
self.second_frame = tk.LabelFrame(root, text="")
self.second_frame.pack(padx=15, pady=15, fill="both", expand="true", side="left")
self.second_canvas = tk.Canvas(self.second_frame, highlightthickness=0)
self.second_canvas.pack(side="left", fill="both", expand="true")
self.second_canvas.bind("<Enter>", lambda _: self.second_canvas.bind_all('<MouseWheel>', self.on_mousewheel_right))
self.second_canvas.bind("<Leave>", lambda _: self.second_canvas.unbind_all('<MouseWheel>'))
self.upload_one()
self.upload_two()
def upload_one(self):
self.first_list = ["11:00", "03:43", "22:04", "17:21", "22:35", "07:01", "16:11", "09:00"]
self.first_scrollbar = ttk.Scrollbar(self.first_frame, orient="vertical", command=self.first_canvas.yview)
self.first_scrollbar.pack(side="right", fill="y")
self.first_canvas.configure(yscrollcommand=self.first_scrollbar.set)
self.first_canvas.bind('<Configure>', lambda e: self.first_canvas.configure(scrollregion = self.first_canvas.bbox("all")))
self.first_list_frame = tk.Frame(self.first_canvas)
self.first_canvas.create_window((0,0), window=self.first_list_frame, anchor="nw")
for index, cit in enumerate(sorted(self.first_list)):
self.one_frame = tk.LabelFrame(self.first_list_frame)
self.one_frame.grid(row=index, column=0, padx=10, pady=(20,0))
self.one_text = tk.Text(self.one_frame, width=77, height=4)
self.one_text.grid(row=1, column=1, rowspan=2, sticky="nw")
self.dragged_text = tk.Text(self.one_frame, wrap="word", width=68, height=3, highlightthickness=1, highlightcolor= "DodgerBlue3",)
self.dragged_text.grid(row=3, column=1, rowspan=2, columnspan=2, pady=(10,20), ipady=7, sticky="nw")
def upload_two(self):
self.second_list = ["morning\nmorning\nmorning", "afternoon\nafternoon\nafternoon", "evening\nevening\nevening", "nigth\nnight\nnight"]
self.second_scrollbar = ttk.Scrollbar(self.second_frame, orient="vertical", command=self.second_canvas.yview)
self.second_scrollbar.pack(side="right", fill="y")
self.second_canvas.configure(yscrollcommand=self.second_scrollbar.set)
self.second_canvas.bind('<Configure>', lambda e: self.second_canvas.configure(scrollregion = self.second_canvas.bbox("all")))
# can i remove this frame?
self.two_list_frame = tk.Frame(self.second_canvas)
self.second_canvas.create_window((0,0), window=self.two_list_frame, anchor="nw")
for index, two in enumerate(sorted(self.second_list)):
self.two_frame = tk.Frame(self.two_list_frame)
self.two_frame.pack(pady=(15,0), fill="x", expand="yes", side="top")
self.two_text = tk.Text(self.two_frame, font=("Times New Roman", 11), wrap="word", highlightthickness=1, highlightcolor= "DodgerBlue3", cursor="hand2", width=81, height=4)
self.two_text.grid(row=0, column=0, padx=15)
self.two_text.insert("end", str(two.strip()), "normal")
self.two_text.config(state="disabled")
self.two_text.bind('<Button-1>', self.click)
self.two_text.bind('<B1-Motion>',self.drag)
self.two_text.bind('<ButtonRelease-1>',self.release)
def on_mousewheel_left(self, event):
widget = event.widget.winfo_parent()
self.first_canvas.yview_scroll(int(-1*(event.delta//120)), 'units')
def on_mousewheel_right(self, event):
widget = event.widget.winfo_parent()
print(widget)
self.second_canvas.yview_scroll(int(-1*(event.delta//120)), 'units')
def click(self, event):
self.text = event.widget.get("1.0",'end-1c')
root.clipboard_clear()
root.clipboard_append(self.text)
self.top = tk.Toplevel(root)
self.top.attributes('-alpha', 0.7)
self.top.overrideredirect(True)
self.top._offsetx = event.x
self.top._offsety = event.y
x = self.top.winfo_pointerx() - self.top._offsetx - 30
y = self.top.winfo_pointery() - self.top._offsety - 30
self.top.geometry('+{x}+{y}'.format(x=x,y=y))
two_toplevel_label = tk.Label(self.top, text=self.text, wraplength=571, justify="left", bg="SystemButtonFace")
two_toplevel_label.grid(row=0, column=0)
def drag(self, event):
x = self.top.winfo_pointerx() - self.top._offsetx
y = self.top.winfo_pointery() - self.top._offsety
self.two_text.tag_remove("sel", "1.0", "end")
self.top.geometry(f"+{x}+{y}")
def release(self, event):
widget = event.widget.winfo_containing(event.x_root, event.y_root)
self.top.destroy()
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()

Is It possible to create multiple form fields in tkinter & python and then submit it to a out to an output textbox in a table column format

So my problem is that I want to create multiple entry fields like over 30, but every time I reformat it using .pack or .grid it keeps throwing off the formatting. is there a way to fit nearly 30 entry boxes on one window without using anything like SQLite? As we can see from this code, we have 4 fields, how would you go on with shrinking the boxes to put in more entry fields like over 30.
Secondly, I want to output all the typed data entry fields to the Listbox is there a way to add a table column to the list box to show a breakdown of each entry field.
The third is it possible to move the Listbox to another tab on the same window to show all entry fields that were typed in, if so how would you do so.
Here is my current code so far
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from datetime import *
# Import Packages
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import *
import tkinter.filedialog
from tkcalendar import Calendar, DateEntry
from tkinter import messagebox
from tkintertable import TableCanvas, TableModel
from tkinter import ttk
# Database
#import sqlite3
import csv
window = Tk()
window.title("TESTTEST")
window.geometry("750x450")
window.config(background='black')
#style = ttk.Style(window)
#style.configure('lefttab.TNotebook', tabposition='wn',)
# TAB LAYOUT
#tab_control = ttk.Notebook(window,style='righttab.TNotebook')
#tab1 = ttk.Frame(tab_control)
#tab2 = ttk.Frame(tab_control)
#tab3 = ttk.Frame(tab_control)
#tab4 = ttk.Frame(tab_control)
#tab5 = ttk.Frame(tab_control)
#tab6 = ttk.Frame(tab_control)
# ADD TABS TO NOTEBOOK
#tab_control.add(tab1, text=f'{"Home":^20s}')
#tab_control.add(tab2, text=f'{"View":^20s}')
#tab_control.add(tab3, text=f'{"Search":^20s}')
#tab_control.add(tab4, text=f'{"Edit":^20s}')
#tab_control.add(tab5, text=f'{"Export":^20s}')
#tab_control.add(tab6, text=f'{"About ":^20s}')
#label1 = Label(tab1, text= 'Python RPA APP',padx=1, pady=1)
#label1.grid(column=0, row=0)
#label2 = Label(tab2, text= 'View',padx=5, pady=5)
#label2.grid(column=0, row=0)
#label3 = Label(tab3, text= 'Search',padx=5, pady=5)
#label3.grid(column=0, row=0)
#label4 = Label(tab4, text= 'Edit/Update',padx=5, pady=5)
#label4.grid(column=0, row=0)
#label5 = Label(tab5, text= 'Export',padx=5, pady=5)
#label5.grid(column=0, row=0)
#label6 = Label(tab6, text= 'About',padx=5, pady=5)
#label6.grid(column=0, row=0)
#tab_control.pack(expand=1, fill='both')
class Main(ttk.Frame):
def __init__(self, parent):
super().__init__()
self.parent = parent
self.punches_list = []
self.ent1 = tk.StringVar()
self.ent2 = tk.StringVar()
self.ent3 = tk.StringVar()
self.ent4 = tk.StringVar()
self.init_ui()
def init_ui(self):
f = ttk.Frame()
# ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW)
## ttk.Label(f, text = "Entry1").pack(side=LEFT, padx=5, pady=5, anchor=NW)
## self.txTest = ttk.Entry(f,textvariable=self.ent).pack(fill=X, padx=5, expand=True, anchor=NW)
# ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW)
# self.txTest1 = ttk.Entry(f, textvariable=self.ent2).pack(side=TOP, anchor=NW)
ttk.Label(f, text = "Entry1").pack(side=TOP, anchor=NW, fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest1 = ttk.Entry(f, textvariable=self.ent1).pack(side=TOP, anchor=NW, fill=tk.BOTH, pady=5, padx=5, expand=0)
ttk.Label(f, text = "Entry2").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest2 = ttk.Entry(f, textvariable=self.ent2).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
ttk.Label(f, text = "Entry3").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest3 = ttk.Entry(f, textvariable=self.ent3).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
#tkinter.Label(window, text = "Username").grid(row = 0) #'username' is placed on position 00 (row - 0 and column - 0)
#tkinter.Entry(window).grid(row = 0, column = 1) # first input-field is placed on position 01 (row - 0 and column - 1)
ttk.Label(f, text = "Entry4").pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.txTest4 = ttk.Entry(f, textvariable=self.ent4).pack(side=TOP, anchor=NW,fill=tk.BOTH, pady=5, padx=5, expand=0)
self.lstItems = self.get_listbox(f, 140,140).pack(anchor=N)
w = ttk.Frame()
ttk.Button(w, text="Add",command=self.add_In).pack(side=TOP, anchor=NE)
ttk.Button(w, text="Clear", command=self.clear_Out).pack(side=TOP, anchor=NE)
ttk.Button(w, text="Close", command=self.on_close).pack(side=TOP, anchor=NE)
#f.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
#w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
f.pack(side=tk.LEFT, fill=tk.BOTH, pady=5, padx=5, expand=1)
w.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
def add_In(self,):
#s = "IN {0:>30} {1}".format(str(datetime.now()), self.ent.get())
s = self.ent1.get()
self.set_list(s)
s = self.ent2.get()
self.set_list(s)
s = self.ent3.get()
self.set_list(s)
s = self.ent4.get()
self.set_list(s)
self.ent1.set('')
self.ent2.set('')
self.ent3.set('')
self.ent4.set('')
def clear_Out(self):
#s = "OUT {0:>29} {1}".format(str(datetime.now()), self.ent1.get())
#field_name.set('')
self.ent1.set('')
self.ent2.set('')
self.ent3.set('')
self.ent4.set('')
#self.set_list(s)
def set_list(self,s):
self.punches_list.append(s)
self.lstItems.delete(0, tk.END)
for i in self.punches_list:
self.lstItems.insert(tk.END, i)
def on_set(self):
self.check.set(1)
def on_close(self):
#self.destroy()
self.parent.on_exit()
def get_listbox(self, container, height=750, width=600):
sb = tk.Scrollbar(container,orient=tk.VERTICAL)
w = tk.Listbox(container,
relief=tk.GROOVE,
selectmode=tk.BROWSE,
height=height,
width=width,
background = 'white',
font='TkFixedFont',
yscrollcommand=sb.set,)
sb.config(command=w.yview)
w.pack(side=tk.LEFT,fill=tk.BOTH, expand =1)
sb.pack(fill=tk.Y, expand=1)
return w
class App(tk.Tk):
"""Start here"""
def __init__(self):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_style()
self.set_title()
Main(self,)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("vista") #change to your liking :)
def set_title(self):
s = "{0}".format('Employee Time-Clock')
self.title(s)
self.destroy()
def on_exit(self):
window.destroy()
#self.destroy()
#sys.exit()
#"""Close all"""
#if messagebox.askokcancel( self.title(), "Do you want to quit?", parent=self):
# self.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
Your code is a giant mess, brah ;D. What I gather from your question is that you need some kind of table. What I gather from your code is the table should have cells comprised of Label and Entry. You also want an interface to create entries. Below is an example of all of that. I don't really see anything to explain. It's just a bunch of Frame, Label, Entry and Button. The only real action is in Table. All that action is, is mathematically figuring out where to put the next Item. This is all really basic stuff.
import tkinter as tk
from tkinter import ttk
#the entire bottom row of the app.
#has a dependency on self.master.table ~ not good OOP
class EntryManager(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.grid_columnconfigure(5, weight=1)
font='Helvetica 10 bold'
tk.Label(self, text='Label', font=font, width=5).grid(row=0, column=0, padx=2)
lbl = tk.Entry(self, width=10, font=font)
lbl.grid(row=0, column=1, padx=2)
tk.Label(self, text='Entry', font=font, width=5).grid(row=0, column=2, padx=2)
ent = tk.Entry(self, width=25, font=font)
ent.grid(row=0, column=3, padx=2)
tk.Button(self, text='add', font=font, command=lambda: self.master.table.addItem(lbl.get(), ent.get())).grid(row=0, column=4, padx=2, sticky='w')
tk.Label(self, text='rows', font=font, width=4).grid(row=0, column=5, padx=2, sticky='e')
r = tk.Entry(self, width=4, font=font)
r.insert('end', self.master.table.rows)
r.grid(row=0, column=6, padx=2)
tk.Label(self, text='cols', font=font, width=4).grid(row=0, column=7, padx=2)
c = tk.Entry(self, width=4, font=font)
c.insert('end', self.master.table.cols)
c.grid(row=0, column=8, padx=2)
tk.Button(self, text='set', font=font, command=lambda: self.master.table.setDims(r.get(), c.get())).grid(row=0, column=9, padx=2, sticky='e')
#generic scrollable frame
class ScrollFrame(tk.Frame):
def __init__(self, master, row=0, column=0, scrollspeed=.02, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.grid(row=row, column=column, sticky='nswe')
self.scrollspeed = scrollspeed
self.canvas = tk.Canvas(self, highlightthickness=0)
self.canvas.grid(column=0, row=0, sticky='nswe')
self.v_scroll = tk.Scrollbar(self, orient='vertical', command=self.canvas.yview)
self.v_scroll.grid(row=0, column=1, sticky='ns')
self.canvas.configure(yscrollcommand=self.v_scroll.set)
self.canvas.bind_all('<MouseWheel>', self.on_mousewheel)
self.frame = tk.Frame(self.canvas, height=0)
self.frame.grid_columnconfigure(0, weight=1)
self.frame.bind('<Configure>', lambda e:self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.canvas.create_window((0,0), window=self.frame, anchor="nw")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def on_mousewheel(self, event):
self.canvas.yview_moveto(self.v_scroll.get()[0]+((-event.delta/abs(event.delta))*self.scrollspeed))
#a table cell
class Item(tk.Frame):
#property
def value(self):
return self.__value.get()
#value.setter
def value(self, text):
self.__value.set(text)
def __init__(self, master, text, value, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
tk.Label(self, text=text, width=10, font='none 8 bold').grid(row=0, column=0, pady=5, padx=5)
self.__value = tk.StringVar(value=value)
tk.Entry(self, textvariable=self.__value, width=25).grid(row=0, column=1, pady=5, padx=5)
#the table
class Table(ScrollFrame):
def __init__(self, master, rows=15, cols=3, **kwargs):
ScrollFrame.__init__(self, master, **kwargs)
self.entries = []
self.rows = rows
self.cols = cols
def addItem(self, text, value):
if len(self.entries) < self.rows*self.cols:
self.entries.append(Item(self.frame, text, value))
self.entries[-1].grid(row=(len(self.entries)-1)%self.rows, column=(len(self.entries)-1)//self.rows)
def getItem(self, row, column):
return self.entries[self.rows*column+row].value
def setDims(self, rows, cols):
if rows.isnumeric():
self.rows = int(rows)
if cols.isnumeric():
self.cols = int(cols)
for ent in self.entries:
ent.grid_forget()
for i, ent in enumerate(self.entries):
if i < self.rows*self.cols:
ent.grid(row=i%self.rows, column=i//self.rows)
class App(tk.Tk):
WIDTH, HEIGHT, TITLE = 770, 465, 'Application'
def __init__(self):
tk.Tk.__init__(self)
ttk.Style().theme_use("vista")
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.table = Table(self, rows=20, cols=3)
self.table.grid(row=0, column=0, sticky='nswe')
EntryManager(self).grid(row=1, column=0, sticky='nswe', ipady=5)
#junk for testing
for i in range(12):
self.table.addItem(f'entry_{i}', f'data {i}')
if __name__ == '__main__':
app = App()
app.config(background='black')
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
#app.resizable(width=False, height=False)
app.mainloop()
Might as well dump the table keys in the table and see what happens. The sizes and alignments of things could use some work.

tkinter canvas text output

I have been looking at my code for a while and new to tkinter. The purpose of my code is to display text within the Canvas widget not overlay a label. But unsure how to do this:
My code is as follows:
from tkinter import *
class Example(Frame):
def printLabel(self):
self.hello = []
self.hello.append('Hello')
self.hello.append('World!')
return(self.hello)
def updatePanel(self):
self.panelA.config(text="{}".format(self.printLabel()))
def __init__(self, root):
Frame.__init__(self, root)
self.buttonA()
self.viewingPanel()
def buttonA(self):
self.firstPage = Button(self, text="Print Text", bd=1, anchor=CENTER, height = 11, width = 13, command=lambda: self.updatePanel())
self.firstPage.place(x=0, y=0)
def viewingPanel(self):
self.panelA = Label(self, bg='white', width=65, height=13, padx=3, pady=3, anchor=NW, text="")
self.panelA.place(x=100, y=0)
self.cl= Canvas(self.panelA,bg='WHITE',width=165,height=113,relief=SUNKEN)
canvas_id = self.cl.create_text(15, 15, anchor="nw")
self.xb= Scrollbar(self.panelA,orient="horizontal", command=self.cl.xview)
self.xb.pack(side=BOTTOM,fill=X)
self.xb.config(command=self.cl.xview)
self.yb= Scrollbar(self.panelA,orient="vertical", command=self.cl.yview)
self.yb.pack(side=RIGHT,fill=Y)
self.yb.config(command=self.cl.yview)
self.cl.itemconfig(canvas_id,font=('Consolas',9), text="{}".format(self.printLabel()))
self.cl.configure(scrollregion = self.cl.bbox("all"))
self.cl.config(xscrollcommand=self.xb.set, yscrollcommand=self.yb.set)
self.cl.config(width=250,height=150)
self.cl.pack(side=LEFT,expand=True,fill=BOTH)
def main():
root = Tk()
root.title("Tk")
root.geometry('378x176')
app = Example(root)
app.pack(expand=True, fill=BOTH)
root.mainloop()
if __name__ == '__main__':
main()
The Hello World! should display without the brackets in the Canvas but the main issue is that when I click on the Button it just overlaps the canvas and prints out the append on to the Label.
The Label should be inside the Canvas.
Here's how to fix the "main issue" along with the "brackets issue". The latter is taken care of by using the string join() method as suggested in the comments.
The updatePanel() method has been modified so it first create a Label widget with the text you want displayed in it, followed by a Canvas "window" object specifying that widget as its contents. Code for the way you were attempting to do it was also removed from the other class methods.
from tkinter import *
class Example(Frame):
def __init__(self, root):
Frame.__init__(self, root)
self.buttonA()
self.viewingPanel()
def printLabel(self):
text = []
text.append('Hello')
text.append('World!')
return ' '.join(text)
def updatePanel(self):
label = Label(self, bg='white', padx=3, pady=3, anchor=NW,
text=self.printLabel())
label.place(relx=0.5, rely=0.5, anchor=CENTER)
self.cl.create_window(100, 100, window=label) # Put Label in a Canvas "window".
def buttonA(self):
self.firstPage = Button(self, text="Print Text", bd=1, anchor=CENTER, height=11,
width=13, command=lambda: self.updatePanel())
self.firstPage.place(x=0, y=0)
def viewingPanel(self):
self.panelA = Label(self, bg='white', width=65, height=13, padx=3, pady=3,
anchor=NW, text="")
self.panelA.place(x=100, y=0)
self.cl= Canvas(self.panelA, bg='WHITE', width=165, height=113, relief=SUNKEN)
canvas_id = self.cl.create_text(15, 15, anchor="nw")
self.xb= Scrollbar(self.panelA,orient="horizontal", command=self.cl.xview)
self.xb.pack(side=BOTTOM, fill=X)
self.xb.config(command=self.cl.xview)
self.yb= Scrollbar(self.panelA, orient="vertical", command=self.cl.yview)
self.yb.pack(side=RIGHT, fill=Y)
self.yb.config(command=self.cl.yview)
self.cl.itemconfig(canvas_id, font=('Consolas',9), text=self.printLabel())
self.cl.configure(scrollregion=self.cl.bbox("all"))
self.cl.config(xscrollcommand=self.xb.set, yscrollcommand=self.yb.set)
self.cl.config(width=250, height=150)
self.cl.pack(side=LEFT, expand=True, fill=BOTH)
def main():
root = Tk()
root.title("Tk")
root.geometry('378x176')
app = Example(root)
app.pack(expand=True, fill=BOTH)
root.mainloop()
if __name__ == '__main__':
main()

extra spaces between buttons in tkinter

I have implemented a code to make GUI using Tkinter and I'm new in this. The problem which I'm facing is that there is lots of spacing between two buttons in column 3 ( select object and play button).
I want to know that why this is happening.
my code is here:
from tkinter import Tk, Text, BOTH, W, N, E, S
from tkinter.ttk import Frame, Button, Label, Style
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Nav Track app")
self.pack(fill=BOTH, expand=True)
self.style = Style()
self.style.theme_use("default")
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="Keep your eyes on screen")
lbl.grid(sticky=W, pady=4, padx=5)
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=5,
padx=8, sticky=E + W + S + N)
abtn = Button(self, text="Start Camera")
abtn.grid(row=1, column=3, padx=4)
cbtn = Button(self, text="Select Object")
cbtn.grid(row=2, column=3, padx=4, pady=4)
dbtn = Button(self, text="Play")
dbtn.grid(row=3, column=3, padx=4, pady=4)
hbtn = Button(self, text="Help")
hbtn.grid(row=7, column=0, padx=5)
obtn = Button(self, text="Exit")
obtn.grid(row=7, column=3)
def main():
root = Tk()
root.geometry("500x450+300+500")
app = Example()
root.mainloop()
if __name__ == '__main__':
main()

Categories

Resources