Not long ago I asked an question on how to import from an input statement. Nailed it. Now I'm upgrading my lengthy code to a GUI for the user. Same problem. How do I import a module based on user input from the tkinter widget Entry.
I originally had:
var1=__import__(input("Enter a module: "))
And attempted something like this:
import tkinter
var1=__import__(tkinter.Entry(top, bd=5)).pack()
A few different phrasings all resulted in the basic error:
TypeError: __import__() argument 1 must be str, not Entry
I have a few different methods still on my list to try. For example:
var1=Entry(top, bd=5).grid(row=7)
var2=Entry.get(var1)
var=__import__(var2)
This gives me the rather awful error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Python33\Doc\Project\testing.py", line 21, in finish
var2=Entry.get(var1)
File "C:\Python33\lib\tkinter\__init__.py", line 2512, in get
return self.tk.call(self._w, 'get')
AttributeError: 'NoneType' object has no attribute 'tk'
You need Entry instance to work with it.
This way:
my_entry = Entry(top, bd=5) # you get object (Entry instance)
my_entry.grid(row=7) # you call object method grid()
entry_text = my_entry.get() # you call object method get()
var = __import__(entry_text)
BTW:
This way you get result of grid() function, not Entry instance.
var1 = Entry(top, bd=5).grid(row=7) # grid() returns always None
see
my_entry = Entry(top, bd=5)
grid_result = my_entry.grid(row=7) # grid() returns always None
var1 = grid_result
In this code you try to pack() imported library :)
var1 = __import__(tkinter.Entry(top, bd=5)).pack()
see
my_entry = Entry(top, bd=5) # you get object
imported_library = __import__(my_entry) # object can't be argument for __import__
var1 = imported_library.pack() # you can't pack library
Related
While trying to create a minimal, reproducible example for another problem in Python 3.7.3, I ran into a NoneType Error that I wasn't expecting.
Main program:
import worker
def multiply_worker_value(arguments):
current_Worker = arguments[0]
multiplier = arguments[1]
new_worker = current_Worker.change_value(multiplier)
return new_worker
current_worker = worker.Worker()
print("Printing value:")
print(current_worker.get_value()[0])
while(current_worker.get_value()[0] < 10):
paramList = [current_worker,2]
current_worker = multiply_worker_value(paramList)
print(current_worker.get_value()[0])
Worker class:
import numpy
class Worker():
def __init__(self):
self.values = numpy.random.rand(10)
def change_value(self,multiplier):
self.values = numpy.sum(self.values*multiplier)
def get_value(self):
return self.values
When this is run, I get:
Printing value:
0.10619190084595542
Traceback (most recent call last):
File "F:\Visual Studio\repos\Projects2020\tests\concurrent_test\concurrent_test\main.py", line 14, in <module>
while(current_worker.get_value()[0] < 10):
AttributeError: 'NoneType' object has no attribute 'get_value'
Press any key to continue . . .
and I am not sure why this is happening.
Inside the while loop, your current_worker gets overwritten with None:
current_worker = multiply_worker_value(paramList)
this calls:
new_worker = current_Worker.change_value(multiplier)
Your Worker.change_value method does not have a return statement, so it implicitly returns None.
Then, in the second iteration of your loop, your code tries to call get_value on None, which fails.
from tkinter import*
def final_calculation (event):
steal = float(amount_steal.get())
output_steal = (amount_steal * steal_c02 *c02_coal)
sumEntry.insert(0, sum)
root = Tk()
steal_c02 = float (5.5)
c02_coal = float (0.94)
amount_steal = Entry(root)
amount_steal.pack(side=LEFT)
equalButton = Button(root, text= "=")
equalButton.bind('<Button-1>', final_calculation)
equalButton.pack(side=LEFT)
sumEntry = Entry(root)
sumEntry.pack(side=LEFT)
root.mainloop()
and the error i get is
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\Anaconda3\lib\tkinter\__init__.py", line 1699, in
__call__
return self.func(*args)
File "<ipython-input-32-5bd239601a92>", line 4, in final_calculation
output_steal = float(amount_steal * steal_c02 *c02_coal)
*TypeError: unsupported operand type(s) for *: 'Entry' and 'float'
It all works fine until i try to calculate the sum please note im a complete noob when it comes to tkinter any help would be very useful
kind regards
49.95
The problem here is that in line 4, instead of using the variable steal (which you have assigned the value in amount_steel), you have used the amount_steel variable, which does not store the value in the textbox, but rather the object representing the textbox.
To fix this, simply change line 4 to:
output_steal = (steal * steal_c02 * c02_coal
However, there is another issue here, which could potentially occur if the user enters a value which isn't convertible to a float: if the user enters a value like "twenty" or "1.1.", then your program will stop. This is fixable by testing to ensure that the entered value is indeed convertible to a float, like so:
def final_calculation(event):
steal = amount_steal.get()
try:
float(steal)
except ValueError:
#code to notify user of invalid value
return #don't return anything to stop the calculation
#rest of code here
I am making a program that draws a line(you decide where is the beggining and end of it with the sliders/scales), problem is im getting these errors(That i wish i understood) when i press the psy Button(code below the errors) :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\python351\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/Koteu/PycharmProjects/guji/fsd.py", line 23, in creat
cans.create_line(ar1,ar2,br1,br2)
File "C:\python351\lib\tkinter\__init__.py", line 2331, in create_line
return self._create('line', args, kw)
File "C:\python351\lib\tkinter\__init__.py", line 2319, in _create
*(args + self._options(cnf, kw))))
_tkinter.TclError: bad screen distance ".14855536.14855504"
Process finished with exit code 0
anyways, the code :
import os
import sys
from tkinter import *
root = Tk()
app=Frame(root)
root.geometry("1200x1200")
ar1 = Scale(root,from_=0,to=600)
ar2= Scale(app,from_=0,to=600,deafultvar=0)#app instead of root because the button for unknown to me reason
#wouldn't appear in GUI otherwise
br1= Scale(root,from_=0,to=600)
br2= Scale(root,from_=0,to=600)
cans = Canvas(root,width = 500,height = 500)
cans.create_line(600,50,0,50) #This has nothing to do with the actual program by my understanding
def creat():
cans.create_line(ar1,ar2,br1,br2)#< this is what causes the problem i don't understand
psy=Button(root,command=creat,text="karole")
psy.pack()
cans.pack()
ar1.pack()
ar2.pack()
br1.pack()
br2.pack()
mainloop()
also, if that helps, im using py345
cans.create_line(x0, y0, ...) takes an even number of integer coordinates as positional args. You passed widgets, which were turned into their string identifiers. In ".14855536.14855504", '.' represents root, '14855536' is the canvas, and '14855504' is the scale ar1. Instead you need to use the .get() method on the scales to get their integer values. The following works.
from tkinter import *
root = Tk()
root.geometry("1200x1200")
ar1 = Scale(root,from_=0,to=600)
ar2= Scale(root,from_=0, to=600)
br1= Scale(root,from_=0, to=600)
br2= Scale(root,from_=0, to=600)
cans = Canvas(root, width=500, height=500)
def creat():
cans.create_line(ar1.get(), ar2.get(), br1.get(), br2.get())
psy=Button(root, command=creat, text="karole")
ar1.pack()
ar2.pack()
br1.pack()
br2.pack()
psy.pack()
cans.pack()
root.mainloop()
A couple of other fixes: the defaultvar option is not valid and caused an error; mainloop() instead of root.mainloop() caused tk to create a second Tk object, which is a bad idea.
EDIT: added the code that works.
I tried to monkey patch an object in Python.
class C:
def __init__(self):
self.__n = 0
def f(self):
self.__n += 1
def __str__(self):
return str(self.__n)
c = C()
def up(self):
self.__n += 2
import types
c.up = types.MethodType(up, c)
c.up()
But I got an AttributeError
Traceback (most recent call last):
File "untitled4.py", line 19, in <module>
c.up()
File "untitled4.py", line 15, in up
self.__n += 2
AttributeError: 'C' object has no attribute '__n'
How can I fix the error?
As your up function isn't declared inside a class, it is not possible to apply name mangling rules to its locals, while it is applied for the attribute name. Therefore you'd need to apply the name mangling manually in your function:
def up(self):
self._C__n += 2
I am attempting to run the following code for a text editor.
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
But I get this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
return self.func(*args)
File "<pyshell#1>", line 15, in <lambda>
create=Button(name, text="Create", command = lambda: create_file(e))
File "<pyshell#1>", line 5, in create_file
current = open(entry.get(),'w')
TypeError: an integer is required
It wants an integer argument.
Does anyone know what that is?
An instance of the Entry widget does not require any arguments for the get method. You are calling it correctly. Neither does the standard open command require an integer. My guess is, one of entry or open is not what you think it is. Maybe you have a method or another object with one of those names?
I suggest putting the call to get and the open on separate lines, to make sure you know which part of that statement is throwing the error:
text = entry.get()
current = open(text, 'w')