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()
Related
I want button 1 on to the second frame
from tkinter import *
root =Tk()
class Graphic():
def __init__(self, master):
self.colour = "blue"
self.frame_input = Frame(master, height =100, width=100, bg="green").grid(row=0, column=0)
self.label_process = Label(master, width=30).grid(row=1, column=0)
self.frame_button = Frame(master,height=100,width=100, bg="red").grid(row=2, column=0)
self.button = Button(master, text="1", bg=self.colour).grid(row=0, column=0)
if '__main__' == __name__:
grafic = Graphic(root)
root.mainloop()
The first argument for each widget is the parent to attach to. You told it to attach to master, and it did. If you want it attached to the second frame, change:
self.button = Button(master, text="1", bg=self.colour).grid(row=0, column=0)
to:
self.button = Button(self.frame_button, text="1", bg=self.colour)
self.button.grid(row=0, column=0)
Note, this still doesn't work, because you tried to chain your grid calls, and grid returns None, so all your attributes (including self.frame_button) are None, not widgets. To fix, split the creation and layout steps for all your widgets:
self.frame_input = Frame(master, height =100, width=100, bg="green")
self.frame_input.grid(row=0, column=0)
self.label_process = Label(master, width=30)
self.label_process.grid(row=1, column=0)
self.frame_button = Frame(master,height=100,width=100, bg="red")
self.frame_button.grid(row=2, column=0)
self.button = Button(self.frame_button, text="1", bg=self.colour)
self.button.grid(row=0, column=0)
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()
I am having an issue getting text to show on Tkinter buttons. I don't get any errors so im not sure why this is the case, I will post the full working code below if anyone can see any obvius errors.I have never had any problems with button labels before but I am trying a new layout with dropdown tabs so this could be a reason for the issue.
import tkinter as tk
from tkinter import ttk
class ToggledFrame(tk.Frame):
def __init__(self, parent, text="", *args, **options):
tk.Frame.__init__(self, parent, *args, **options)
root.state('zoomed')
root.configure(background='black')
root.title("Stylibleue dashboard")
self.show = tk.IntVar()
self.show.set(0)
self.title_frame = ttk.Frame(self)
self.title_frame.pack(fill="x", expand=1)
ttk.Label(self.title_frame, text=text).pack(side="left", fill="x")
self.toggle_button = ttk.Checkbutton(self.title_frame, width=1, text='+',
command=self.toggle,
variable=self.show, style='Toolbutton')
self.toggle_button.pack(side="left", fill="x", expand=1)
self.sub_frame = tk.Frame(self, relief="sunken", borderwidth=1)
def toggle(self):
if bool(self.show.get()):
self.sub_frame.pack(fill="x", expand=1)
self.toggle_button.configure(text='-')
else:
self.sub_frame.forget()
self.toggle_button.configure(text='+')
def helloCallBack (self):
print ("hello")
if __name__ == "__main__":
root = tk.Tk()
t = ToggledFrame(root, text='Bassin 1', relief="raised")
t.pack(fill="x", anchor="s")
B = ttk.Button(t.sub_frame, text ='Feeder 1',command = quit)
ttk.Button(t.sub_frame).pack( expand=0, pady=2, padx=2, anchor="w")
c = ttk.Button(t.sub_frame, text ="Feeder 2")
ttk.Button(t.sub_frame).pack(expand=0, pady=2, padx=2, anchor="w")
t2 = ToggledFrame(root, text='Bassin 2', relief="raised")
t2.pack(fill="x")
d = ttk.Button(t2.sub_frame, text ='Feeder 1',command = quit)
ttk.Button(t2.sub_frame).pack( expand=0, pady=2, padx=2, anchor="w")
e = ttk.Button(t2.sub_frame, text ="Feeder 2")
ttk.Button(t2.sub_frame).pack(expand=0, pady=2, padx=2, anchor="w")
root.mainloop()
You are creating 8 buttons but only giving a label to four of them, and it’s the ones without a label that you are calling .pack on. The ones with the label are never added to the window.
I have a small test application using Python tkinter that I got to work. The problem is that it does not exit properly when the "Quit" button is pressed. It is a two-frame tabbed application where I started with the StackOverflow question ttk tkinter multiple frames/windows.
It is now a full example that works, but needs work because it doesn't quit and exit properly. When I press the "Quit" button, it kills the frame for that tab, but the application doesn't quit and exit properly. I have to hit the Window "X" Close icon to close it.
My main question is how (and where?) do I test for the event on either the "Quit" button on the "Feet to Meters" calculator, or the "Cancel/Quit" button on the BMI calculator.
A second question I have is that the design of the application seems inefficient to me, because it creates two widgets "Frame" objects, each with their own set of buttons, including 2 "quit" buttons. How do I put these tabs and frames into a parent window and then add a quit button on that parent window to close the entire application.
I modified the buttons to properly destroy the Frame that the button is in:
Changed button2 "command=self.quit" to "command=self.destroy"
self.button2 = ttk.Button(self, text="Cancel/Quit", command=self.quit).grid(row=3, column=1, sticky=E)
to
self.button2 = ttk.Button(self, text="Cancel/Quit", command=self.destroy).grid(row=3, column=1, sticky=E)
""" Created on Thu Jul 11 17:20:22 2019 """
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class App1(ttk.Frame):
""" This application calculates BMI and returns a value. """
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
#text variables
self.i_height = StringVar()
self.i_weight = StringVar()
self.o_bmi = StringVar()
#labels
self.label1 = ttk.Label(self, text="Enter your weight:").grid(row=0, column=0, sticky=W)
self.label2 = ttk.Label(self, text="Enter your height:").grid(row=1, column=0, sticky=W)
self.label3 = ttk.Label(self, text="Your BMI is:").grid(row=2, column=0, sticky=W)
#text boxes
self.textbox1 = ttk.Entry(self, textvariable=self.i_weight).grid(row=0, column=1, sticky=E)
self.textbox2 = ttk.Entry(self, textvariable=self.i_height).grid(row=1, column=1, sticky=E)
self.textbox3 = ttk.Entry(self, textvariable=self.o_bmi).grid(row=2, column=1, sticky=E)
#buttons
self.button1 = ttk.Button(self, text="Ok", command=self.calculateBmi).grid(row=3, column=2, sticky=E)
## Changed button2 "command=self.quit" to "command=self.destroy"
# self.button2 = ttk.Button(self, text="Cancel/Quit", command=self.quit).grid(row=3, column=1, sticky=E)
self.button2 = ttk.Button(self, text="Cancel/Quit", command=self.destroy).grid(row=3, column=1, sticky=E)
#exitApplication = tk.Button(root, text='Exit Application', command=root.destroy)
#canvas1.create_window(85, 300, window=exitApplication)
def calculateBmi(self):
try:
self.weight = float(self.i_weight.get())
self.height = float(self.i_height.get())
self.bmi = self.weight / self.height ** 2.0
self.o_bmi.set(self.bmi)
except ValueError:
messagebox.showinfo("Error", "You can only use numbers.")
finally:
self.i_weight.set("")
self.i_height.set("")
class App2(ttk.Frame):
""" Application to convert feet to meters or vice versa. """
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""Create the widgets for the GUI"""
# 1 textbox (stringvar)
self.entry= StringVar()
self.textBox1= ttk.Entry(self, textvariable=self.entry).grid(row=0, column=1)
# 5 labels (3 static, 1 stringvar)
self.displayLabel1 = ttk.Label(self, text="feet").grid(row=0, column=2, sticky=W)
self.displayLabel2 = ttk.Label(self, text="is equivalent to:").grid(row=1, column=0)
self.result= StringVar()
self.displayLabel3 = ttk.Label(self, textvariable=self.result).grid(row=1, column=1)
self.displayLabel4 = ttk.Label(self, text="meters").grid(row=1, column=2, sticky=W)
# 2 buttons
self.calculateButton = ttk.Button(self, text="Calculate", command=self.convert_feet_to_meters).grid(row=2, column=2, sticky=(S,E))
self.quitButton = ttk.Button(self, text="Quit", command=self.destroy).grid(row=2, column=1, sticky=(S,E))
#exitApplication = tk.Button(root, text='Exit Application', command=root.destroy)
#canvas1.create_window(85, 300, window=exitApplication)
def convert_feet_to_meters(self):
"""Converts feet to meters, uses string vars and converts them to floats"""
self.measurement = float(self.entry.get())
self.meters = self.measurement * 0.3048
self.result.set(self.meters)
### CODE BELOW COMMENTED OUT WHEN JOINING ORIGINAL POSTER CODE WITH HIS SOLUTION
### It seems no longer relevant since App1 and App2 have their own buttons.
#def button1_click():
# """ This is for the BMI Calculator Widget """
# root = Tk()
# app = App1(master=root)
# app.mainloop()
#
#def button2_click():
# """ This is for the Feet to Meters Conversion Widget """
# root = Tk()
# app = App2(master=root)
# app.mainloop()
#def main():
# window = Tk()
# button1 = ttk.Button(window, text="bmi calc", command=button1_click).grid(row=0, column=1)
# button2 = ttk.Button(window, text="feet conv", command=button2_click).grid(row=1, column=1)
# window.mainloop()
def main():
#Setup Tk()
window = Tk()
#Setup the notebook (tabs)
notebook = ttk.Notebook(window)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
notebook.add(frame1, text="BMI Calc")
notebook.add(frame2, text="Feet to Meters")
notebook.grid()
#Create tab frames
app1 = App1(master=frame1)
app1.grid()
app2 = App2(master=frame2)
app2.grid()
#Main loop
window.mainloop()
if __name__ == '__main__':
main()
The application doesn't quit when the "Quit" button is pressed. Only the individual frames quit.
Thanks to Martineau for the hint that helped me get this example to work. I declared 'window as a global variable, since it was defined in the name space of the class constructors. Without that, there was an error raised of undefined window. This method breaks the encapsulation and modularity of the classes by passing in the window as a global. If there is a better way to do this, I would like to know.
# -*- coding: utf-8 -*-
""" Created on Thu Jul 11 17:20:22 2019
Filename: tkinter-multiple-frames-windows_v3.py
From question on StackOverflow question "ttk tkinter multiple frames/windows"
at https://stackoverflow.com/questions/6035101/ttk-tkinter-multiple-frames-windows?rq=1
Now a full example that works but it needed some modification to clarify how it works.
"""
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class BMICalcApp(ttk.Frame):
""" This application calculates BMI and returns a value. """
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
#text variables
self.i_height = StringVar()
self.i_weight = StringVar()
self.o_bmi = StringVar()
#labels
self.label1 = ttk.Label(self, text="Enter your weight:").grid(row=0, column=0, sticky=W)
self.label2 = ttk.Label(self, text="Enter your height:").grid(row=1, column=0, sticky=W)
self.label3 = ttk.Label(self, text="Your BMI is:").grid(row=2, column=0, sticky=W)
#text boxes
self.textbox1 = ttk.Entry(self, textvariable=self.i_weight).grid(row=0, column=1, sticky=E)
self.textbox2 = ttk.Entry(self, textvariable=self.i_height).grid(row=1, column=1, sticky=E)
self.textbox3 = ttk.Entry(self, textvariable=self.o_bmi).grid(row=2, column=1, sticky=E)
#buttons
self.button1 = ttk.Button(self, text="Ok", command=self.calculateBmi).grid(row=3, column=2, sticky=E)
self.button2 = ttk.Button(self, text="Cancel/Quit", command=window.destroy).grid(row=3, column=1, sticky=E)
def calculateBmi(self):
try:
self.weight = float(self.i_weight.get())
self.height = float(self.i_height.get())
self.bmi = self.weight / self.height ** 2.0
self.o_bmi.set(self.bmi)
except ValueError:
messagebox.showinfo("Error", "You can only use numbers.")
finally:
self.i_weight.set("")
self.i_height.set("")
class ConvertFeetMeters(ttk.Frame):
""" Application to convert feet to meters or vice versa. """
def __init__(self, master=None):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""Create the widgets for the GUI"""
# 1 textbox (stringvar)
self.entry= StringVar()
self.textBox1= ttk.Entry(self, textvariable=self.entry).grid(row=0, column=1)
# 5 labels (3 static, 1 stringvar)
self.displayLabel1 = ttk.Label(self, text="feet").grid(row=0, column=2, sticky=W)
self.displayLabel2 = ttk.Label(self, text="is equivalent to:").grid(row=1, column=0)
self.result= StringVar()
self.displayLabel3 = ttk.Label(self, textvariable=self.result).grid(row=1, column=1)
self.displayLabel4 = ttk.Label(self, text="meters").grid(row=1, column=2, sticky=W)
# 2 buttons
self.calculateButton = ttk.Button(self, text="Calculate", command=self.convert_feet_to_meters).grid(row=2, column=2, sticky=(S,E))
self.quitButton = ttk.Button(self, text="Quit", command=window.destroy).grid(row=2, column=1, sticky=(S,E))
def convert_feet_to_meters(self):
"""Converts feet to meters, uses string vars and converts them to floats"""
self.measurement = float(self.entry.get())
self.meters = self.measurement * 0.3048
self.result.set(self.meters)
def main():
#Setup Tk()
global window
window = Tk()
#Setup the notebook (tabs)
notebook = ttk.Notebook(window)
frame1 = ttk.Frame(notebook)
frame2 = ttk.Frame(notebook)
notebook.add(frame1, text="BMI Calc")
notebook.add(frame2, text="Feet to Meters")
notebook.grid()
#Create tab frames
bmi_calc = BMICalcApp(master=frame1)
bmi_calc.grid()
feet_meters_calc = ConvertFeetMeters(master=frame2)
feet_meters_calc.grid()
#Main loop
window.mainloop()
if __name__ == '__main__':
main()
I am trying to make a simple program using tkinter.
I was trying to change font or style of width or height.
width can be changed but when it comes to height or font - it shows mistake.
I am thinking - maybe it can be because the layout?
(The button that is changed in width is in the bottom of def initUI)
Also in case anyone can also answer this question:
I made 1 frame red because there will be error messages there but does anyone know how to make this red lie less in width?
Thank you in
from tkinter import *
from tkinter.ttk import *
class Example(Frame):
def __init__(self,master):
super().__init__()
master.minsize(width=350, height=160)
master.maxsize(width=650, height=500)
self.initUI()
def initUI(self):
self.master.title("Hank (version 3)")
self.pack(fill=BOTH, expand=True)
frame1 = Frame(self)
frame1.pack(fill=X)
#dataset
lbl1 = Label(frame1, text="Dataset file_name", width=18)
lbl1.pack(side=LEFT, padx=5, pady=5)
entryDataset= Entry(frame1)
entryDataset.pack(fill=X, padx=5, expand=True)
#row col begin
frame2 = Frame(self)
frame2.pack(fill=X)
lblRow = Label(frame2, text="Row", width=6)
lblRow.pack(side=LEFT, padx=5, pady=5)
entryRow = Entry(frame2, width=5)
entryRow.pack(side=LEFT, padx=0, expand=True)
lblCol = Label(frame2, text="Column", width=7.5)
lblCol.pack(side=LEFT, padx=5, pady=5)
entryCol = Entry(frame2, width=5)
entryCol.pack(side=LEFT, padx=5, expand=True)
lblBegin = Label(frame2, text="Start at", width=6)
lblBegin.pack(side=LEFT, padx=5, pady=5)
entryBegin = Entry(frame2, width=5)
entryBegin.pack(side=LEFT, padx=0, expand=True)
#console window
s = Style()
s.configure('My.TFrame', background='grey')
frame3 = Frame(self, style='My.TFrame')
frame3.pack(fill=BOTH, expand=True)
#button start and help
s = Style()
s.configure('My.ConsoleFrame', background='red')
frame4 = Frame(self)
frame4.pack(fill=BOTH, expand=True)
startbutton = Button(frame4, text="Start Clustering", height="100", width="100")
startbutton.pack(side=RIGHT, padx=5, pady=5)
def main():
root = Tk()
root.geometry("300x160+300+160")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
This is one of the prime examples of why global imports are bad.
You write at the top:
from tkinter import *
from tkinter.ttk import *
This means that you import everything from tkinter and tkinter.ttk into your main.py namespace. Then you write for example:
frame3 = Frame(self, bg="grey")
....
lblCol = Label(frame2, text="Column", width=7)
These are Frame/Label objects, but which ones? The one in tkinter or the one in tkinter.ttk? If it is the first, you will have to set the height with -height, else you will have to use tkinter.ttk.Style(). Same with the -bg for the frame.
Solution:
import tkinter as tk
class Example(tk.Frame):
def __init__(self,master):
super().__init__()
master.minsize(width=350, height=160)
master.maxsize(width=650, height=500)
self.initUI()
def initUI(self):
self.master.title("Hank (version 3)")
self.pack(fill=tk.BOTH, expand=True)
frame1 = tk.Frame(self)
frame1.pack(fill=tk.X)
#dataset
lbl1 = tk.Label(frame1, text="Dataset file_name", width=18)
lbl1.pack(side=tk.LEFT, padx=5, pady=5)
entryDataset= tk.Entry(frame1)
entryDataset.pack(fill=tk.X, padx=5, expand=True)
#row col begin
frame2 = tk.Frame(self)
frame2.pack(fill=tk.X)
lblRow = tk.Label(frame2, text="Row", width=6)
lblRow.pack(side=tk.LEFT, padx=5, pady=5)
entryRow = tk.Entry(frame2, width=5)
entryRow.pack(side=tk.LEFT, padx=0, expand=True)
lblCol = tk.Label(frame2, text="Column", width=7)
lblCol.pack(side=tk.LEFT, padx=5, pady=5)
entryCol = tk.Entry(frame2, width=5)
entryCol.pack(side=tk.LEFT, padx=5, expand=True)
lblBegin = tk.Label(frame2, text="Start at", width=6)
lblBegin.pack(side=tk.LEFT, padx=5, pady=5)
entryBegin = tk.Entry(frame2, width=5)
entryBegin.pack(side=tk.LEFT, padx=0, expand=True)
frame3 = tk.Frame(self, bg="grey")
frame3.pack(fill=tk.BOTH, expand=True)
frame4 = tk.Frame(self)
frame4.pack(fill=tk.BOTH, expand=True)
startbutton = tk.Button(frame4, text="Start Clustering", height="100", width="100")
startbutton.pack(side=tk.RIGHT, padx=5, pady=5)
def main():
root = tk.Tk()
root.geometry("300x160+300+160")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
I did it here with the tkinter widgets. You can obviously do import tkinter.ttk as ttk and rewrite the code using those, it is just a matter of taste.