Python Serial data not displaying in Canvas on tk GUI - python-3.x

I am new to Python and have a problem displaying serial data on my canvas in a tk GUI. I have set up the GUI and all is working, but the data is not displaying in the canvas.
I feel that I am missing something small...
Secondly, when I click the buttons to connect, the GUI freezes up.
Her is my code.
Any help would be welcome
Here is a picture of the current GUI
import serial
import serial.tools.list_ports
import tkinter as tk
from tkinter import *
from tkinter import ttk
import time
import time as tm
from configparser import ConfigParser
import os
import logging
current_time = tm.strftime('%H:%M:%S - %D')
#Get current ports and devices connected
ports = serial.tools.list_ports.comports()
serialInst = serial.Serial()
#List available ports
portlist = []
for onePort in ports:
portlist.append(str(onePort))
#Set logfile
def logfile():
os.system("notepad.exe " + config['Logger']['logfilename'])
# Read config file settings
config = ConfigParser()
config.read('config.ini')
#global logFileName
logFileName = config['Logger']['logfilename']
## Logger Configuration
def setupLogger(filename):
logger = logging.getLogger("Log")
logger.setLevel(config['Logger']['loglevel'])
# create file handler which logs even debug messages
fh = logging.FileHandler(filename)
fh.setLevel(config['Logger']['loglevel'])
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(config['Logger']['loglevel'])
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s ~ %(name)s ~ %(levelname)s ~ %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
# Return the Created logger
return logger
log = setupLogger(logFileName)
# Method to read config file settings
portsettings = config['serial_settings']
ser = serial.Serial(
port=config['serial_settings']['port'],
baudrate=config['serial_settings']['baudrate'],
parity=config['serial_settings']['parity'],
#stopbits=config['serial_settings']['stop bits']
)
def initPort():
while True:
if ser.in_waiting:
packet = ser.readline.decode('utf')
def connect():
ser.timeout = None
ser.writeTimeout = 0
tk.Label(dataFrame, text='Starting Up Serial Monitor').grid(row=1, column=1)
print("Starting Up Serial Monitor")
try:
ser.open()
except Exception as e:
log.info("Check if serial port is open.")
print("Check if serial port is open: " + str(e))
log.info(str(e))
if ser.isOpen():
try:
ser.flushInput()
ser.flushOutput()
ser.write((config['Commands']['maint']+'\n').encode('ascii'))
tk.Label(dataFrame, text="Serial data sent : " + config['Commands']['maint'], bg='white').grid(row=2, column=1)
ser.write((config['Commands']['inst']+'\n').encode('ascii'))
tk.Label(dataFrame, text="Serial data sent : " + config['Commands']['inst'], bg='white').grid(row=3, column=1)
ser.write((config['Commands']['dnl']+'\n').encode('ascii'))
tk.Label(dataFrame, text="Serial data sent : " + config['Commands']['dnl'], bg='white').grid(row=4, column=1)
ser.write((config['Commands']['status8']+'\n').encode('ascii'))
tk.Label(dataFrame, text="Serial data sent : " + config['Commands']['status8'], bg='white').grid(row=5, column=1)
log.info("Serial Data written to port.")
time.sleep(1)
numberOfLine = 0
while True:
response = ser.readline().decode('utf')
log.info("Reading serial data.")
log.info("Serial data read :"+response)
numberOfLine = numberOfLine + 1
Label(dataFrame, text=("Serial data read : " + response), bg='white').grid(row=7, column=1)
if numberOfLine >= 30:
break
ser.close()
except Exception as e:
print("Error communicating...: " + str(e))
else:
print("Cannot open serial port.")
log.error("Cannot open serial port.")
root = Tk()
root.resizable(True, True)
root.config(bg='light grey')
root.title(config['Info']['Application'] + config['Info']['ver'] + ' - Start Time ' + current_time)
copy_Label = Label(root, text=config['Info']['Copyright'], fg="red", font="Clibri 8 ").grid(column=1, row=50)
window_width = 600
window_height = 500
# get the screen dimension
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# find the center point
center_x = int(screen_width/2 - window_width / 2)
center_y = int(screen_height/2 - window_height / 2)
# set the position of the window to the center of the screen
root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
#Serial settings frame
sersetframe = Frame(root, highlightbackground="black", highlightthickness=2)
sersetframe.grid(row=1, column=1, padx=5, pady=5)
#Display serial settings from config
topLabel = Label(sersetframe, text='Serial Config Details. ', fg="black", bg='white', font="Clibri 10 bold").grid(row=2, column=1)
portLabel = Label(sersetframe, text='Port = '+config['serial_settings']['port'], fg="blue", bg='white', font="Clibri 10 bold").grid(row=3, column=1)
baudLabel = Label(sersetframe, text='Baudrate = '+config['serial_settings']['baudrate'], fg="blue", bg='white', font="Clibri 10 bold").grid(row=4, column=1)
paritytLabel = Label(sersetframe, text='Parity = '+config['serial_settings']['parity'], fg="blue", bg='white', font="Clibri 10 bold").grid(row=5, column=1)
#Button frame
buttonframe = Frame(root, highlightbackground="black", highlightthickness=2)
buttonframe.grid(row=49, column=2, padx=5, pady=5)
#Output frame
opframe = Frame(root, highlightbackground="black", highlightthickness=2)
opframelabel = Label(opframe, font='ariel 8 bold', bg='white', fg='blue', text='Serial Output')
opframelabel.grid(row=0, column=1)
opframe.grid(row=10, column=1, padx=5, pady=5)
#Output Canvas
dataCanvas = Canvas(root, width=350, height=200, bg='white')
dataCanvas.grid(row=30, column=1)
#Scrollbar
vsb = Scrollbar(root, orient='vertical', command=dataCanvas.yview)
vsb.grid(row=30, column=0, rowspan=10, sticky='ns')
dataCanvas.config(yscrollcommand=vsb.set)
dataFrame = Frame(dataCanvas, bg='white')
dataCanvas.create_window((10, 0), window=dataFrame, anchor='nw')
# Action Buttons
sendBtn = tk.Button(buttonframe, text='Send', command=connect).grid(column=1, row=7)
connectBtn = tk.Button(buttonframe, text='Connect', command=initPort).grid(column=1, row=8)
exitBtn = tk.Button(buttonframe, text='Exit', command=root.destroy).grid(column=1, row=9)
#Info frame
infoframe = Frame(root, highlightbackground="black", highlightthickness=2)
infoframelabel = Label(infoframe, font='ariel 8 bold', bg='white', fg='black', text='Info:')
infoframelabel.grid(row=0, column=1)
infoframe.grid(row=49, column=1, padx=5, pady=5)
# Check config file settings
dir_path = os.path.dirname(os.path.realpath(__file__))
config_filepath = dir_path+"\config.ini"
# check if the config file exists
exists = os.path.exists(config_filepath)
if exists:
print("**** config.ini file found at : ", config_filepath)
configfileLabel = Label(infoframe,text='Found config file at : '+config_filepath, fg="green",
bg='white', font="Clibri 10 bold").grid(row=49, column=1)
else:
print("**** config.ini file WAS NOT FOUND at : ", config_filepath)
configfileLabel = Label(root,text='DID NOT FIND config file at : ' + config_filepath, fg="red",
bg='white', font="Clibri 10 bold").grid(row=49, column=1)
comportLabel = Label(infoframe, text='Available COM ports : '+str(onePort), fg="black",
bg='white', font="Clibri 10 bold").grid(row=50, column=1)
#Run gui
root.mainloop()

