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.
Related
I have some general questions regarding working code below:
tkinter is library for graphic interface as I understand I can use it interchangeably with for example Kivy?
Would it be better to learn Kivy instead or other?
Lines import tkinter as tk and from tkinter import * do exactly the same, in the first one I have alias though?
In the code below, why do I have to use ttk in ttk.Progressbar?
I imported whole library with import tkinter as tk so why do i have to reimport ttk just for progress bar? (otherwise it is not working). I would expect to work sth. like tk.Progressbar
In the line btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress), why method "fnUpdateProgress" can't have any variables? Whenever I add any, the button stop working? -> for example btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress(24)) (ofc then some changes in def of the method itself)
I created progress bar (pb) as attribute of the class Test, but wolud it be better to define it as regular variable (without self)? To be honest, code works exactly the same.
Code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from CreateProgramMain import main
import GlobalVariables
class Test():
####################################################################################
def __init__(self):
self.Progress=0
self.root = tk.Tk()
self.root.title(GlobalVariables.strAppName)
self.root.geometry('400x200')
lbl = Label(self.root, text="Please choose environment.",font=("Arial Bold", 12))
lbl.grid(column=2, row=0,sticky='e')
def btnTestClicked():
main("TEST",self)
btnTest=tk.Button(self.root, text="Test Environment", command=btnTestClicked)
btnTest.grid(column=2, row=15)
#Place progress bar
pb = ttk.Progressbar(self.root,orient='horizontal',mode='determinate',length=200)
pb.grid(column=1, row=65, columnspan=2, padx=10, pady=20)
pb["value"]=self.Progress
pb["maximum"]=100
btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress)
btnProg.grid(column=2, row=75)
self.root.mainloop()
def fnUpdateProgress(self): #why i cant insert variable inside?
pb["value"]=self.Progress
self.Progress=self.Progress+5
pb.update()
app = Test()
Thank you
it is upto you. However, tkinter and kivy both have their own syntaxes, commands, and their own usages. It might be a little difficult to convert tkinter code to kivy.
it is upto you
Yes. In the first, you have imported tkinter as tk. In the second one. You have done a wild card import. You have imported everything
Tkinter is a folder containing various modules. It contains a file called ttk.py which you have to import to access ttk.
All other classes like Label, Entry, Tk is present in __init__.py
you have to use lambda for it. If you call the function, it will be executed wlright away and the returned value is kept as the command.
Doing command=self.fnUpdateProgress(24)) will execute the function right away. Then, the returned value is kept as a command. Here, it returns None. So the command is nothing or the button is useless.
Use a lambda expression command=lambda: self.fnUpdateProgress(24))
if you don't add self it will be local to the function only. To access ot outside, it would have to be declared global, which is the point to avoid while using classes
ı am new in tkinter. I want to multpily two inputs box. my codes are below. The problem is when i run it runs as x2*x2 but i want to x2*x1 how can ı fix this code it runs only one box
import tkinter as tk
from functools import partial
from tkinter import *
root=tk.Tk()
root.geometry("900x900+100+200")
root.title("Converter")
root.configure(background="grey")
root.resizable(width=False,height=False)
def call_result15(rL,inputn):
x1=inputn.get()
x2=inputn.get()
h=float(float(x1)*float(x2))
rL.config(text="% f " % h)
return
numberInput=tk.StringVar()
var=tk.StringVar()
input_label=tk.Label(root,text="x1",background="white",foreground="black")
input_entry=tk.Entry(root,textvariable=numberInput)
input_label.grid()
input_entry.grid()
numberInput2=tk.StringVar()
var2=tk.StringVar()
input_label=tk.Label(root,text="x2",background="white",foreground="black")
input_entry=tk.Entry(root,textvariable=numberInput2)
input_label.grid()
input_entry.grid()
rlabel=tk.Label(root,text="h1",background="white",foreground="black")
rlabel.grid()
call_result15=partial(call_result15,rlabel,numberInput2)
result_button.grid()
root.mainloop()
def call_result15(rL,inputn):
x1=inputn.get()
x2=inputn.get()
x1 and x2 are both read from the same supplied inputn parameter...
call_result15=partial(call_result15,rlabel,numberInput2)
which is bound here. So of course we multiply the value from numberInput2 by itself.
You need to write the callback so it accepts (and uses) both inputs, and bind both of them in the partial.
I have a problem that annoys me. I am currently building a small app with a Tkinter GUI.
On the front page, I want some introductory text in either a text or a scrolledtext widget. The code examples I've come across uses keywords such as INSERT, CURRENT and END for indexation inside the widget.
I have literally copy pasted the below code into my editor, but it doesn't recognise INSERT (throws error: "NameError: name 'INSERT' is not defined"):
import tkinter as tk
from tkinter import scrolledtext
window = tk.Tk()
window.title("test of scrolledtext and INSERT method")
window.geometry('350x200')
txt = scrolledtext.ScrolledText(window,width=40,height=10)
txt.insert(INSERT,'You text goes here')
txt.grid(column=0,row=0)
window.mainloop()
I can get the code to work if I change [INSERT] with [1.0], but it is very frustrating that I cannot get INSERT to work, as I've seen it in every example code I've come across
Use tk.INSERT instead of only INSERT. Full code is shown.
import tkinter as tk
from tkinter import scrolledtext
window = tk.Tk()
window.title("test of scrolledtext and INSERT method")
window.geometry('350x200')
txt = scrolledtext.ScrolledText(window,width=40,height=10)
txt.insert(tk.INSERT,'You text goes here')
txt.grid(column=0,row=0)
window.mainloop()
You don't need to use the tkinter constants. I personally think it's better to use the raw strings "insert", "end", etc. They are more flexible.
However, the reason the constants don't work for you is that you're not directly importing them. The way you're importing tkinter, you need to use tk.INSERT, etc.
INSERT could not be used directly.
You can use it in the past just because you used this in the past:
from tkinter import * # this is not a good practice
INSERT,CURRENT and END are in tkinter.constants.Now in your code,you even didn't import them.
If you want to use them,you can use
from tkinter.constants import * # not recommended
...
txt.insert(INSERT,'You text goes here')
Or
from tkinter import constants
...
txt.insert(constants.INSERT,'You text goes here') # recommend
If didn't want to import them,you can also use:
txt.insert("insert",'You text goes here')
Edit:I found in the source code of tkinter,it had import them,reboot's answer is also OK.
The StringVar.get() method returns a blank value when the function c() is called. However, it works perfectly fine when I call only the new_db () function.
I really cannot understand the problem. Could somebody explain it to me?
#modules
import os
from Tkinter import *
chance=3
def cr():
print data.get()
#new_db
def new_db():
global data
m.destroy()
new=Tk()
data=StringVar()
Entry(new,font='BRITANIC 16',textvariable=data).grid(column=1,row=2)
Button(new,text='Create New Database',command=cr).place(x=175,y=75)
new.geometry('500x100+400+250')
new.mainloop()
def c():
global m
m=Tk()
Button(m,text='erferf',command=new_db).pack()
m.mainloop()
c()
Look at this answer When do I need to call mainloop in a Tkinter application?. It tells that the mainloop() must be called once and only once.
Also, the Tk object m should still exist when new_db() is executed on the click of the Button.
For what you try to accomplish, you should create the Tk() only once, and call mainloop() only once. Then you shoud place code to hide/show the appropriate widgets. Look at In Tkinter is there any way to make a widget not visible? to know how to show/hide widgets.
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!