Seems like python is partial - python

The following is a function I created, and put it in a file called last_function.py
from tkinter import*
def new_gui(app,sound_file,mixer):
track=mixer.Sound(sound_file)
def track_toggle():
if ballCheckbutton.get()==1:
track.play(loops=-1)
else:
track.stop()
ballCheckbutton=IntVar()
c1=Checkbutton(app,text="check me out",command=track_toggle,variable=ballCheckbutton)
c1.pack(side=LEFT)
ballScale=DoubleVar()
def ScaleVolume(v):
track.set_volume(ballScale.get())
ballScale.set(track.get_volume())
s1=Scale(app,variable=ballScale,resolution=0.1,command=ScaleVolume,orient=HORIZONTAL,from_=0.0,to=1.0,label="volume")
s1.pack()
and this is the file i use.. to call the code and run it..
from tkinter import *
import pygame.mixer
from last_function import*
app=Tk()
mixer=pygame.mixer
mixer.init()
new_gui(app,"49119_M_RED_HardBouncer.wav",mixer)
def close():
mixer.stop()
app.destroy()
app.protocol("WM_DELETE_WINDOW",close)
app.mainloop()
Everything works fine.. but my query is...
1> Why can't I remove from tkinter import* from the last_function file.. cause anyway it's got that on the top of the file that's calling it right. Why do I get an error saying IntVar() not defined.
2> Why do I have to pass mixer as a parameter in the function? can the function not inherit it directly from import pygame.mixerthat's on top of the file calling it?
What I mean to say is. THERE ARE TKINTER COMPONENTS ALSO BEING USED, BUT I DON'T PASS TKINTER AS A PARAMETER.. Do I ! then why is there this... selective parameter assignment??
I'm really confused!!!

1> Why can't i remove from tkinter
import* from the last_function file..
cause anyway it's got that on the top
of the file that's calling it
right.Why do i get an error saying
IntVar() not defined
The Python "import" follows the same scoping rules as the rest of the Python language. By "import" at the top of your second files does not make the Tkinter namespace available to the last_function.py module. Tkinter also needs to be imported there.
2>why do i have to pass mixer as a
parameter in the function? can the
function not inherit it directly from
import pygame.mixerthat's on top of
the file calling it? WHAT I MEAN TO
SAY IS. THERE ARE TKINTER COMPONENTS
ALSO BEING USED,BUT I DON'T PASS
TKINTER AS A PARAMETER.. DO I!! then
why is there this.. selective
parameter assignment??
With the way you have this coded, you need to pass mixer because you are modifying it in your second file with:
mixer.init()
If you reimported mixer in your last_function.py, you would be getting another instance of mixer and not the one previously imported. There is nothing selective about this since both of your files have the Tkinter namespace imported.
You should try and re-factor this code to avoid having to import Tkinter into two modules and having to init mixer in one module and pass it to another.

Related

Call same function using different buttons

How can i call the same function using different buttons? Currently i am creating different functions for different buttons.
from tkinter import *
from tkinter import filedialog
window=Tk()
window.title("CNO")
def browsefunc():
filename=filedialog.askopenfilename(parent=window,initialdir="C:\\Users\\jyoti\\Documents\\Python")
pathlabel_lbl1.config(text=filename)
def browsefunc1():
filename=filedialog.askopenfilename(parent=window,initialdir="C:\\Users\\jyoti\\Documents\\Python")
pathlabel_lbl2.config(text=filename)
Browse_btn=Button(window,text="Browse",command=browsefunc)
Browse_btn.grid(row=1,column=2,sticky=W+E)
pathlabel_lbl1=Label(window)
pathlabel_lbl1.grid(row=1,column=0,columnspan=2,sticky=W+E)
Browse_btn=Button(window,text="Browse",command=browsefunc1)
Browse_btn.grid(row=2,column=2,sticky=W+E)
pathlabel_lbl2=Label(window)
pathlabel_lbl2.grid(row=2,column=0,columnspan=2,sticky=W+E)
Tkinter does not limit the number of times that a function can be called through different widgets. So, you can simply put the browsefunc() as the command attribute of any number of buttons. Use the following:
from tkinter import *
from tkinter import filedialog
window=Tk()
window.title("CNO")
def browsefunc():
filename=filedialog.askopenfilename(parent=window,initialdir="C:\\Users\\jyoti\\Documents\\Python")
pathlabel_lbl1.config(text=filename)
def browsefunc1():
filename=filedialog.askopenfilename(parent=window,initialdir="C:\\Users\\jyoti\\Documents\\Python")
pathlabel_lbl2.config(text=filename)
Browse_btn=Button(window,text="Browse",command=browsefunc)
Browse_btn.grid(row=1,column=2,sticky=W+E)
pathlabel_lbl1=Label(window)
pathlabel_lbl1.grid(row=1,column=0,columnspan=2,sticky=W+E)
Browse_btn=Button(window,text="Browse",command=browsefunc)
Browse_btn.grid(row=2,column=2,sticky=W+E)
pathlabel_lbl2=Label(window)
pathlabel_lbl2.grid(row=2,column=0,columnspan=2,sticky=W+E)
window.mainloop()
You might sometimes wanna use lambda also. Although in your case it isn't required at all.
Hope this helps.
Simply edit the command=browsefunc to match your function name in both of your buttons.
Currently you have Browse_btn=Button(window,text="Browse",command=browsefunc) and Browse_btn=Button(window,text="Browse",command=browsefunc1), so just edit the last one to have the same function name to call.