Related

Problem with askopenfilename() sending to converting function and saving file using asksavefile() - Python Tkinter

I wrote a CAD coordinate conversion application that reads a .txt file using filedialok.askopenfilename() using the function read_file_click().
After selecting the appropriate scale in the Combobox, the program converts the file using the convert() function, then saves it to a .txt file after calling the function save_file_click().
The problem is that when I send the returned value from the convert function to the save_file_click() function, I get two notifications about opening the file.
I don't know how to correct this error. I tried using global variables, but it doesn't help, and weak errors appears with the data_list_no_head variable. Thanks for help:)
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import os
root = Tk()
root.title("Autocad Coordinate Converter")
root.geometry("")
root.geometry("280x320")
root.resizable(False, False)
def combo_sets():
scale_combo.set("")
def ending_message():
messagebox.showinfo("Autocad Coordinate Converter", "End")
def read_file_click():
global data_list_no_head
file_path = filedialog.askopenfilename()
return file_path
def convert():
file_path_new = read_file_click()
data_list = []
with open(file_path_new, encoding='utf-16') as file:
for line in file:
data_list.append(line.split())
data_list_no_head = data_list[4:]
return data_list_no_head
def save_file_click():
new = convert()
scale_get = scale_combo.get()
data = None
event_eng = None
cal = None
x_coordinate = None
y_coordinate = None
output_file = open(output_file_path_name, 'a')
if scale_get == "1:500" or scale_get == "1:1000":
for event in new:
for _ in event:
data = event[1]
event_eng = event[4]
x_coordinate = event[5]
y_coordinate = event[6]
cal = int(event_eng[-1])*2-2
output_file.write(f"_layer u w{data[2:4]}e{event_eng[-1]} _donut 0 {cal} {y_coordinate},"
f"{x_coordinate} \n")
output_file.close()
new_file_name = output_file_path_name[:-4] + ".scr.txt"
os.rename(output_file_path_name, new_file_name)
combo_sets()
ending_message()
elif scale_get == "1:2000":
for event in new:
for _ in event:
data = event[1]
event_eng = event[4]
x_coordinate = event[5]
y_coordinate = event[6]
cal = 2*(int(event_eng[-1])*2-2)
output_file.write(f"_layer u w{data[2:4]}e{event_eng[-1]} _donut 0 {cal} {y_coordinate},"
f"{x_coordinate} \n")
output_file.close()
new_file_name = output_file_path_name[:-4] + ".scr.txt"
os.rename(output_file_path_name, new_file_name)
combo_sets()
ending_message()
elif scale_get == "1:5000":
for event in new:
for _ in event:
data = event[1]
event_eng = event[4]
x_coordinate = event[5]
y_coordinate = event[6]
cal = 5*(int(event_eng[-1])*2-2)
output_file.write(f"_layer u w{data[2:4]}e{event_eng[-1]} _donut 0 {cal} {y_coordinate},"
f"{x_coordinate} \n")
output_file.close()
new_file_name = output_file_path_name[:-4] + ".scr.txt"
os.rename(output_file_path_name, new_file_name)
combo_sets()
ending_message()
elif scale_get == "1:10000":
for event in new:
for _ in event:
data = event[1]
event_eng = event[4]
x_coordinate = event[5]
y_coordinate = event[6]
cal = 20*(int(event_eng[-1])-2)
output_file.write(f"_layer u w{data[2:4]}e{event_eng[-1]} _donut 0 {cal} {y_coordinate},"
f"{x_coordinate} \n")
output_file.close()
new_file_name = output_file_path_name[:-4] + ".scr.txt"
os.rename(output_file_path_name, new_file_name)
combo_sets()
ending_message()
# Frame1
frame1 = LabelFrame(root, padx=15, pady=15, relief=FLAT)
frame1.grid(row=1, column=0)
button_1 = Button(frame1, text="Read .txt file", padx=15, pady=15, width=20, height=1, command=read_file_click)
button_1.grid(row=1, column=0, padx=3, pady=3)
# Frame2
frame2 = LabelFrame(root, padx=15, pady=15, relief=FLAT)
frame2.grid(row=2, column=0)
Label(frame2, text="Select scale:", width=14).grid(row=1, column=1, padx=1, pady=1)
scale_combo = ttk.Combobox(frame2, values=["1:500", "1:1000", "1:2000", "1:5000", "1:10000"], width=9, state='readonly')
scale_combo.current()
scale_combo.grid(row=2, column=1, padx=1, pady=1)
# Frame3
frame3 = LabelFrame(root, padx=50, pady=50, relief=FLAT)
frame3.grid(row=3, column=0)
button_2 = Button(frame3, text="Save file in CAD format", padx=15, pady=15, width=20, height=1,
command=save_file_click)
button_2.grid(row=0, column=0, padx=3, pady=3)
root.mainloop()

