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

This question already has an answer here:
How i can print(b) from a func which is define in frontend.py to backend.py
(1 answer)
Closed 3 years ago.
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

Python Tkinter entry not loading content correct

i am facing a problem. I'm runnig this code.
import tkinter as tk
root = tk.Tk()
def check():
if len(e.get().split("a")) > 1:
print("contains a")
e = tk.Entry(frame1)
e.grid(row=4,column=1,columnspan=2,padx = (10,10), pady=(5,10), sticky="w e")
e.bind("<Key>",check)
when i type "a" to the entry I wont get nothing printed. I'll get the result by tiping a second character. I think that it happens because the function gets executed before the content has actualy changed. I tried to add a timer on the beginning of the function but it does nothing.
I want get the result by entering the first "a". What should I do?
I think that it happens because the function gets executed before the content has actualy changed.
You're right. If you want the callback to be able to see the character you just typed, you should create a StringVar and bind to that instead of binding to a "<Key>" event on the widget.
import tkinter as tk
frame1 = tk.Tk()
def check(*args):
if "a" in s.get():
print("contains a")
s = tk.StringVar()
e = tk.Entry(frame1, textvariable=s)
s.trace("w", check)
e.grid(row=4,column=1,columnspan=2,padx = (10,10), pady=(5,10), sticky="w e")
frame1.mainloop()

Pausing from within a tkinter function

I'm trying to create a couple of functions which do things in a sequential order. First they need to open a new window and display a label, then they need to wait for some seconds, then they need to call another function. However, I'm struggling to get the functions to wait, all the methods I've tried (.after, .sleep, .wait_visibility) seem to be ignored and it just skips to the next function call without pausing.
Here's what I have (sorry if it's messy, I'm new to python):
from tkinter import *
import time
root =Tk()
root.geometry('600x600')
def scale_screen(event = None):
global s_screen
s_screen = Toplevel(root)
s_screen.title('Residual Inhibition Tester')
s_screen.geometry('600x600')
s_screen.transient(root)
s_screen.bind('<Return>', sel)
global var
var = IntVar()
scale = Scale(s_screen, variable = var, orient = HORIZONTAL, length = 1000)
scale.focus_set()
scale.pack(anchor=CENTER)
button = Button(s_screen, text="Select", command=sel)
button.pack(anchor=CENTER)
def sel(event = None):
label = Label(s_screen)
selection = "Value = " + str(var.get())
label.config(text = selection)
interval_screen()
def interval_screen():
global i_screen
i_screen = Toplevel(root)
i_screen.geometry('600x600')
i_screen.transient(root)
i_label = Label(i_screen, text = "Please Wait")
i_label.pack(anchor = CENTER)
s_screen.destroy()
i_screen.after(3000, masker_screen)
#time.sleep(3)
#i_screen.after(300,i_label.configure(text="Playing New Masker Noise"))
#root.wait_visibility(window = i_screen)
def masker_screen():
global m_screen
m_screen = Toplevel(root)
m_screen.geometry('600x600')
m_screen.transient(root)
m_label = Label(m_screen, text = "Playing New Masker Noise").pack(anchor = CENTER)
m_screen.after(3000, lambda: scale_screen(event = None))
i_screen.destroy()
b1 = Button(root, command = scale_screen).pack(anchor=CENTER)
root.bind('<Return>', scale_screen)
root.mainloop()
In this example, the program will run but just skip the interval_screen entirely and just do the masker_screen. I'm also not averse to just using one screen and using the .configure methods to change the label text if that's easier.
Thanks!
Without seeing all the ways you tried it, it's impossible to know what you did wrong. In general you should never call time.sleep and you should never call after with just a single argument. Also, when you use after with two arguments, the second argument must be a reference to a function.
The proper way to do this is to have your first function call your second function via after:
def interval_screen():
...
i_screen.after(3000, maker_screen)
def masker_screen():
...
m_screen.after(3000, lambda: scale_screen(event = None))
Note that in your updated question you're using after incorrectly:
m_screen.after(3000, scale_screen(event = None))
You're calling the function scale_screen(...) immediately, and giving the result of that to the after function. If you need to pass arguments to your function you must create another function that does not require arguments. The simplest way to do this is with lambda, though you can also use functools.partial or you can create your own function.

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.

Tkinter "entry" object not updating textvariable variable (Python 3.4)