What's the difference between these two [duplicate]

This question already has answers here:
Difference between import tkinter as tk and from tkinter import
(3 answers)
How do I import other Python files?
(23 answers)
Closed 4 years ago.
Can someone please explain the difference between
import tkinter as tk
and
from tkinter import *
It would be so great if someone could give and example where the same task is
achieved (or an object is created) by using these two statements seperately
Simply saying, the import tkinter as tk will initiate a tk instance of tkinter in your file which can call it's functions by writing something like
tk.Entry()
Which will save you from typing the long name.
while from tkinter import * will import all the names defined under the __all__ variable, so you can call the same function as
Entry()
You should read This to understand more
Both are importing the same package. The primary difference is that your first line is importing the package tkinter and then referring to it with "tk", which would allow you to call its functions using that different name. I don't have any experience with tkinter, but a good example I can give would be with numpy or pandas. A lot of functions in numpy, like numpy.random.randn() could instead be written with a shorthand name using "import as", like so:
import numpy as np
np.random.randn()
The differences seams little at first however import tkinter as tk is actually a much better option for one big reason.
By importing as something specific you make all the methods from that import required a prifix. This prevents methods from overriding or being overwritten accidentally.
For example if I have a library that contains a time() method and say lest call this library custom_timer and then say I need to import the built in time method also.
If use * for my import we have a problem.
from custom_timer import * # importing all modules including time() form this library.
import time # importing built in time().
What will end up happening is the 2nd import will override the time method from the first import. To prevent accidents like this we can simple import as your_prefix_here.
Take this example.
import custom_timer as ct # importing this library as ct.
import time # importing built in time().
In this case we will have 2 distinctive imports for time that do not override each other.
One is ct.time() and the other is time()
Because libraries like tkinter contain many methods it is safer to use import as verses import * for the above reason.
All that said if you are in a hurry and just want to throw something together to test an idea or answer a question using from tkinter import * is fine for much smaller applications. Personally I try to use import tkinter as tk for everything I do for good practice.
As for your request for 2 examples see below.
With tk import:
import tkinter as tk
root = tk.Tk()
tk.Label(root, text="I am a label made using tk prefix.")
root.mainloop()
With * import:
from tkinter import *
root = Tk()
Label(root, text="I am a label made in tkinter with the * import.")
root.mainloop()

How to change global variable using other file by importing

I have made this calculator on Python with GUI using Tkinter, it's my university project but there are some requirements and one is that every function should be imported in the main GUI file not to be placed there.
For example, I have created a null operator textinput for textvariable and buttons from 1 to 9 and defined a button click handler function for it:
def btnClick(numbers):
global operator
operator=operator+str(numbers)
text_Input.set(operator)
And I have saved this in the other file called "Buttons.py"
Now when i call it in my gui file like this and make a button to execute it
import Buttons
button7=Button(cal,padx=16,bd=4,fg='black',font=('The Citadels',20),
text='7',command=lambda:Buttons.btnClick(7),bg='ghost white')
.grid(row=5,column=0)
But get an error saying
name 'operator' is not defined
What is missing for my code to work ?
When you use the import statement on its own, you import the module but you don't import the namespace. operators is not defined because it is part of the module's namespace. To fix this, you can either use Buttons.operator instead of operator, or you can change your import statement to look like from Buttons import *, which will import all the variables from Buttons into your namespace as well.