Is it possible to grab input from the topview tkinter window and retrieve saved entry field value from within master tk window

The program is made up of classes and I am trying to use a tkinter topview from within a function so that when it's called it is able to retrieve the entryfield value to the master class
from tkinter import
from PIL import Image, ImageTk
Below is the driver code handling the transitioning from one class to another
class SeaofBTCapp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (
WelcomePage, Register_new_user): # ,PageThree,PageFour):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(WelcomePage)
# def show_frame(self, cont):
# frame = self.frames[cont]
# frame.tkraise()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
frame.update()
frame.event_generate("<<show_frame>>")
def get_page(self, cont):
for page in self.frames.values():
if str(page.__class__.__name__) == cont:
return page
return None
class Register_new_user(object):
pass
Below is the entry point of the program and is the first page to be displayed
class WelcomePage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
# self.bind("<<show_frame>>", self.main_prog)
def resize_image(event):
global photo
new_width = event.width
new_height = event.height
image = copy_of_image.resize((new_width, new_height))
photo = ImageTk.PhotoImage(image)
label.config(image=photo)
label.image = photo # avoid garbage collection
def pin_input():
top = Toplevel()
top.geometry("180x100")
top.title("toplevel")
l2 = Label(top, text="This is toplevel window")
global entry_1
global password
password = StringVar
entry_1 = None
def cleartxtfield():
global password
new = "3"
password.set(new)
# ############# Function to parse for only numerical input
def validate(input):
if input.isdigit():
return True
elif input == "":
return True
else:
return False
def enternumber(x):
global entry_1
setval = StringVar()
setval = str(x)
# print(setval)
entry_1.insert(END, setval)
entry_1 = Entry(top, textvariable=password, width=64, show='*')
entry_1.place(x=200, y=100)
entry_1.focus()
reg = top.register(validate)
entry_1.config(validate="key", validatecommand=(reg, '%P'))
def getcreds():
# check if four digit entered and is not empty
global passwd
passwd = password.get()
print(f"The Credentials are {passwd}")
def funcbackspace():
length = len(entry_1.get())
entry_1.delete(length - 1, 'end')
def killwindow():
# when the user quits it should clear all the data input fields filled in in the previous steps. and should display information that it is about to quit in a few seconds
command = top.destroy()
# Label(top,text="Goodbye\n (Closing in 2 seconds)")
top.after(2000, top.quit())
cancel = Button(top, width=8, height=3, text="Cancel", bg="red", fg="black", command=killwindow)
cancel.place(x=220, y=150)
backspace = Button(top, width=8, height=3, text="Backspace", bg="red", fg="black", command=funcbackspace)
backspace.place(x=500, y=150)
# ----number Buttons------
def enternumber(x):
global entry_1
setval = StringVar()
setval = str(x)
# print(setval)
entry_1.insert(END, setval)
btn_numbers = []
for i in range(10):
btn_numbers.append(
Button(top, width=8, height=3, text=str(i), bd=6, command=lambda x=i: enternumber(x)))
btn_text = 1
for i in range(0, 3):
for j in range(0, 3):
btn_numbers[btn_text].place(x=220 + j * 140, y=250 + i * 100)
btn_text += 1
btn_zero = Button(top, width=15, height=2, text='0', bd=5, command=lambda x=0: enternumber(x))
btn_zero.place(x=330, y=550)
clear = Button(top, text="Clear", bg="green", fg="white", width=8, height=3, command=cleartxtfield)
clear.place(x=220, y=550)
okbtn = Button(top, text="Enter", bg="green", fg="black", width=8, height=3, command=getcreds)
okbtn.place(x=500, y=550)
val = getcreds()
print("The value to be returned is %s" % val)
return val
password = pin_input()
print("Gotten password is %s" % password)
copy_of_image = Image.open("image.png")
photoimage = ImageTk.PhotoImage(copy_of_image)
label = Label(self, image=photoimage)
label.place(x=0, y=0, relwidth=1, relheight=1)
label.bind('<Configure>', resize_image)
top_left_frame = Frame(self, relief='groove', borderwidth=2)
top_left_frame.place(relx=1, rely=0.1, anchor=NE)
center_frame = Frame(self, relief='raised', borderwidth=2)
center_frame.place(relx=0.5, rely=0.75, anchor=CENTER)
Button(top_left_frame, text='REGISTER', bg='grey', width=14, height=1,
command=lambda: controller.show_frame(Register_new_user)).pack()
Button(center_frame, text='ENTER', fg='white', bg='green', width=13, height=2,
command=lambda: controller.show_frame(Register_new_user)).pack()
if __name__ == '__main__':
app = SeaofBTCapp()
app.title("Password return on topview window")
width = 1000
height = 700
screenwidth = app.winfo_screenwidth()
screenheight = app.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
app.geometry(alignstr)
# app.resizable(width=False, height=False)
app.resizable(width=True, height=True)
app.mainloop()
If I understand this correctly you want to enter a password in a dialog and then get the password from the dialog when you close it.
Have a look at Dialog Windows at effbot for a discussion about creating dialog windows.
Here is an example of how you can implement a simple dialog:
from tkinter import *
from tkinter import simpledialog
class MyDialog(simpledialog.Dialog):
def body(self, master):
'''create dialog body.
return widget that should have initial focus.
This method should be overridden, and is called
by the __init__ method.'''
Label(master, text='Value:').grid(row=0)
self.e1 = Entry(master)
self.e1.grid(row=0, column=1)
return self.e1 # initial focus
def apply(self):
'''process the data
This method is called automatically to process the data, *after*
the dialog is destroyed. By default, it does nothing.'''
value = self.e1.get()
self.result = value
def validate(self):
'''validate the data
This method is called automatically to validate the data before the
dialog is destroyed. By default, it always validates OK.'''
return 1 # override
def buttonbox(self):
'''add standard button box.
override if you do not want the standard buttons
'''
box = Frame(self)
w = Button(box, text="OK", width=10, command=self.ok, default='active')
w.pack(side='left', padx=5, pady=5)
w = Button(box, text="Cancel", width=10, command=self.cancel)
w.pack(side='left', padx=5, pady=5)
self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)
box.pack()
if __name__ == '__main__':
root = Tk()
root.geometry('200x100+800+50')
def do():
d = MyDialog(root)
print(d.result)
b = Button(root, text='Go!', width=10, command=do)
b.pack(expand=True)
Did that answer your question?

