How to call function properties from other file [duplicate] - python

This question is an exact duplicate of:
How i can print(b) from a func which is define in frontend.py to backend.py
There are 2 Files 1.Frontend 2.Backend
In Frontend There is one function pop(), which basically is b = a.get()
and what i want is whenever user type something in entry box it should be printed via backend...
FRONTEND
from tkinter import *
import backend
win = Tk()
win.geometry("500x500")
def pop():
b = a.get()
But = Button(text = "CLICK",command = pop)
But.pack()
a = StringVar()
e_1 = Entry(textvariable = a)
e_1.pack()
BACKEND
from frontend import pop
print(b)
I was expected that whenever use type something in entry box it should be print via backend but i got an error that is "b" is not define..

You could do something like this:
Change pop to:
def pop():
b = a.get()
return b
Backend:
from frontend import pop
print(pop())
This prints b.
Variables are defined in a function are only part of that function's "scope" as JacobIRR said, but you can still return the variable.

Related

Attempting to return a variable from a class returns a function object instead

I'm looking to pass a variable out of a class and into another. To do so, I am returning the variable in a method and calling that method in another class. Unfortunately when I do so, all I get is:
<function body.returntheline at 0x7f9444673bf8>
My code is as follows:
from tkinter import *
class body:
def __init__(self):
root = Tk()
self.input_file = Entry(root)
self.input_file.pack(side = LEFT)
self.launch = Button(root, text = "Go External", command = operator)
self.launch.pack()
self.launchx= Button(root, text = "GO", command = self.testingvalue)
self.launchx.pack()
root.mainloop()
def testingvalue(self):
thesillyvalue = self.input_file.get()
print(thesillyvalue)
def returntheline(self):
test = str(self.input_file.get())
return test
class operator:
def __init__(self):
self.textvar = body.returntheline()
print(self.textvar)
if __name__ == "__main__":
body()
What is it that I have to do to get the specific value from this class instead of the function object? To test that the value does work, I have set up an internal method which does the same thing, only within the class. It does print out a string object to the console, so I am at a loss as to why the returned one does not.
You will need to pass the instance itself over to the external class via lambda or similar:
# under class body, change self.launch to this:
self.launch = Button(root, text = "Go External", command = lambda x=self: operator(x))
# Then under class operator:
class operator:
def __init__(self, body_instance): # pass in the instance of body as argument
self.textvar = body_instance.returntheline() # directly call the instance method over the instance.
print(self.textvar)
The lambda basically ensures you will always pass self (the instance) over to the external class.
But in this case the instance of the external class operator is just wasted after calling the __init__, but perhaps your real life example have a better use...

How to access class member functions from within different instances of that same class? Python

My issue is that with my tkinter application. I have a button used to collapse part of the application, however if I click on each of the buttons on the left I have to press the collapse button 7 times to get rid of all instances of the right side of the application which is first created in the createArea member function.
I have stored each instance of the class in a dictionary called dictionary and I need for the destroyRight function to destroy all of the right side of the application in every instance.
I am unsure how to access the functions of each class instance when it is stored in a dictionary and I am also unsure as to how I am able to get one instance of a class to communicate with all the others.
Help would be very much appreciated.
Image of my application
from tkinter import*
root = Tk()
class Buttons:
def __init__(self,master,imperialText,metricText,metricVal):
self.imperialText,self.metricText,self.metricVal,self.master = imperialText,metricText,metricVal,master
self.displayedText = (self.imperialText +'-'+ self.metricText)
self.button = Button(self.master,text= self.displayedText,command = self.createArea)
self.button.config(height= 3,width=30)
self.button.grid(column = 0)
self.rightCreated = False
self.rightButtons = []
def createArea(self):
self.rightCreated = True
self.entryBox = Entry(self.master)
self.entryBox.bind('<Return>',self.calc)
self.entryBox.grid(column = 1,row = 1)
self.label = Label(self.master,text = 'Enter '+self.imperialText)
self.label.grid(column = 1,row = 0)
self.backButton = Button(self.master,text = '<<Collapse', command = self.destroyRight)
self.backButton.grid(column = 1, row = 6)
print('happen')
self.rightButtons.extend([self.entryBox,self.label,self.backButton])
def destroyRight(self):
collapseAll()
print(self.rightButtons)
for i in self.rightButtons:
i.destroy()
def calc(self):
print('hi')
def collapseAll():
for i in dictionary:
dictionary[i].destroyRight()
dictionary = {'B1':None,'B2':None,'B3':None,'B4':None,'B5':None,'B6':None,'B7':None}
ImperialText = ['inches','miles','foot','yards','gallons','pounds','ounces']
MetricText = ['centimetres','kilometres','metres','metres','litres','kilograms','grams']
metricVal = [2.54,1.6093,0.3048,0.9144,4.546,0.454,0.454]
num = 0
for i in dictionary:
dictionary[i] =
Buttons(root,ImperialText[num],MetricText[num],metricVal[num])
num += 1
if num == 6:
print(i)
root.mainloop()
All you have to do is something like dictionary['B1'].calc() which accesses the first button in the dictionary and calls the calc method.
There's nothing special about the fact that your instances are values in a dictionary. You can think of this just like having separate variables B1, B2,... for each instance (in fact the global namespace is just a dictionary). An advantage of having them in a dict is you can easily loop over the instances and call the same method on each instance like:
for b in dictionary.values():
b.collapse()
or whatever.

