import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame,text = "Print", command = lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame,height = 5, width = 20)
freek.pack()
input_a = freek.get(1.0, "end-1c")
print(input_a)
fruit = 0
fad = input_a[fruit:fruit+1]
print(fad)
schepje = len(input_a.strip("\n"))
print(schepje)
def zandkasteel():
lbl.config(text = "Ingevulde string: "+input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint()
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text = "")
lbl.pack()
frame.mainloop()
I need to get the string that was entered into the text entry field freek. I have tried to assign that string to input_a, but the string doesn't show up.
Right now, input_a doesn't get anything assigned to it and seems to stay blank. I had the same function working before implementing a GUI, so the problem shouldn't lie with the def zandkasteel.
To be honest I really don't know what to try at this point, if you happen to have any insights, please do share and help out this newbie programmer in need.
Here are some simple modifications to your code that shows how to get the string in the Text widget when it's needed — specifically when the zandkasteel() function gets called in response to the user clicking on the Print button.
import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame, text="Print", command=lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame, height=5, width=20)
freek.pack()
def zandkasteel():
input_a = freek.get(1.0, "end-1c")
print(f'{input_a=}')
fruit = 0
fad = input_a[fruit:fruit+1]
print(f'{fad=}')
schepje = len(input_a.strip("\n"))
print(f'{schepje=}')
lbl.config(text="Ingevulde string: " + input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint(1, 3)
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text="")
lbl.pack()
frame.mainloop()
Im writing a program so i can practise my spanish grammer. I come from the world of PLC programming and wanted to delve into Python to get 2 birds stoned at once. Below is the code, it however gives me an error on the syntax as its missing the var RandomVerbNumber in the on_change def. I have tried defining it outside of the def structures, but it will always make RandomVerbNumber have an incorrect value.
I have tried looking into classes and the init function. But that's not very clear to me yet.
import gspread
import random
import tkinter as tk
gc = gspread.service_account(filename = 'credentials.json')
SpanishVerbs = gc.open('Spanish Verbs')
worksheet = SpanishVerbs.worksheet("EnglishSpanishList")
EnglishList = worksheet.col_values(1)
SpanishList = worksheet.col_values(2)
AmountOfRows = len(worksheet.col_values(1))
def on_next(event):
RandomVerbNumber = random.randint(0,AmountOfRows)
EnglishVerbLabel.config(text = EnglishList[RandomVerbNumber])
print(EnglishList[RandomVerbNumber]," = ",SpanishList[RandomVerbNumber])
def on_change(event):
if SpanishEntry.get() == SpanishList[RandomVerbNumber]:
ResultLabel.config(text = "Correct")
else:
ResultLabel.config(text = "Incorrect")
SpanishEntry.delete(0, tk.END)
root = tk.Tk()
QuestionLabel = tk.Label(root, text = "Spanish Verb for:")
EnglishVerbLabel = tk.Label(root)
ResultLabel = tk.Label(root)
SpanishEntry = tk.Entry(root)
root.bind("<Return>", on_change)
buttonNext = tk.Button(root, text="Next", fg="black")
buttonNext.bind("<Button-1>", on_next)
QuestionLabel.grid(row=0, sticky=tk.E)
EnglishVerbLabel.grid(row=0, column=1)
SpanishEntry.grid(row=1, columnspan=2)
buttonNext.grid(row=2, columnspan=2)
ResultLabel.grid(row=3, columnspan=2)
root.mainloop()
RandomVerbNumber is not defined in the function on_change. Why do you think it would be defined?
There does exist a variabel RandomVerbNumber in another function, but that's outside of the scope of on_change. Variables only exists within their scope.
You can pass a randomised array defined in main as an argument into both methods, holding the index values of the words and pop the index value in the on_next method. Your edited code is below, my edits are marked with NOTE tags.
This method works because python lists are passed by reference.
import gspread
import random
import tkinter as tk
gc = gspread.service_account(filename = 'credentials.json')
SpanishVerbs = gc.open('Spanish Verbs')
worksheet = SpanishVerbs.worksheet("EnglishSpanishList")
EnglishList = worksheet.col_values(1)
SpanishList = worksheet.col_values(2)
AmountOfRows = len(worksheet.col_values(1))
#NOTE:
randomisedList = random.sample(range(AmountOfRows), AmountOfRows)
#NOTE: event argument removed
def on_next(list):
EnglishVerbLabel.config(text = EnglishList[RandomVerbNumber])
print(EnglishList[RandomVerbNumber]," = ",SpanishList[RandomVerbNumber])
list.pop()
#NOTE: event argument removed
def on_change(list):
#NOTE:
if SpanishEntry.get() == SpanishList[list[-1]]:
ResultLabel.config(text = "Correct")
else:
ResultLabel.config(text = "Incorrect")
SpanishEntry.delete(0, tk.END)
root = tk.Tk()
QuestionLabel = tk.Label(root, text = "Spanish Verb for:")
EnglishVerbLabel = tk.Label(root)
ResultLabel = tk.Label(root)
SpanishEntry = tk.Entry(root)
#NOTE:
root.bind("<Return>", lambda event, list=randomisedList: on_change(list))
buttonNext = tk.Button(root, text="Next", fg="black")
#NOTE:
buttonNext.bind("<Button-1>", lambda event, list=randomisedList: on_next(list))
QuestionLabel.grid(row=0, sticky=tk.E)
EnglishVerbLabel.grid(row=0, column=1)
SpanishEntry.grid(row=1, columnspan=2)
buttonNext.grid(row=2, columnspan=2)
ResultLabel.grid(row=3, columnspan=2)
root.mainloop()
I have the following work in progress code where I am trying to have a user input a date from a calendar, but I am very new to using tkinter,tkcalendar so I am not sure how to get the input to store as a variable that I can pass along to use elsewhere:
def addGameTimeInfo():
#week_number = input('Enter the week number of this game:')
#game_date = input('Enter the date for this game(YYYY/MM/DD):')
#season_number = input('Enter Season Number for this game:')
def calendar_view():
def print_sel():
print(cal.selection_get())
top = Toplevel(root)
cal = Calendar(top,
font="Arial 14", selectmode='day',
cursor="hand1")
cal.pack(fill="both", expand=True)
ttk.Button(top, text="ok", command=print_sel).pack()
def dateentry_view():
def print_sel(e):
print(cal.get_date())
top = Toplevel(root)
ttk.Label(top, text = 'Choose date').pack(padx=10,pady=10)
cal = DateEntry(top, width=12, background = 'darkblue',
foreground ='white',borderwidth=2)
cal.pack(padx=10,pady=10)
cal.bind('<<DateEntrySelected>>',print_sel)
root = Tk()
s = ttk.Style(root)
s.theme_use('clam')
ttk.Button(root, text = 'Calendar',command=calendar_view).pack(padx=10,pady=10)
ttk.Button(root,text='DateEntry',command=dateentry_view).pack(padx=10,pady=10)
root.mainloop()
I saw this being discussed in another post but I can not comment as I am a new user, otherwise I would have posted there. Thank you!
I am trying to use a ttk.notebook in python3 on a Linux (Ubuntu 14.04LTS) system to read Blockquote`# -- coding: utf-8 --data from experiments and perform several curve fits on this data in order to calculate the coefficients needed for a Finite Element calculation.
The actual calculation of these curves I have already performed without tkinter. I am now setting up the user interface.
All works well, until I want to fill in the variable a as global variable, noting is exported to the Ipython shell (using spyder2). The variables: CreepData and path2 which are made global in the same way are visble in the Ipython shell.
I am not sure if the way I am extracting values from the combo boxes or the Entry fields on the notebook page select units and run work in the intended way.
See the code below:
""" Created on Sat Jan 16 18:56:16 2016
#author: peterk
Derived frpm a lot of posted examples """ import csv from copy import
deepcopy import numpy as np import matplotlib import scipy import
matplotlib matplotlib.use("TkAgg") from
matplotlib.backends.backend_tkagg import
FigureCanvasTkAgg,NavigationToolbar2TkAgg from matplotlib.figure
import Figure from matplotlib import pyplot as plt from scipy import
stats from scipy.optimize import curve_fit from tkinter import *
import tkinter as tk import tkinter.font as tkFont import tkinter.ttk
as ttk from tkinter import filedialog path2="./creep.csv"
class CreepNotebook(ttk.Frame):
def __init__(self, isapp=True, name='notebookdemo'):
ttk.Frame.__init__(self, name=name)
self.pack(expand=True, fill="both")
self.master.title('Creep fit')
self.isapp = isapp
self._create_widgets()
self.master.minsize(1920,1000)
def _create_widgets(self):
self._create_main_panel()
def _create_main_panel(self):
mainPanel = ttk.Frame(self, name='demo')
mainPanel.pack( expand=True, side="top", fill="both")
# create the notebook
nb = ttk.Notebook(mainPanel, name='notebook')
# extend bindings to top level window allowing
# CTRL+TAB - cycles thru tabs
# SHIFT+CTRL+TAB - previous tab
# ALT+K - select tab using mnemonic (K = underlined letter)
nb.enable_traversal()
nb.pack(fill="both", padx=2, pady=3,expand=True)
self._create_readme_tab(nb)
self._create_import_data_tab(nb)
self._create_select_units_run_tab(nb)
self._create_text_tab(nb)
def _create_readme_tab(self, nb):
# frame explaining the app
frame = ttk.Frame(nb, name='readMeFirst')
# widgets to be displayed on 'Description' tab
msg = ["Ttk is the new Tk themed widget set. One of the widgets ",
"it includes is the notebook widget, which provides a set ",
"of tabs that allow the selection of a group of panels, ",
"each with distinct content. They are a feature of many ",
"modern user interfaces. Not only can the tabs be selected ",
"with the mouse, but they can also be switched between ",
"using Ctrl+Tab when the notebook page heading itself is ",
"selected. Note that the second tab is disabled, and cannot "
"be selected."
" aaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"dddddd",
"eeeee",
"f",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
" here is text too"]
lbl = ttk.Label(frame, wraplength='4i', justify=tk.LEFT, anchor=tk.CENTER,
text=''.join(msg))
neatVar = tk.StringVar()
btn = ttk.Button(frame, text='Neat!', underline=0,
command=lambda v=neatVar: self._say_neat(v))
neat = ttk.Label(frame, textvariable=neatVar, name='neat')
# position and set resize behaviour
lbl.grid(row=0, column=0, columnspan=2, sticky='new', pady=5)
btn.grid(row=1, column=0, pady=(2,4))
neat.grid(row=1, column=1, pady=(2,4))
frame.rowconfigure(1, weight=1)
frame.columnconfigure((0,1), weight=1, uniform=1)
# bind for button short-cut key
# (must be bound to topplevel window)
self.winfo_toplevel().bind('<Alt-n>', lambda e, v=neatVar: self._say_neat(v))
# add to notebook (underline = index for short-cut character)
nb.add(frame, text='ReadMeFirst', underline=0, padding=2)
def _say_neat(self, v):
v.set('Yeah, I know...')
self.update()
self.after(500, v.set(''))
# return path2
# =============================================================================
def _create_import_data_tab(self, nb):
# Populate the second pane.
frame = ttk.Frame(nb, name="import data")
global l
global k
global sigma
global creepData
global filen
global path2
butn=ttk.Button(frame, text='select csv file', command=self.askopenfilename2)
butn.pack(side="top")
self.file_opt = options = {}
options['defaultextension'] = '.csv'
options['filetypes'] =[('csv files', '.csv'),('all files', '.*')]
options['initialdir'] = '.'
options['initialfile'] = 'creep2.csv'
options['parent'] = nb
options['title'] = 'Select csv file'
global creepData
print("path2 in _create_import_data_tab")
print (path2)
nb.add(frame, text='Import data', underline=0)
def askopenfilename2(self):
global path2
global creepData
path2 = filedialog.askopenfilename(**self.file_opt)
print("path2 in askopenfilename2")
print(path2)
creepReader=csv.reader(open(path2, newline=""), delimiter=',')
creepData=list(creepReader)
#enter code here
========================================
def _create_text_tab(self, nb):
# populate the third frame with a text widget
frame = ttk.Frame(nb)
txt = tk.Text(frame, width=40, height=10)
vscroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=txt.yview)
txt['yscroll'] = vscroll.set
vscroll.pack(side=tk.RIGHT)
# txt.pack(tk.fill=BOTH, tk.expand=True)
txt.pack() # btn2l.pack(side="top", pady=5)
# btn2.pack(side="top", pady=2)
# w.pack(side="top", pady=2)
# neatVar = tk.StringVar()
# btn = ttk.Button(frame, text='Neat!', underline=0,
# command=lambda v=neatVar: self._say_neat(v))
# neat = ttk.Label(frame, textvariable=neatVar, name='neat')
# def _say_neat(self, v):
# v.set('Yeah, I know...')
# self.update()
# self.after(500, v.set(''))
# add to notebook (underline = index for short-cut character)
nb.add(frame, text='Text Editor', underline=0)
#============================================================
def _create_select_units_run_tab(self, nb):
# select units and perform the calculation
frame = ttk.Frame(nb, name="select units and calculate")
global l
global k
global sigma
global creepData
global a
a=tk.StringVar()
frame.grid(column=0, row=0, rowspan=12, columnspan=5,sticky=(N,S,E,W))
units = ('m,kg,s', 'mm,Mg,s', 'mm,kg,ms')
a=tk.StringVar()
cbl0 = ttk.Label(frame, text='Select or fill in the required fields and push the run button')
cbl1 = ttk.Label(frame, text='Select units used in your FE-prgram')
cb1 = ttk.Combobox(frame, value=units, state='readonly')
# cbl1.pack(side="top")
# cb1.pack(side="top")
time_units=('hrs', 's','ms')
cbl2=ttk.Label(frame, text='Select time units used in the csv file')
cb2 = ttk.Combobox(frame, value=time_units, state='readonly')
# cbl2.pack(side="top")
# cb2.pack(side="top")
strain_units=('strain [%]', 'strain [-]','CreepModulus [MPa]')
cbl3=ttk.Label(frame, text='Select strain or modulus units used in the csv file')
cb3 = ttk.Combobox(frame, value=strain_units, state='readonly')
# cbl3.pack(side="top")
# cb3.pack(side="top")
yml=ttk.Label(frame, text=' Input Anisotropic Youngs Modulus in MPa')
ym=Entry(frame)
# yml.pack(side="top")
# ym.pack(side="top")
isfl=ttk.Label(frame, text='Input Isotropic factor')
isf=Entry(frame)
# isfl.pack(side="top")
# isf.pack(side="top")
run1Var = tk.StringVar()
btn2 = ttk.Button(frame, text='Run', underline=0,
command=lambda w=run1Var: self._run1(w))
btn2l = ttk.Label(frame, textvariable=run1Var, name='run1')
cbl0.grid(column=0, row=0, sticky=W, pady=100)
cbl1.grid(column=6, row=1, sticky=W, pady=25)
cb1.grid(column=6, row=2, sticky=W, pady=2)
cbl2.grid(column=6, row=3, sticky=W, pady=25)
cb2.grid(column=6, row=4, sticky=W, pady=2)
cbl3.grid(column=6, row=5, sticky=W, pady=25)
cb3.grid(column=6, row=6, sticky=W, pady=2)
yml.grid(column=6, row=7, sticky=W, pady=25)
ym.grid(column=6, row=8, sticky=W ,pady=2)
isfl.grid(column=6, row=9, sticky=W, pady=25)
isf.grid(column=6, row=10, sticky=W, pady=2)
btn2l.grid(column=6, row=11, sticky=W, pady=25)
btn2.grid(column=6, row=12, sticky=W, pady=2)
nb.add(frame, text='Select data and run', underline=0, padding=2)
a=cb1.get()
print(a)
print(cb1.get())
yms=ym.get()
isfs=isf.get()
def _run1(self, w):
# global CreepData
# global creepDat
# creepDat=deepcopy(creepData)
w.set('CreepData is copied')
self.update()
self.after(500, w.set(''))
#===================================================================
if __name__ == '__main__':
CreepNotebook().mainloop()`
If needed I can upload the csv.files on my repro, but I do not think it is needed for answering the question. The run1 function would be used to fit the data curves and return a message that the calculations were performed.
CHANGED - sorry I did not initially understand your question, prehaps this is more helpful:
first I'd recommend taking a look at both of these:
when to use global statement
Share variables between methods
second, you are creating the input entries in _create_select_units_run_tab and then you do:
def _create_select_units_run_tab:
...
a = cb1.get()
...
this will get the contents immediately after being created and even before .mainloop() is called so it will absolutely always be an empty string, in order to get the content later in _run1 you need to keep track of the entries instead:
def _create_select_units_run_tab:
...
self.input_fields = [cb1,cb2,cb3,ym,isf]
#this will give all other methods access to the input fields
#then to get them back you can use this:
def get_inputs(self):
return [entry.get() for entry in self.input_fields]
#then in run you can get the data in the fields
def _run1(self, w):
inp_data = self.get_inputs()
print(inp_data)
if "" in inp_data:
w.set("you need to fill everthing in first!")
else:
w.set(str(inp_data))
...
While testing the code I cancelled the file dialog window which threw an error because path2 == "" so you may want a check:
def askopenfilename2(self):
...
if path2 is not "":
creepReader=csv.reader(open(path2, newline=""), delimiter=',')
creepData = list(creepReader)
#else:
# creepData = None # or just leave it as the last used value?
...
not to mention the open() is never closed (Input and Output Python documentation):
It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent `try-finally` blocks:
with open('workfile', 'r') as f:
... read_data = f.read()
>>> f.closed
True
So you may want to implement that too:
with open(path2, newline="") as file_obj:
creepReader=csv.reader(file_obj, delimiter=',')
Lastly I'd like to draw attention to:
self.after(500,w.set('')
w.set('') is being called immediately and using the return value None in self.after, to instead call w.set with the argument you need to do this:
self.after(500,w.set,'')
then tkinter will call it after 500ms forwarding any extra arguments it receives in after
There may be other issues with your code that I missed but I hope this helped.
I would like to ask how would I go about maybe creating a 'LIVE' text box in python? This program is a simulator for a vending machine (code below). I want there to be a text box showing a live credit update How do you do that in tkinter?
For Example: Say there is a box for credit with 0 inside it in the middle of the window. When the 10p button is pressed the box for credit should change from '0' to '0.10'.
Is it possible to do thit in tkinter and python 3.3.2?
Thank you in advance!
import sys
import tkinter as tk
credit = 0
choice = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
def addTENp():
global credit
credit+=0.10
def addTWENTYp():
global credit
credit+=0.20
def addFIFTYp():
global credit
credit+=0.50
def addPOUND():
global credit
credit+=1.00
def insert():
insert = Tk()
insert.geometry("480x360")
iLabel = Label(insert, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
tenbutton = Button(insert, text="10p", command = addTENp).grid(row=2, column=1)
twentybutton = Button(insert, text="20p", command = addTWENTYp).grid(row=3, column=1)
fiftybutton = Button(insert, text="50p", command = addFIFTYp).grid(row=4, column=1)
poundbutton = Button(insert, text="£1", command = addPOUND).grid(row=5, column=1)
insert()
Sure you can! Just add another label to the frame, and update the text attribute whenever one of your add functions is called. Also, you can simplify that code, using one add function for all the different amounts.
def main():
frame = Tk()
frame.geometry("480x360")
Label(frame, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
display = Label(frame, text="") # we need this Label as a variable!
display.grid(row=2, column=1)
def add(amount):
global credit
credit += amount
display.configure(text="%.2f" % credit)
Button(frame, text="10p", command=lambda: add(.1)).grid(row=3, column=1)
Button(frame, text="20p", command=lambda: add(.2)).grid(row=4, column=1)
Button(frame, text="50p", command=lambda: add(.5)).grid(row=5, column=1)
Button(frame, text="P1", command=lambda: add(1.)).grid(row=6, column=1)
frame.mainloop()
main()
Some more points:
note that you define many of your variables twice
you should not give a variable the same name as a function, as this will shadow the function
probably just a copy paste error, but you forgot to call mainloop and your tkinter import is inconsistent with the way you use the classes (without tk prefix)
you can do the layout right after creating the GUI elements, but note that in this case not the GUI element will be bound to the variable, but the result of the layouting function, which is None
Borrowing a framework from tobias_k's excellent answer, I would recommend you use a DoubleVar instead.
from tkinter import ttk
import tkinter as tk
def main():
frame = Tk()
frame.geometry("480x360")
credit = tk.DoubleVar(frame, value=0)
# credit = tk.StringVar(frame, value="0")
ttk.Label(frame, textvariable = credit).pack()
def add_credit(amt):
global credit
credit.set(credit.get() + amt)
# new_credit = str(int(credit.get().replace(".",""))+amt)
# credit.set(new_credit[:-2]+"."+new_credit[-2:])
ttk.Button(frame, text="10p", command = lambda: add_credit(0.1)).pack()
# ttk.Button(frame, text="10p", command = lambda: add_credit(10)).pack()
ttk.Button(frame, text="20p", command = lambda: add_credit(0.2)).pack()
# ttk.Button(frame, text="20p", command = lambda: add_credit(20)).pack()
ttk.Button(frame, text="50p", command = lambda: add_credit(0.5)).pack()
# ttk.Button(frame, text="50p", command = lambda: add_credit(50)).pack()
ttk.Button(frame, text="P1", command = lambda: add_credit(1.0)).pack()
# ttk.Button(frame, text="P1", command = lambda: add_credit(100)).pack()
frame.mainloop()
The comments in that code is an alternate implementation that will work better, if only just. This will guarantee you won't have any strange floating-point errors in your code.