Is there good way to save text input from tkinter Text widget

I was building, a receipt using Tkinter in Text widgets, it is well-formatted in GUI
but when I save that it becomes like this
There is so much disorder in the text file
How can I get a text formatted like one in GUI, in text file ???
here is my code.
from tkinter import *
from tkinter.filedialog import asksaveasfilename
from tkinter.messagebox import askyesno
# ------------
app = Tk()
# =================== frames ========================
frame1 = Frame(app)
frame1.pack(side=TOP)
# ----
title_label = Label(frame1, text="Facture", font=("courier", 40, 'bold'))
title_label.pack()
# ----
frame2 = Frame(app, bd=5)
frame2.pack(side=TOP)
# ----
frame3 = Frame(app)
frame3.pack(side=TOP)
# ============================================
# ======--- text field -----======
text_input = Text(frame2, width=47, height=25, bg="aliceblue", fg='black', font=("arial", 14, 'bold'))
text_input.pack()
# ============ in text field ===============
text_input.insert(END, f'--------------------------------- Facture ---------------------------------\n')
text_input.insert(END, f"\nQty " + f"Product" + f" PU" + f" PV/TVAC" + f'\n')
text_input.insert(END, f"\n1 " + f"FANTA CITRON" + f" 2500" + f" 2500")
text_input.insert(END, f"\n1 " + f"BUFFET PER HEAD" + f" 10000" + f" 10000")
text_input.insert(END, f"\n1 " + f"MUKEKE GRILLE OIGNONS" + f"16000" + f" 16000" + f'\n')
text_input.insert(END, f"\nTOTAL" + f" 28500")
# --------- functions ---------
def save():
filepath = asksaveasfilename(
defaultextension = "csv",
filetypes = [("Text Files", "*.csv"), ("All Files", "*.*")])
if not filepath:
return
with open(filepath, 'w') as output_file:
text = text_input.get('1.0', END)
output_file.write(text)
def printR():
pass
def delete():
text_input.delete('1.0', END)
def exit():
iExit = askyesno("Attention", "You are on your way to quit\nAre you sure you want quit")
if iExit > 0:
app.destroy()
# ----------------------------------
# ============---------------===============
# =====--------- Buttons -----------========
save_button = Button(frame3, text="Save", height=3, width=10, command=save)
save_button.grid(row=0, column=0, padx=2)
# ----------------
print_button = Button(frame3, text="Print", height=3, width=10, command=printR)
print_button.grid(row=0, column=1, padx=2)
# ----------------
delete_button = Button(frame3, text="Delete", height=3, width=10, command=delete)
delete_button.grid(row=0, column=2, padx=2)
# ----------------
quit_button = Button(frame3, text="Exit", height=3, width=10, command=exit)
quit_button.grid(row=0, column=3, padx=2)
# ============================================
app.mainloop()
.........................
.........................
.........................
.........................
I think that the problem is that the "Text" is formatted well only using the Tkfixedfont font.
I made some changes, replaced the format type, deleted the bold and size and used the format() function to align the text.
from tkinter import *
from tkinter.filedialog import asksaveasfilename
from tkinter.messagebox import askyesno
# ------------
app = Tk()
# =================== frames ========================
frame1 = Frame(app)
frame1.pack(side=TOP)
# ----
title_label = Label(frame1, text="Facture", font=("courier", 40, 'bold'))
title_label.pack()
# ----
frame2 = Frame(app, bd=5)
frame2.pack(side=TOP)
# ----
frame3 = Frame(app)
frame3.pack(side=TOP)
# ============================================
# ======--- text field -----======
text_input = Text(frame2,bg="aliceblue", fg='black', font=('TkFixedFont'))
text_input.pack(expand = True)
# ============ in text field ===============
header = "{0} {1} {2}\n".format("-"*35,"Facture", "-"*35)
text_input.insert(END, header)
fields = "{0:10}{1:40}{2:20}{3:8}\n".format("Qty", "Product", "PU", "PV/TVAC")
text_input.insert(END, fields)
rs = (("1", "FANTA CITRON", "2500", "2500"),
("1", "BUFFET PER HEAD", "10000", "10000"),
("1", "MUKEKE GRILLE OIGNONS", "16000", "16000"),)
for i in rs:
fields = "{0:10}{1:40}{2:20}{3:10}\n".format(i[0], i[1], i[2], i[3])
text_input.insert(END, fields)
footer = "{0:70}{1}".format("TOTAL","28500")
text_input.insert(END, footer)
# --------- functions ---------
def save():
filepath = asksaveasfilename(
defaultextension = "csv",
filetypes = [("Text Files", "*.csv"), ("All Files", "*.*")])
if not filepath:
return
with open(filepath, 'w') as output_file:
text = text_input.get('1.0', END)
output_file.write(text)
def printR():
pass
def delete():
text_input.delete('1.0', END)
def exit():
iExit = askyesno("Attention", "You are on your way to quit\nAre you sure you want quit")
if iExit > 0:
app.destroy()
# ----------------------------------
# ============---------------===============
# =====--------- Buttons -----------========
save_button = Button(frame3, text="Save", height=3, width=10, command=save)
save_button.grid(row=0, column=0, padx=2)
# ----------------
print_button = Button(frame3, text="Print", height=3, width=10, command=printR)
print_button.grid(row=0, column=1, padx=2)
# ----------------
delete_button = Button(frame3, text="Delete", height=3, width=10, command=delete)
delete_button.grid(row=0, column=2, padx=2)
# ----------------
quit_button = Button(frame3, text="Exit", height=3, width=10, command=exit)
quit_button.grid(row=0, column=3, padx=2)
# ============================================
app.mainloop()