Return value using button [duplicate]

This question already has an answer here:
Python - returning from a Tkinter callback
3 answers
I'm trying to return a value using a button, but i just can't get it to work. What i want is the button to return a value which later on can be used to check is the function was used or not. The code that I'm using is the following:
from Tkinter import *
master = Tk()
master.geometry("200x100")
def bla():
return 1
Button(master, command = bla, text = 'OK').pack()
if bla == 1:
print('1')
mainloop()
I've also tried to do this using lambda but i could not figure that one out too.
Try taking a look at this link https://stackoverflow.com/a/11907627/3110529 as it addresses the issues you're having.
The main concern is that callbacks are designed to just be a behaviour that happens in response to an event and therefore it doesn't entirely make sense for them to return a value. In your program, when you say
if bla == 1:
print('1')
you're asking if the function pointer (or reference?) is equal to 1 which it obviously will never be.
You might be tempted to use global variables to cover this (i.e. store a 'blah' variable, then have the call back set its value) but this is generally considered bad practice. Instead, as in the link, try converting it to a class which will allow you to use member variables to store the results and responses of callbacks in a more organised manner.
Your problem is that you arn't saving the return value of bla().
You can do this using a global variable:
from Tkinter import *
master = Tk()
master.geometry("200x100")
gloBla = 0
def bla():
global gloBla
gloBla = 1
Button(master, command = bla, text = 'OK').pack()
mainloop()
if gloBla == 1:
print('1')
As per the Tknitter Documentation http://effbot.org/tkinterbook/variable.htm, you can use BooleanVar StringVar or IntVar. They Function as Global variables. In this vase Variable Changes with each click of the button.
from Tkinter import *
master = Tk()
Variable = BooleanVar()
Variable.set(False)
app = Frame(master, borderwidth=10).grid()
def bla():
print("1")
if Variable.get() == 0:Variable.set(True)
else:Variable.set(False)
print("current state of Variable: {0} ".format(Variable.get()))
button1= Button(app, text = "Click Me",command=lambda:bla()).grid()
mainloop()
The lambda: command ensure that the function is not called on startup.

class aggregation (classes within classes) with Python 3 and Tkinter

