Update Lambda function arguments on button click - python-3.x

I've snipped out parts of the code, as i suspect the answer is quite newbie :)
I am trying to validate the input in the Entry by clicking the button (which references to a validation funciton). However the path_directory-variable are not updated (it keeps the initial value).
How do I update it when the button is clicked?
directory = tk.Entry(entry_frame)
validate_button= tk.Button(paths_frame, text='Next', command=lambda path_directory=directory.get(): self.validate_path(path_directory))
def validate_path(self, path_directory):
if path.exists(path_directory):
print('# Path validation succuessful: ', path_directory)
else:
print('# Path validation failed: ', path_directory)

The problem is that you are getting the value only on lambda init. Simply use a function, not lambda, like this:
def validate_click():
path_directory=directory.get()
self.validate_path(path_directory)
validate_button= tk.Button(paths_frame, text='Next', command=validate_click)
Hope that's helpful!

Related

ValueError: complex() arg is a malformed string

I have to take complex number as an input from Entry widget of tkinter and perform the conjugate operation on that complex number. I applied explicit conversion method but my code is not able to convert Entry widget string into complex number and showing error "ValueError: complex() arg is a malformed string" Can anyone help me?
Thank you in advance.
lbl_shh=Label(second_root,text="Enter parameter Shh",fg="red").grid(column=0,row=7,padx=20,pady=20)
e_shh = Entry(second_root)
lbl_svv=Label(second_root,text="Enter parameter Svv",fg="red").grid(column=0,row=8,padx=20,pady=20)
e_svv = Entry(second_root)
e_shh.grid(column=1,row=7)
e_svv.grid(column=1,row=8)
shh=e_shh.get()
svv=e_svv.get()
shh=shh.replace(" ","")
svv=svv.replace(" ","")
shh=complex(shh)
svv=complex(svv)
#shh=complex(''.join(shh.split()))
#svv=complex(''.join(svv.split()))
shhs=np.conjugate(shh)
svvs=np.conjugate(svv)
num= svv*svvs
dem=shh*shhs
f=np.power(num/dem, 0.25)
I have to print the value of f
I think you misunderstand how to properly get information within tkinter and probably Python in general.
You cannot just use .get() when your code is just initializing. It will always return an empty string unless you have some code that sets the value prior to get and at that point its just redundant to use get.
What you need to do is have some code like a button that will pull the value of your entry(s) after someone has added something to them.
Also I noticed in your example code you have second_root and this leads me to believe you are using 2 instances of Tk() in your code. If that is the case this may also be part of your problem. You should only ever have one instance of Tk() when coding in tkinter.
To ilistrate your problem Take this example:
I added some print statements, a function and a button to show what was actually being grabbed by get() or rather to show it is an empty string. If you do not have anything in the field by the time get() is executed.
And here is an example result from when you put a proper value that complex() can use.
See below example to get an idea of how get() works:
import tkinter as tk
root = tk.Tk()
entry = tk.Entry(root)
entry.pack()
def print_entry():
print(entry.get())
tk.Button(root, text='Print Entry', command=print_entry).pack()
root.mainloop()

Too many positional arguments are given

Hi there smart people,
I have a small program where a combobox should be updated with a new list, depending on a User entry, when a Button is clicked.
Infact I would assume that no arguments need to be given since the called functions "gets" the user entries and then updates the combobox. No additional external Info needed.
Unfortunatley I get the Error:
TypeError:Func_Update_MA() takes 1positional argument but 2 were given.
How can I solve this issue?
To be honest I dont really get the whole "self" thing but I tried pretty much every combination of using self, not using it and combining it with something like args* or kwargs** (another mystery to me)
If you need more code I will provide it off course.
Thanks alot in advance!
class Class_MA_Win():
def __init__(self, Win_MA_Sel, Cockpit_Win):
Btt_Update_MA = Button(self.Mitarbeiter_Selection_Win, text="Liste Updaten")
Btt_Update_MA.bind("<Button-1>",self.Func_Update_MA)
Btt_Update_MA.grid(column=2, row=3, padx=10, pady=10)
def Func_Update_MA(self):
Entry_name = self.Ent_first_name_MA.get()
Entry_lastname = self.Ent_last_name_MA.get()
Entry_ID = self.Ent_ID_MA.get()
Whenever you use widget.bind(...), it will return an event object with a number of attributes describing the event. This is then passed to your func Func_Update_MA which accepts no argument, thus the error.
To solve this, simply accept the event as an arg:
def Func_Update_MA(self,event=None):
...
Also you mentioned about args and kwargs but you seem to wrongly position the asterisks. The correct is *args and **kwargs, like so:
def Func_Update_MA(self, *args, **kwargs):
...

tkinter scrolledtext.insert and label.configuration point of execution