Tkinter - Canvas in new window and the image resize to the new window resolution

I'm trying to do a Canvas that display a picture in a new window with a pressing a button, actually that is working, but I need the display that show the image in the new windows resize to the new window dimension.
I already tried to manage to get the size to an specific but nothing really worked out for me.
Here is the code:
from tkinter import *
import requests
import shutil
from xml.dom.minidom import parse
import fileinput
import os.path as path
import os
import tempfile
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
root = Tk()
root.title("Etiquetas")
root.configure(width=1280,height=720)
root.geometry('{}x{}'.format(427, 600))
root.resizable(width=False, height=False)
canvas = Canvas(root, width=500, height=500)
canvas.pack(fill="both", expand=True)
my_image = PhotoImage(file='label.png')
def new_winF(): # new window definition
newwin = Toplevel(root)
display = Label(newwin, text="Humm, see a new window !")
display.pack()
def retrieve_input():
f = open('DataXML.xml', 'w+')
f.truncate(0)
inputParamString = ParamString.get("1.0","end-1c")
inputAlto = Alto.get("1.0","end-1c")
inputAncho = Ancho.get("1.0","end-1c")
inputTemplateLabel = TemplateLabel.get("1.0","end-1c")
#StringEtiqueta = open("DataXML.xml", "a+")
f.write(inputParamString)
f.close()
doc = parse("DataXML.xml")
my_node_list = doc.getElementsByTagName("label_param")
LabelResultado = open("Template.txt", "w")
LabelResultado.write(inputTemplateLabel)
LabelResultado.close()
for node in my_node_list:
name_node = node.getElementsByTagName("name")
value_node = node.getElementsByTagName("value")
y = ("[" + name_node[0].firstChild.data + "]")
z = y.upper()
print(z)
if (value_node[0].firstChild != None):
print(value_node[0].firstChild.data)
x = value_node[0].firstChild.data
else:
print("")
x = ""
with fileinput.FileInput("Template.txt", inplace=True) as file:
for line in file:
print(line.replace(z, x), end='')
w = open('Template.txt.bak', 'w+')
w.close()
codigoZPL = open("Template.txt", "r")
zpl = codigoZPL.read()
codigoZPL.close()
url = ('http://api.labelary.com/v1/printers/8dpmm/labels/'+inputAlto+'x'+inputAncho+'/0/')
files = {'file': zpl}
#headers = {'Accept': 'application/pdf'}
response = requests.post(url, headers=0, files=files, stream=True)
if response.status_code == 200:
response.raw.decode_content = True
with open('label.png', 'wb') as out_file: # change file name for PNG images
shutil.copyfileobj(response.raw, out_file)
else:
print('Error: ' + response.text)
newwin = Toplevel(root)
ncanvas = Canvas(newwin, width=500, height=500)
canvas.pack(fill="both", expand=True)
my_image = PhotoImage(file='label.png')
display = canvas.create_image(850, 50, anchor=NE, image=my_image)
line = canvas.create_line(0, 0, 0, 0)
display.pack()
root.mainloop()
def click_limpiar():
Alto.delete(0.0, END)
Ancho.delete(0.0, END)
ParamString.delete(0.0, END)
TemplateLabel.delete(0.0, END)
def close_window():
root.destroy()
exit()
#Crear un label
Label (text="Ingresar ParamString: ") .place(x=10,y=15)
Label (text="Ingresar TamaƱo (pulgadas): ") .place(x=10,y=160)
Label (text="Ingresar TemplateLabel: ") .place(x=10,y=218)
#Crear un textbox
ParamString = Text(root)
ParamString.pack()
ParamString.place(x=12, y=50, height=100, width=400)
Alto = Text(root)
Alto.pack()
Alto.place(x=12, y=190, height=20, width=20)
Ancho = Text(root)
Ancho.pack()
Ancho.place(x=52, y=190, height=20, width=20)
TemplateLabel = Text(root)
TemplateLabel.pack
TemplateLabel.place(x=12, y=250, height=300, width=400)
#Botones
Button(root, text="Aceptar", width=16, command=retrieve_input) .place(x=20,y=560)
Button(root, text="Limpiar", width=16, command=click_limpiar) .place(x=150,y=560)
Button(root, text="Salir", width=16, command=close_window) .place(x=280,y=560)
app = Window(root)
root.mainloop()
The Canvas part is this one:
newwin = Toplevel(root)
ncanvas = Canvas(newwin, width=500, height=500)
canvas.pack(fill="both", expand=True)
my_image = PhotoImage(file='label.png')
display = canvas.create_image(850, 50, anchor=NE, image=my_image)
line = canvas.create_line(0, 0, 0, 0)
display.pack()
Thanks in advance,