Understanding import and scope

I am a noob to python and I am trying to understand how the import statement works.
I am running python 3.6.
I have IDLE working.
My test directory is setup like
directory:test_py
In the directory test_py I have files
test_calc.py,button.py,graphics.py
graphics.py is a graphics library.
My main program is in test_calc.py.
In test_calc.py I use from graphics import *. Its the first line
button.py is a module that contains a class definition, Button.
It also uses the graphics library graphics.py.
The main program in test_calc.py uses the Button class.
The Button class definition also calls Point, a function from the graphics library.
I thought the call to create a Button object would be able to use the graphcs
library from the statement from graphics import* in test_calc.py, but it cant.
button.py also needs a from graphics import * to access the graphics library functions.
Is there a way I can have just the **from graphics import* ** in test_calc.py
and have the Button class also see the graphics library
module and objects without have to also import it in button.py?
I have spent a easy 8hrs reading and trying to figure this out.
Any help is appreciated.
here is the complete test_calc.py file
from graphics import *
from button import *
def __createButtons(win):
#create a list of buttons
bSpecs = [(2,1,'0'), (3,1,'.'),
(1,2,'1'), (2,2,'2'), (3,2,'3'), (4,2,'+'), (5,2,'-'),
(1,3,'4'), (2,3,'5'), (3,3,'6'), (4,3,'*'), (5,3,'/'),
(1,4,'7'), (2,4,'8'), (3,4,'9'), (4,4,'<-'), (5,4,'C')]
buttons = []
for (cx,cy,label) in bSpecs:
buttons.append(Button(win, Point(cx,cy), .75,.75,label))
###create larger = button
buttons.append(Button(win, Point(4.5,1), 1.75, .75, "="))
#activate all buttons
for b in buttons:
b.activate()
def main():
#create the window for the calculator
win = GraphWin("Calculator")
win.setCoords(0,0,6,7)
win.setBackground("slategray")
win= win
__createButtons(win)
main()
here is the beginning of button.py
The Point function from graphics library is not available to Button without this statement
from graphics import *
class Button:
def __init__(self, win, center, width, height, label):
w,h = width/2.0, height/2.0
x,y = center.getX(), center.getY()
self.xmax, self.xmin = x+w, x-w
self.ymax, self.ymin = y+h, y-h
#Point function from graphics library
p1 = Point(self.xmin,self.ymin)
p2 = Point(self.xmax, self.ymax)
Short answer: No, there is no way to do that.
graphics.py is out of scope of button.py, because test_calc.py imported graphics and test_calc.py is in scope of button.py.
However, if you really want to save an extra line, you can just remove from graphics import * from test_calc.py because button.py already imported graphics.py.
No, you can't do this. If this worked the way you want, you'd break namespacing and scope implicitly within button, not just explicitly in test_calc.
The scope of a module (used by all things defined in that module) is defined by what it imports, and what it defines (and in poor design cases, by things monkey=patched in later). Adding in things from "stuff defined in the things that imported me" is a terrible idea.
The correct solution here is to just do:
# If a package, explicit relative imports avoid checking the whole of sys.path
from .graphics import *
# IF not a package, use plain names without leading .s
from graphics import *
at the top of your button.py file, so it actually specifies where it expects to get the APIs from (ideally, you explicitly list the names to use, not just *, which helps static checking code determine if all your names are defined, helps maintainers figure out where specific names came from, and avoids the risk of two modules providing the same name and stomping all over each other). Since you've already done this, you're golden; you can just omit the import of graphics stuff in test_calc.py (assuming test_calc.py itself doesn't use it).
If, for some insane reason, this really is necessary, the simplest way to do it is to bypass import semantics and explicitly eval the code for button in the same scope that includes the graphics stuff. In test_calc.py, after doing from graphics import *, you'd explicitly open and read the contents of button.py (into, for example, button_source) then do:
eval(compile(button_source, button_path, 'exec'), globals())
which would compile and evaluate the source code of button.py using test_calc's global scope (which includes graphics stuff now), so the newly defined stuff would be defined in test_calc's globals, and see all the stuff defined there as its "native scope" too.

Tkinter importing without *?

In my past programming i used the following code:
from tkinter import *
Gui = Tk()
but someone told me that importing * was not good for many reasons but now when i want to import
from tkinter import geometry
it says geometry not a module thing (name).
and when i do:
import tkinter
tkinter.geometry(500x500)
it says 'module' object has no attribute 'geometry'
Can someone explain me how to import with tkinter all the different ways?? Not only for geometry but most of the tkinter modules...???
That's because the module tkinter doesn't have a geometry function. It's the Tk instances that do.
Here's a good way to accomplish what you're trying to do:
import tkinter as tk # tk is a convenient, easy to type alias to use for tkinter.
gui = tk.Tk()
gui.geometry("500x500") # don't forget the quotes
Why from tkinter import * is a non-ideal way to import tkinter
As an aside, whoever told you that from tkinter import * was a bad idea was correct - when you do that, you load all of tkinter's namespace into your module's namespace.
If you do that, you can end up with unpleasant namespace collisions, like this:
from tkinter import *
gui = Tk()
Label = "hello"
Label1 = Label(gui, text=Label)
# Traceback (most recent call last):
# File "stackoverflow.py", line 98, in <module>
# Label1 = Label(gui, text=Label)
# TypeError: 'str' object is not callable
You've overwritten the reference to tkinter's Label widget - so you can't create any more Labels! Of course you shouldn't be capitalizing local variables like that anyways, but why worry about avoiding those namespace problems when you can do this instead:
import tkinter as tk
This ^^^^ import method is also preferable because if at some point you want to swap Tkinter out for another module with a similar implementation, instead of combing through your code for all elements of the Tkinter module, you can just go like this:
#import tkinter as tk
import newTkinter as tk
And you're all set. Or, if you want to use another module that happens to have some of the same names for its classes and methods, the following would cause chaos:
from tkinter import *
from evilOverlappingModule import *
but this would be fine:
import tkinter as tk
import evilOverlappingModule as evil
The reason that from module import * is considered harmful is that it pollutes the main namespace with every public name in the module. At best this makes code less explicit, at worst, it can cause name collisions. For example, module codecs has an open method defined, and there is the built-in version, which take different arguments. If I write
from codecs import *
f = open(…)
which open will I get? Tkinter has a lot of symbols, and tkinter based programs tend to use them very heavily. better than the import * is
import tkinter as tk
which then allows the — still explicit, but easier to type and read:
tk.Tk().geometry(…)
If you * imported tkinter, essentially tkinter. is in the namespace, meaning that to access to tkinter modules without worrying about prefixing it with tkinter.. In this case, geometry("500x500") is a method of Tk(), so you would use it like this
from Tkinter import *
Gui = Tk()
Gui.geometry("500x500")
Gui.mainloop()
Similar objects, such as various widgets, etc. are used the same. For example, a label would be made like this:
from Tkinter import *
Gui = Tk()
label= Label(Gui, text="Hello World!")
label.pack()
Gui.mainloop()
I don't know why someone said that importing * wasn't good cause that isn't true, it's actually better then just importing tkinter. Importing * will make the programming easier. With just tkinter you would need to type tkinter. before doing something, or if you do it as tk, you would need to do tk., from tkinter import * is the best what you can do.
Instead of doing:
from tkinter import *
You can do:
from tkinter import Tk, Canvas #The widgets you want to use
Or:
import tkinter as tk
Here’s a quick answer: Tkinter doesn’t have a geometry function. You can use the geometry function with instances of the Tk() class.
Example:
import tkinter as tk # Use the module name ’Tkinter’ if you have Python 2
root = tk.Tk()
root.geometry(‘500x500’) # You can change the size
# Other code goes here
root.mainloop()
Just like the geometry function, the mainloop, pack, grid, place, config etc. functions are used with the instances of the class Tk()
Thank You! Hope that works!

Categories

Resources