I am trying to write a simple Python program that will allow a user to input an IP address in decimal, or dotted-decimal format, then convert it to the opposite format and display it in the same entry box (ie, if they enter a decimal IP address, they can click a button and their input will be replaced with the dotted-decimal equivalent).
The problem I'm having is with pulling the data out of the entry box, then putting the new data back into the entry box. I've written an example with just the GUI code, and none of my other conversion logic, to simplify the problem:
import tkinter as tk
root = tk.Tk()
root.title("Test")
win1 = tk.Frame(root)
win1.grid()
x = tk.StringVar()
y = tk.StringVar()
xBox = tk.Entry(win1)
xBox.grid(row = 0, column = 0)
xBox.textvariable = x
yBox = tk.Entry(win1)
yBox.grid(row = 1, column = 0)
yBox.textvariable = y
button = tk.Button(win1,text = "Calculate", command = lambda: copyVal())
button.grid(row = 2, column = 0)
def copyVal():
print("x: " + x.get())
print("y: " + y.get())
xVal = x.get()
print("xval: " + xVal)
y.set(xVal)
root.update_idletasks()
root.mainloop()
Here's what I expect to happen with this code:
The value entered in the top box should be stored in StringVar x.
Clicking the "Calculate" button should run the copyVal() function:
copyVal() gets the value of StringVar x and stores it as xVal.
copyVal() sets the value of StringVar y to match xVal.
The text in the bottom box should now match the text in the top box.
Instead, it does not retrieve the value of StringVar x, so there's nothing to set StringVar y to.
I've tried the following variations:
Using xVal = xBox.get() instead of xVal = x.get(): this retrieves the contents of the top entry box, and sets the value of StringVar y to match it, but the bottom entry box does not change.
Using command = copyVal() instead of command = lambda: copyVal(): the copyVal function executes immediately upon program execution, rather than when the button is pressed.
Moving the copyVal function outside the root mainloop: raises a NameError exception when the button is pressed (copyVal is seen as not defined).
Moving root.update_idletasks() outside the copyVal function has no effect.
I've looked around for solutions to this issue, but no matter how many people I find who are experiencing similar problems, none of their fixes seem to resolve the issue for me (I usually see them told to use StringVar() to get/set values). I am completely new to working with Tkinter, so I'm sure this is something really basic that I'm overlooking, and I appreciate any advice anyone can offer.
Python objects often allow you to add attributes to them arbitrarily:
>>> class Foo:
... pass
...
>>> foo = Foo()
>>> foo.a = 1 # No error. It makes a new attribute.
>>> foo.a
1
>>>
>>> def foo():
... pass
...
>>> foo.a = 1 # Works with function objects too.
>>> foo.a
1
>>>
So, when you do:
xBox.textvariable = x
...
yBox.textvariable = y
you are not actually setting the Entrys' textvariable options to x and y. Instead, you are creating new attributes named textvariable on each of those objects.
To fix the problem, either set each Entry's textvariable option when you create the widgets:
xBox = tk.Entry(win1, textvariable=x)
...
yBox = tk.Entry(win1, textvariable=y)
or use the .config method to change them later:
xBox.config(textvariable=x)
...
yBox.config(textvariable=y)

Tkinter app behaves differently when imported than when directly executed [duplicate]

This question already has answers here:
Why is Python running my module when I import it, and how do I stop it?
(12 answers)
Closed 4 years ago.
I am trying to build a GUI.
When I execute the application directly (i.e. double click the python file), I get a different result (console output) to importing it (mainloop).
I would like it to give the following console output:
c
d
e
f
g - from app
as I would like the main loop to be accessible after it has been imported as a module.
I am attempting to make the input and output controllable from an external file importing it as a module.
I get the expected output when I run the file, but when I import it as a module, it appears to run the main loop, as I get a Tkinter mainloop window output.
Here is the code:
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.text = Lines()
self.text.insert("\n\n\n\n\n")
self.waitingForInput = False
self.inText = ""
self.pack()
self.widgets()
def widgets(self):
self.L1 = Label(self)
self.L1["text"] = self.text.bottomLines
self.L1.pack(side = "top")
self.E1 = Entry(self)
self.E1["width"] = 40
self.E1.pack(side = "top")
self.B1 = Button(self)
self.B1["text"] = "Enter",
self.B1["command"] = self.giveInput
self.B1.pack(side = "top")
def giveInput(self):
if self.waitingForInput:
self.inText = self.B1.get()
self.waitingForInput = False
def getInput(self, output):
giveOutput(output)
self.waitingForInput = True
while True:
time.sleep(0.1)
if not self.waitingForInput:
break
return self.inText
def giveOutput(self, output):
self.text.insert(output)
self.L1["text"] = self.text.bottomLines
print self.text.bottomLines + " - from app"
root = Tk()
app = Application(master = root)
app.giveOutput("a \n b \n c \n d \n e \n f \n g")
The Lines class is essentially a stack of lines of text in a string, stacking more with insert(x) and accessing the final five lines of the stack with bottomLines.
Back on topic, when imported as a module, it runs the main loop, with a label containing what I assume to be 5 empty lines, an entry box and the "Enter" button. I do not want this. I want the same result as when I run the file directly, as I showed before.
I only want the box to appear when the app.mainloop method is called.
What have I done wrong, how is it wrong, and how can I correct it?
This will only run when the module is run directly, not when imported:
if __name__ == "__main__":
root = Tk()
app = Application(master = root)
app.giveOutput("a \n b \n c \n d \n e \n f \n g")

Categories

Resources