I have the following python36 code wich is checking values, and then set a tkinter label that the entry values has been accepted, to then execute another threaded function. Before and after the function as well as inside the function I would like to display something in a tkinter scrolledtext box. Like it where a console/shell.
All the label.configure() as well as scrolledtext.insert() are only getting displayed all at the same time after everything has been run.
I am not able to use the scrolledtext.insert() inside the threaded function (fundamentals question, could I use it inside a function of an imported module?)
I would like to have the execution time of these functions like if I would use the print() function. So execute it as soon as the script went over it.
It would be nice if you could explain to me why this is not executed immideately since I am currently learning python or point me to the appropriate reference.
elif str(x2) == 'None' and str(x3) == 'None':
E2T = 'accepted'
E2L.configure(text=E2T, fg="green")
E2L.grid(row=5, column=2)
E3T = 'accepted'
E3L.configure(text=E3T, fg="green")
E3L.grid(row=6, column=2)
# Start scanning process
scrolledtext.insert(tkinter.INSERT, 'Start scanning....\n' )
print('testprint')
portlist = scan(E1.get(),E2.get(),E3.get())
# try work with returned value and display as in a console
print(portlist)
print('testprint')
scrolledtext.insert(tkinter.INSERT, 'Following Ports are open\n' )
scrolledtext.insert(tkinter.INSERT, str(portlist))
You can do scrolledtext.update_idletasks() after a scrolledtext.insert(), it will refresh the widget and your text will pop.
see that comment for more.
Hope it help!

Getting return value from tkinter button when clicked

I need a tkinter Button to assign a value to a variable, but I can't figure out how. I can't just put the assignment in the button callback function, because that would be local within the callback function and would be lost. How can I get a value back from the button in my main function?
Here is the code:
def newfile():
def create_file(entry):
file=open(entry.get(0),'w')
return file
chdir(askdirectory())
name=Tk()
name.title("Name the File?")
prompt=Label(name, text="Enter name for new file:")
prompt.grid(row=0)
e=Entry(name)
e.grid(row=1)
e.insert(0, "Untitled")
create=Button(name, text="Create")
#Code I want the button to execute: current=create_file(e), name.destroy()
create.grid(row=2, column=3)
name.mainloop()
return current
Does anyone know?
Also, I need to be able to retrieve current from the return of newfile().
If you use nonlocal current, you should be able to directly set the current variable within the create_file function, as long as current has already been defined, it should work. Remember to put the function call connected to the buttons command argument, in a lambda function, so you can give it the argument. In the future, though, really do follow the comments, the whole code could be reorganised to make it seem more sensible...
def newfile():
current = None
def create_file(entry):
nonlocal current
current = open(entry.get(),'w')
e.master.destroy()
chdir(askdirectory())
name=Tk()
name.title("Name the File?")
prompt=Label(name, text="Enter name for new file:")
prompt.grid(row=0)
e=Entry(name)
e.grid(row=1)
e.insert(0, "Untitled")
create=Button(name, text="Create", command = lambda: create_file(e))
create.grid(row=2, column=3)
name.mainloop()
return current
What I would do is create a class, in this class define name and current as class variables (self.name and self.current) so I could modify them in a class function without problem.

Passing StringVar object from Entry to Label within functions in tkinter

Hi I've been struggling to get this to work, each time i change something I receive another error. I've been trying to create an entry box with a function and then get the variable from the entry box into a label, created by a button press. When I tried to do this often this error came up.
TypeError: get() missing 1 required positional argument: 'self'
I then put self in in the method brackets.
command = lambda: x.myFunc(self.my_variable.get(self))
Then another error, which I'm not sure how to sort out.
AttributeError: 'My_Class' object has no attribute '_tk'
Here's the full code, I'm new to classes and self, so any corrections are welcome.
from tkinter import *
import time
class My_Class:
def start(self):
self.root=Tk()
self.my_variable=StringVar
self.entry_box=Entry(self.root, textvariable=self.my_variable)
self.entry_box.pack()
self.button=Button(self.root,text="Pass variable now",
command=lambda:x.myFunc(self.my_variable.get(self)))
self.button.pack()
def myFunc(self,my_variable):
self.lab=Label(self.root,text=self.my_variable)
self.lab.pack()
x=My_Class()
x.start()
This is the correct way to create a StringVar object:
text = StringVar() # note additional ()
Can you explain me what x is in the following statement:
lambda: x.myFunc(self.my_variable.get(self))
x is not visible inside the class, because it's declared outside the class.
myFunc is not indented correctly: you should indent it like the __init__ method.
I really recommend you to watch some tutorials on OOP before proceeding. You are basically trying to guess how OOP works.
If you make myFunc A method if the class (which you might be trying to do; it's hard to know because your indentation is wrong), you don't have to pass anything to myFunc. That function has access to everything in the class, so it can get what it needs, when it needs it. That lets you eliminate the use of lambda, which helps reduce complexity.
Also, you normally don't need a StringVar at all, it's just one more thing to keep track of. However, if you really need the label and entry to show exactly the same data, have them share the same textvariable and the text is updated automatically without you having to call a function, or get the value from the widget, or set the value n the label.
Here's an example without using StringVar:
class My_Class:
def start(self):
...
self.entry_box = Entry(self.root)
self.button = Button(..., command = self.myFunc)
...
def myFunc(self):
s = self.entry_box.get()
self.lab = Label(..., text = s)
...

Resources