It says that base_obj is not defined. But I did define it already. So why am I getting this error?
here is the code:
from tkinter import *
root = Tk()
class BaseClass:
def __init__(self,an_int,a_string):
self.the_int = an_int
self.the_string = a_string
class BiggerClass:
def __init__(self,an_instance_of_BaseClass,big_class_string,big_class_int,new_name):
self.the_instance_of_BaseClass = an_instance_of_BaseClass #here we are aggregating the base class into the bigger class
self.the_big_class_string = big_class_string
self.the_big_class_int = big_class_int
self.the_big_class_new_name = new_name
base_int_var = IntVar()
base_string_var = StringVar()
bigger_name_var = StringVar()
entry_base_int = Entry(root,textvariable = base_int_var).pack()
entry_base_string = Entry(root,textvariable = base_string_var).pack()
big_new_name_var = StringVar()
entry_bigger_name = Entry(root, textvariable = bigger_name_var).pack()
entry_big_new_name = Entry(root,textvariable = big_new_name_var).pack()
def create_base_class_instance():
global base_obj
base_obj = BaseClass(base_int_var.get(),base_string_var.get()) # I define 'base_obj' here
list_of_bigs = []
def create_bigger_class_instance(big_handle):
bigger_name_var = big_handle
big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
list_of_bigs.append(big_handle)
#global big_obj
#big_obj = BiggerClass(base_obj,bigger_name_var.get(),45)
create_base_class_button = Button(root, text ="create base class", command = create_base_class_instance).pack()
create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()
match_name_var = StringVar()
entry_match_name = Entry(root,textvariable = match_name_var).pack()
def my_button_method():
for a_big in list_of_bigs:
if a_big.the_big_class_new_name == match_name_var:
print(a_big.the_instance_of_BaseClass.the_string)
#print(big_obj.the_instance_of_BaseClass.the_int)
#bigger_class_obj = BiggerClass(base_obj,"hello this is the big class",45)
button_print_out = Button(root,text = "press me", command = my_button_method).pack()
root.mainloop()
here is the error message:
Traceback (most recent call last):
File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 45, in <module>
create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()
File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 39, in create_bigger_class_instance
big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
NameError: name 'base_obj' is not defined
You have defined the object in create_base_class_instance function and you are calling it in my_button_method.
You should initialize it outside, and use global keyword in both functions.
However using global variables considered code smell. I would advise finding another solution, for example passing base_obj as an argument to both functions.
base_obj = None
def some_function():
global base_obj
# some code referencing base_obj
def other_function():
global base_obj
# some code referencing base_obj
Functions in Python are executed only when they are called. The keyword global is used to indicate that the variable used here is the same as in the global scope. Thus you will need to add a declaring statement in the main class and not in any of the sub function.
For e.g. You will have to write
base_obj = None
In the main class before either of the two functions is called. You do not need global base_obj in your second function as you are not assigning any value to it.
Look at this line of code:
create_big_class_button = Button(..., command = create_bigger_class_instance(big_new_name_var)).pack()
You are immediately calling create_bigger_class_instance(...), and the result of that is getting assigned to the command. Since create_bigger_class_instance relies on the existence of base_obj, and you haven't created base_obj yet since it's tied to a button click, you get the error.
(As a side note, doing something like create_big_class_button = Button(...).pack() will always result in create_big_class_button being set to None, because that is what pack() returns.)

How to call a parametized function with Tkinter in Python?

from tkinter import *
def my_function(parameter1, parameter2):
total = int(entrada1.get()) + int(entrada2.get())
Label(root,text=calculated_property).pack()
root = Tk()
frame = Frame(root)
frame.pack()
root.title("Testing 123")
numero1 = IntVar()
numero2 = IntVar()
entrada1 = Entry(root,textvariable=numero1)
entrada1.pack()
entrada2 = Entry(root,textvariable=numero2)
entrada2.pack()
aceptar = Button(root,text="Calcular",command=my_function)
aceptar.pack()
root.mainloop()
I'm working on simple graphic interfaces in Python. I`m using the tkinter library to practice with.
The form generated is quite simple, it just consist of two inputs and a button that calls the function: my_function.
I have troubles calling that function because the attribute "command" does not allows any parameter, but my_function requires two that are given by the inputs of the form.
Then, the idea is calling several functions inside my_function and return in a label a calculated_property.
Can you give me any solution?
Thank U so much!
You can simply use a lambda function to pass the arguments:
aceptar = Button(root,text="Calcular", command=lambda: my_function(arg1, arg2))
This code is equivalent to doing:
def func():
my_function(arg1, arg2)
aceptar = Button(root,text="Calcular", command=func)
except that the function is created inline.

Resources