when i run this code in python 3.5:
import tkinter
top = tkinter.Tk()
def callback():
print ("click!")
button = Button(top, text="OK", command=callback)
top.mainloop()
I get an error:
NameError: name 'Button' is not defined
As said, "Button" is not defined
You should try :
import tkinter
top = tkinter.Tk()
def callback():
print ("click!")
button = tkinter.Button(top, text="OK", command=callback)
top.mainloop()
Alternatively to #freidrichen response you can either use (not recommended)
from tkinter import *
or
import tkinter as tk
then
tk.Button(top, text="OK", command=callback)
Importing the tkinter module only gives you access to the module object (tkinter). You can access any of the classes therein by writing e.g. tkinter.Button instead of just Button:
import tkinter
top = tkinter.Tk()
def callback():
print ("click!")
button = tkinter.Button(top, text="OK", command=callback)
top.mainloop()
Or you can specifically import the classes that you need from the module:
import tkinter
from tkinter import Button
top = tkinter.Tk()
def callback():
print ("click!")
button = Button(top, text="OK", command=callback)
top.mainloop()
This is a late response but while browsing the web with a similiar problem, I found this code. Hoping this works out for anyone who encounters this.
if __name__ == '__main__':
try:
from tkinter import *
except ImportError:
from Tkinter import *
Code taken from:
http://code.activestate.com/recipes/577409-python-tkinter-canvas-rectangle-selection-box/
Related
I want to detect the right click event on tkinter Menu command.
Consider code below.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
menu_button = ttk.Menubutton(root, text="MENU")
menu_button.grid()
m = tk.Menu(menu_button, tearoff=False, activeborderwidth=0)
menu_button["menu"] = m # To avoid garbage collection
m.add_command(label="an option", command=lambda: print("option1"))
m.add_command(label="another option", command=lambda: print("option2"))
root.mainloop()
When I click an option or another option, the commands are called as expected. But want I want to do is catch right click event. Can anyone knows that how can I detect it?
use button.bind("<Button-3>", event). Consider this code:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
button = tk.Button(root, text='right click this')
button.pack()
button.bind("<Button-3>", lambda e: print('You right clicked'))
root.mainloop()
filename p1.py
import tkinter as tk
def action():
import p2
root=tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn=tk.Button(root,text='click me',command=action)
btn.pack()
root.mainloop()
filename p2.py
After closing this window, I want to reopen it on clicking the click me button but it does not open once I close this window.
import tkinter as tk
root=tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl=tk.Label(root,text='Hello everybody \n I have problem',font=("times new roman",20,'bold'))
lbl.pack()
root.mainloop()
Here's a solution for you:
Module_one:
import tkinter as tk
def action():
import action_module
action_module.page_two()
root = tk.Tk()
root.title('part1')
root.geometry('200x200+50+50')
btn = tk.Button(root, text='click me', command=action)
btn.pack()
root.mainloop()
action_module:
def page_two():
import tkinter as tk
root = tk.Toplevel()
root.title('part2')
root.geometry('200x200+50+50')
lbl = tk.Label(root, text='Hello everybody \n I think the problem is fixed',
font=("times new roman", 20, 'bold'))
lbl.pack()
root.mainloop()
Just put the code in the second module inside a function. Then call it inside the first file's action function.
Lets say I have two python files. Both with an GUI. First is "Main" second is "Calculator". From Main I will start Calculator. So I have to import calculator. In Calculator I will do a calculation. Lets keep I easy an say 1+1=2. Now I want to "send" this Result to an Text in Main.
How do I do that without an circular import? I cant find an good tutorial/example for that!
My code so far:
Main:
from tkinter import *
import Test_2
window = Tk()
window.title("First Window")
def start():
Test_2.start_second()
Input1 = Entry(window)
Input1.grid(row=0,column=0, padx=10, pady=5)
Start = Button(window,text="Start", command=start)
Start.grid(row=1,column=0, padx=10, pady=5)
window.mainloop()
Second:
from tkinter import *
def start_second():
window2 = Tk()
window2.title("Second Window")
def send():
x = Input.get()
Input2 = Entry(window2)
Input2.grid(row=0,column=0, padx=10, pady=5)
Send = Button(window2,text="Send", command=send)
Send.grid(row=1,column=0, padx=10, pady=5)
window2.mainloop()
This code does exactly what you asked for (as opposed to what I suggested in the comment; but anyway, you either get a value from a module function or you send a reference for it to alter)
I tried to follow your structure.
Basically it is a matter of sending the parent window and the first entry as parameters to the second window creation function. Don't call mainloop two times, just once in the end, and use Toplevel for all other windows after the main Tk one. This is not to say that I like the use of an inner function and of the lambda, for readability, but lambdas are necessary in tkinter everytime you want to send parameters to a command callback, otherwise it will get called right way in command definition.
tkinter_w1.py (your main.py)
from tkinter import Tk, ttk
import tkinter as tk
from tkinter_w2 import open_window_2
root = Tk()
entry1 = ttk.Entry(root)
button1 = ttk.Button(root, text='Open Window 2',
command=lambda parent=root, entry=entry1:open_window_2(parent, entry))
entry1.pack()
button1.pack()
root.mainloop()
tkinter_w2.py (your Test_2.py)
from tkinter import Tk, ttk, Toplevel
import tkinter as tk
def open_window_2(parent, entry):
def send():
entry.delete(0,tk.END)
entry.insert(0,entry2.get())
window2 = Toplevel(parent)
entry2 = ttk.Entry(window2)
button2 = ttk.Button(window2, text='Send', command=send)
entry2.pack()
button2.pack()
I found the below code :
def callback(ev):
ev.widget.select_range(0, 'end')
root = Tk()
t = Text(root, height=10, width=40)
t.pack()
t.bind('<Command-a>', callback) //WORKS for ENTRY
root.mainloop()
I'm basically trying to make cmd + a or Ctrl + a (Windows) work for Text in Tkinter.
Error (When I give the command : cmd-a in text):
'Text' object has no attribute 'select_range'
The code is ok except that you are inventing methods on the Text widget. However, if you look at the bindings on the widget class (Text) there are some virtual events defined
>>> '<<SelectAll>>' in root.bind_class('Text')
True
So in your handler for the keyboard event, use event_generate to raise a SelectAll virtual event.
import tkinter as tk
def select_all(ev):
ev.widget.event_generate('<<SelectAll>>')
root = tk.Tk()
txt = tk.Text(root)
txt.pack()
txt.bind('<Control-A>', select_all)
Text class does not have select_range() function, that is why you got that error message. But you can use bind_class() to bind events to the Text class widgets. Here is a dirty demo:
import tkinter as tk
def simulate_contral_a(e):
e.widget.tag_add("sel","1.0","end")
root = tk.Tk()
root.bind_class("Text","<Control-a>", simulate_contral_a)
T = tk.Text(root, height=2, width=30)
T.pack()
T.insert(tk.END, "Press Ctrl+a\nto select me\n")
root.mainloop()
Run this MCVE above and press Ctrl + a to see its effect:
Something like this:
from Tkinter import *
root = Tk()
but = Button(root, text = "button")
but.pack()
#When I try:
but.destroy()
but.pack()
I get an error:
TclError: bad window path name ".37111768"
The pack_forget method will hide the widget and you can pack or grid it again later.
http://effbot.org/tkinterbook/pack.htm
I have managed to get it working :) here is my work:
from Tkinter import *
def changebutton():
but.destroy()
secondbut=Button(root,text="changed")
secondbut.pack()
if __name__=='__main__':
root=Tk()
global but
but= Button(root,text="button",command=changebutton)
but.pack()
root.mainloop()