Hi I am having trouble calling functions in tkinter
Here is the code
class Demo(tk.Frame):
def ShowOption(self):
print(self.v1.get())
def __init__(self,controller):
tk.Frame.__init__(self,width=800, height=600)
f = Frame(self)
optionList = ('A', 'B','C')
self.v1 = tk.StringVar()
self.v1.set(optionList[0])
Opt1 = tk.OptionMenu(f, self.v1, *optionList,command = self.ShowOption)
Opt1.grid(row=2,column=2,sticky='w')
f.place(relx = 0.5,rely=0.5,anchor='c')
The problem I have is if I use this method it states the function takes 1 postional argument and none were given but if I use
Opt1 = tk.OptionMenu(f, self.v1, *optionList,command = self.ShowOption() )
The function runs straight away when the class is created.
Any help greatly appreciated.
Callback for the command option of OptionMenu expects an argument which is the selected item.
So either you use lambda to skip the argument:
command=lambda v: self.ShowOption()
Or redefine ShowOption() to accept an argument:
def ShowOption(self, value):
...
do this
command = lambda : self.ShowOption()
Related
I have written the two functions below in the same python file. If I print the answer function it returns the answer of 7 which is expected.
The second function is calling the first function to get the answer.
If I create two python files as below and run it there is an error NameError: name 'math' is not defined.
Why am I not able to create the function that is required to run answer() in the second python file?
I have tried referencing math = 0 to give it a starting variable. My goal is to be able to build functions that I can import into the main python file where that function uses functions created in the main file. The two files are p1.py and p2.py
def math(x,y):
answer = x + y
return answer
def answer():
answer = math(5,2)
return answer
print(answer())
# Returns the answer of 7
def answer():
answer = math(5,2)
return answer
import p1
def math(x,y):
answer = x + y
return answer
print(answer())
# Returns NameError: name 'math' is not defined.
There are a few ways to make it work, you can make answer take a function as an argument:
def answer(math):
answer = math(5,2)
return answer
and call it with answer(math), or you could import it in p1.py by adding from p2 import math.
I have 2 Modules, the first module has class One with a function which returns a value. The second has 2 classes Two and Three with functions. I've imported the class from the first module into the second.
In function i of Class Two I've assigned the function x from class One to y. from there I can access returned value by printing y, the function also returns a variabletype needed else where in the program.
but also need to access this same variable y from within function z in class Three.
The method I've used in class Three returns an error. I've tried using getattr but found no joy. But I believe I may have been using it wrong.
The only other solution I've had is to return y along with type. Then assign the function i in class Two to pop in function z of class Three. But this calls the function from x in class One which means I have to enter another value then it prints multiple unneeded lines.
I've created a mock of this problem to try and find a solution but I'm a little stuck. I need to access the value from y in function i of class Two multiples times in a number of other classes.
Method one:
Module 1: TestOne.py
class One():
def x(self):
Go = input("Please enter value\n")
return Go
Module 2: Test.py
from TestOne import*
class Two():
def i(self):
type = "Move"
y = One.x(self)
print("Test 1: ",y)
return type
class Three():
def z(self):
print("Test 2: ", Two.i.y)
Module 3: TestMain.py
from Test import*
p = Two()
t =Three()
p.i()
t.z()
Error:
PS C:\Users\3com\Python> python testmain.py
Please enter value
Test 1:
Traceback (most recent call last):
File "testmain.py", line 9, in <module>
t.z()
File "C:\Users\3com\Python\Test.py", line 16, in z
print("Test 2: ", Two.i.y)
AttributeError: 'function' object has no attribute 'y'
Method 2:
Module 1: TestOne.py
class One():
def x(self):
Go = input("Please enter value\n")
return Go
Module 2: Test.py
from TestOne import*
class Two():
def i(self):
type = "Move"
y = One.x(self)
print("Test 1: ",y)
return type, y
class Three():
def z(self):
pop = Two.i(self)[1]
print("Test 2: ", pop)
Module 3: TestMain.py:
from Test import*
p = Two()
t =Three()
p.i()
t.z()
Output:
PS C:\Users\3com\Python> python testmain.py
Please enter value
1
Test 1: 1
Please enter value
1
Test 1: 1
Test 2: 1
Edit:
I've done a little digging and have a solution that solves the problem. using global. But have found a number of articles which say that the use of global can be somewhat dangerous if not used correctly,
Method 3: Working Solution. Meets desired output.
Module 1: TestOne.py
class One():
def x(self):
Go = input("Please enter value\n")
return Go
Module 2: Test.py
from TestOne import*
class Two():
def i(self):
type = "Move"
global y
y = One.x(self)
print("Test 1: ",y)
return type
class Three():
def z(self):
print("Test 2: ", y)
Module 3: TestMain.py:
from Test import*
p = Two()
t =Three()
p.i()
t.z()
Output:(Desired Output)
PS C:\Users\3com\Python> python testmain.py
Please enter value
1
Test 1: 1
Test 2: 1
Having done research and looking for similar problems I found that using a dictionary is one of the easier and safer ways to be able to access the needed information.
whilst trying to use global I found that I had encountered a number of problems also the program was not running as expected. With the current method I can access the values stored in the dictionary by importing them to needed module and can also easily make changes
This is the modified solution:
Module 1: TestOne.py
my_dict ={'Go':None}
class One():
def x(self):
my_dict['Go'] = input("Please enter value\n")
my_dict is defined as a dictionary with a key:Go and the value set to None.
In function x of class One, my_dict['Go'] is given the value derived from input.
Module 2: Test.py
from TestOne import*
class Two():
def i(self):
type = "Move"
One.x(self)
print("Test 1: ", my_dict["Go"])
return type
class Three():
def z(self):
print("Test 2: ", my_dict["Go"])
In class Two I no longer need to assign One.x(self) to y.
The value of 'my_dict['Go']` in now accessible as it has been imported from the module 'TestOne.py'
Module: TestMain.py
from Test import*
p = Two()
t =Three()
p.i()
t.z()
Output:
Please enter value
1
Test 1: 1
Test 2: 1
Accessing "Module Scope" Var
I need some help, I trying to update the etcprice label value after I push the button and after every 5 seconds, in terminal works, but in tk window not. I stucked here :( please, help me.
I tried to setup the "price" to "StringVar()" but in that case I got a lot of errors.
Many thanks
import urllib.request
from urllib.request import *
import json
import six
from tkinter import *
import tkinter as tk
import threading
price = '0'
def timer():
threading.Timer(5.0, timer).start()
currentPrice()
def currentPrice():
url = 'https://api.cryptowat.ch/markets/bitfinex/ethusd/price'
json_obj = urllib.request.urlopen(url)
data = json.load(json_obj)
for item, v in six.iteritems(data['result']):
# print("ETC: $", v)
price = str(v)
# print(type(etcar))
print(price)
return price
def windows():
root = Tk()
root.geometry("500x200")
kryptoname = Label(root, text="ETC price: ")
kryptoname.grid(column=0, row=0)
etcprice = Label(root, textvariable=price)
etcprice.grid(column=1, row=0)
updatebtn = Button(root, text="update", command=timer)
updatebtn.grid(column=0, row=1)
root.mainloop()
windows()
The solution was: I created a new String variable called “b” and I changed the etcprice Label variable to this.
After I added this b.set(price) in currentPrice() def: and is working.
The price variable is a global - if you're trying to change it, you need to do so explicitly:
def currentPrice():
global price
url = 'https://api.cryptowat.ch/markets/bitfinex/ethusd/price'
json_obj = urllib.request.urlopen(url)
data = json.load(json_obj)
for item, v in six.iteritems(data['result']):
# print("ETC: $", v)
price = str(v)
# print(type(etcar))
print(price)
return price
otherwise, Python will 'mirror' it as a local variable inside the function, and not modify the global.
It's not a good idea to keep on launching more and more threads each time you click the button - so:
updatebtn = Button(root, text="update", command=currentPrice)
probably makes more sense.
You don't need to use threads here, just to call functions 'in the background'. You can use tkinter's own .after function instead to delay caling functions. (it uses milliseconds, not float second values, btw)
def timer(delay_ms, root, func):
func()
root.after(delay_ms, timer, root, func)
might be a helpful kind of function.
Then before you launch your mainloop, or whenever you want the getting to start, call it once:
timer(5000, root, currentPrice)
If you want the currentPrice function to run in a separate thread, and so not block your main GUI thread if there is network lag, for instance, then you can use threads more like this:
Thread(target=currentPrice, daemon=True).start()
which will run it in a daemon-thread - which will automatically get killed if you close the program, or ctrl-c it, or whatever. So you could put that line in a getCurrentPriceBG or similar function.
I need to get the variable a function's return value is assigned to.
function example()
end
variable = 3 --just for example
variable = example() --I need the value of variable(in this case 3) passed as an argument to example()
Please read the Lua reference on how to call and define functions.
https://www.lua.org/manual/5.3/manual.html#3.4.10
https://www.lua.org/manual/5.3/manual.html#3.4.11
You can simply do this:
function fancyFunction(val)
return val
end
local val = 3
val = fancyFunction(val)
of course this minimum example does not make much sense. You should of course have another return value than your argument. Otherwise you don't have to call the function in the first place.
(Quite hard to understand what you're trying to do.) Could you possibly be referring to object oriented programming? If so, then you need something like this:
--setup
t = {}
function t:set(v) self.value = v end --assign value to 'variable'
function t:get() return self.value end
--use
t:set(3)
print(t:get())
I'm implementing an actor-based app in scala and I'm trying to be able to pass functions between the actors for them to be processed only when some message is received by the actor.
import actors.Actor
import java.util.Random
import scala.Numeric._
import Implicits._
class Constant(val n:Number) extends Actor{
def act(){
loop{
receive{
case "value" => reply( {n} )
}
}
}
}
class Arithmetic[T: Numeric](A: ()=>T, B: ()=>T) extends Actor{
def act(){
receive{
case "sum" => reply ( A() + B() )
/* case "mul" => reply ( A * B )
*/
}
}
}
object Main extends App{
val c5 = new Constant(5)
c5.start
val a = new Arithmetic({c5 !! "value"}, {c5!!"value"} )
a.start
println(a!?"sum")
println(a!?"mul")
}
In the example code above I would expect the output to be both 5+5 and 5*5. The issue is that reply is not a typed function and as such I'm unable to have the operator (+,*) to operate over the result from A and B.
Can you provide any help on how to better design/implement such system?
Edit: Code updated to better reflect the problem. Error in:
error: could not find implicit value for evidence parameter of type Numeric[Any]
val a = new Arithmetic({c5 !! "value"}, {c5!!"value"} )
I need to be able to pass the function to be evaluated in the actor whenever I call it. This example uses static values but I'll bu using dynamic values in the future, so, passing the value won't solve the problem. Also, I would like to receive different var types (Int/Long/Double) and still be able to use the same code.
The error: Error in: error: could not find implicit value for evidence parameter of type Numeric[Any]. The definition of !!:
def !! (msg: Any): Future[Any]
So the T that Arithmetic is getting is Any. There truly isn't a Numeric[Any].
I'm pretty sure that is not your problem. First, A and B are functions, and functions don't have + or *. If you called A() and B(), then you might stand a chance... except for the fact that they are java.lang.Number, which also does not have + or * (or any other method you'd expect it to have).
Basically, there's no "Number" type that is a superclass or interface of all numbers for the simple reason that Java doesn't have it. There's a lot of questions touching this subject on Stack Overflow, including some of my own very first questions about Scala -- investigate scala.math.Numeric, which is the best approximation for the moment.
Method vs Function and lack of parenthesis
Methods and functions are different things -- see tons of related questions here, and the rule regarding dropping parenthesis is different as well. I'll let REPL speak for me:
scala> def f: () => Int = () => 5
f: () => Int
scala> def g(): Int = 5
g: ()Int
scala> f
res2: () => Int = <function0>
scala> f()
res3: Int = 5
scala> g
res4: Int = 5
scala> g()
res5: Int = 5