How to add background image to my application in Tkinter?

The code picture needs to fit the screen size perfectly. I saw a bunch of tutorials but nothing seems to work.I tried adding a canvas but it covers half the screen.All my buttons go under the image itself not over it. It's getting on my nerves .
here's my code :
import tkinter as tk
import PIL
from PIL import Image, ImageTk
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
root = Tk()
w = Label(root, text="Send and receive files easily")
w.config(font=('times', 32))
w.pack()
def create_window():
window = tk.Toplevel(root)
window.geometry("400x400")
tower= PhotoImage(file="D:/icons/tower.png")
towlab=Button(root,image=tower, command=create_window)
towlab.pack()
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("Bifrost v1.0")
self.pack(fill=BOTH, expand=1)
self.img1 = PhotoImage(file="D:/icons/download.png")
self.img2 = PhotoImage(file="D:/icons/upload.png")
sendButton = Button(self, image=self.img2)
sendButton.place(x=305, y=15)
receiveButton = Button(self, image=self.img1)
receiveButton.place(x=355, y=15)
menu = Menu(self.master)
self.master.config(menu=menu)
file = Menu(menu)
file.add_command(label='Exit', command=self.client_exit)
menu.add_cascade(label='File', menu=file)
edit = Menu(menu)
edit.add_command(label='abcd')
menu.add_cascade(label='Edit', menu=edit)
help = Menu(menu)
help.add_command(label='About Us', command=self.about)
menu.add_cascade(label='Help', menu=help)
def callback():
path = filedialog.askopenfilename()
e.delete(0, END) # Remove current text in entry
e.insert(0, path) # Insert the 'path'
# print path
w = Label(root, text="File Path:")
e = Entry(root, text="")
b = Button(root, text="Browse", fg="#a1dbcd", bg="black", command=callback)
w.pack(side=TOP)
e.pack(side=TOP)
b.pack(side=TOP)
def client_exit(self):
exit()
def about(self):
top = Toplevel()
msg = Message(top, text="This is a project developed by Aditi,Sagar and
Suyash as the final year project.",
font=('', '15'))
msg.pack()
top.geometry('200x200')
button = Button(top, text="Okay", command=top.destroy)
button.pack()
top.mainloop()
root.resizable(0,0)
#size of the window
root.geometry("700x400")
app = Window(root)
root.mainloop()
Overlaying elements is tricky. I think this might be approximately what you're looking for. At least it's a start...
import PIL
from PIL import Image, ImageTk
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
root = Tk()
class Window:
def __init__(self, master=None):
tower = PIL.Image.open("Images/island.png")
master.update()
win_width = int(master.winfo_width())
win_height = int(master.winfo_height())
# Resize the image to the constraints of the root window.
tower = tower.resize((win_width, win_height))
tower_tk = ImageTk.PhotoImage(tower)
# Create a label to hold the background image.
canvas = Canvas(master, width=win_width, height=win_height)
canvas.place(x=0, y=0, anchor='nw')
canvas.create_image(0, 0, image=tower_tk, anchor='nw')
canvas.image = tower_tk
frame = Frame(master)
frame.place(x=win_width, y=win_height, anchor='se')
master.update()
w = Label(master, text="Send and receive files easily", anchor='w')
w.config(font=('times', 32))
w.place(x=0, y=0, anchor='nw')
master.title("Bifrost v1.0")
self.img1 = PhotoImage(file="Images/logo.png")
self.img2 = PhotoImage(file="Images/magnifier.png")
frame.grid_columnconfigure(0, weight=1)
sendButton = Button(frame, image=self.img2)
sendButton.grid(row=0, column=1)
sendButton.image = self.img2
receiveButton = Button(frame, image=self.img1)
receiveButton.grid(row=0, column=2)
receiveButton.image = self.img1
menu = Menu(master)
master.config(menu=menu)
file = Menu(menu)
file.add_command(label='Exit', command=self.client_exit)
menu.add_cascade(label='File', menu=file)
edit = Menu(menu)
edit.add_command(label='abcd')
menu.add_cascade(label='Edit', menu=edit)
help = Menu(menu)
help.add_command(label='About Us', command=self.about)
menu.add_cascade(label='Help', menu=help)
def callback():
path = filedialog.askopenfilename()
e.delete(0, END) # Remove current text in entry
e.insert(0, path) # Insert the 'path'
# print path
w = Label(root, text="File Path:")
e = Entry(root, text="")
b = Button(root, text="Browse", fg="#a1dbcd", bg="black", command=callback)
w.pack(side=TOP)
e.pack(side=TOP)
b.pack(side=TOP)
def client_exit(self):
exit()
def about(self):
message = "This is a project developed by Aditi,Sagar and"
message += "Suyash as the final year project."
messagebox.showinfo("Delete Theme", message)
root.resizable(0,0)
#size of the window
root.geometry("700x400")
app = Window(root)
root.mainloop()

Resources