Tkinter (python 2.7.2) Help needed - python

I'm trying to make my first GUI program. The problem is, that I can't figure out how to make a main menu, which would switch to one of the programs after clicking a button.
#Dev by Mkee
from Tkinter import *
import tkMessageBox
#Main Stuff
app = Tk()
app.title("Mkee's Tools")
app.geometry('300x200')
#modules
class Programs:
def Shuffle():
app2 = Tk()
app2.title("Shuffle")
app2.geometry('300x200')
app2.mainloop()
#end of modules
labelText = StringVar()
labelText.set('')
label1 = Label(app, textvariable=labelText, height=4)
label1.pack()
button1 = Button(app, text='Shuffle', width=30, command=Programs.Shuffle)
button1.pack(side='right', padx=5,pady=1)
app.mainloop()
I know that I'm doing it wrong. I just have no idea how to do it, So i gave it a try of how could it be. Please help me.

You could call pack_forget() to hide widgets, and (later)
pack to show them again:
Tkinter is singled-threaded, and mainloop runs the main event loop. Therefore you shouldn't call mainloop twice.
#Dev by Mkee
import Tkinter as tk
import sys
class Shuffle(object):
def __init__(self,master=None):
self.master=master
self.text=tk.Text(master)
def hide(self):
self.text.pack_forget()
def show(self):
self.text.pack(side=tk.LEFT, padx=5, pady=5)
class Buttons(object):
def __init__(self,master=None):
self.master=master
self.red = tk.Button(self.master, text="Red", bg="red", fg="white")
self.green = tk.Button(self.master, text="Green", bg="green", fg="black")
self.blue = tk.Button(self.master, text="Blue", bg="blue", fg="white")
def hide(self):
self.red.pack_forget()
self.green.pack_forget()
self.blue.pack_forget()
def show(self):
self.red.pack(side=tk.LEFT,expand=tk.YES,fill=tk.BOTH)
self.green.pack(side=tk.LEFT,expand=tk.YES,fill=tk.BOTH)
self.blue.pack(side=tk.LEFT,expand=tk.YES,fill=tk.BOTH)
class MainApp(object):
def __init__(self,master=None):
self.master=master
app=self.app=tk.Tk()
app.title("Mkee's Tools")
app.geometry('300x200')
self.shuffle=Shuffle(master)
self.buttons=Buttons(master)
self.current=None
menubar=tk.Menu(app)
program_menu=tk.Menu(menubar)
program_menu.add_command(label='Shuffle',
command=lambda: self.show(self.shuffle))
program_menu.add_command(label='Buttons',
command=lambda: self.show(self.buttons))
program_menu.add_command(label='Quit',command=sys.exit)
menubar.add_cascade(label='Programs', menu=program_menu)
app.config(menu=menubar)
def show(self,obj):
if self.current != obj:
try: self.current.hide()
except AttributeError: pass
self.current=obj
obj.show()
def main():
m=MainApp()
m.app.mainloop()
if __name__=='__main__':
main()

Related

Hide a Button in Tkinter

I want to hide a tkinter button but not when the user clicks it. I just want to hide it, at random times. How will I do that in Python? Below is the code I tried:
self.startGame = Button(self.canvas, text="Start", background='white', command = self.startGame, font=("Helvetica"))
self.startGame.place(x=770, y=400)
Hiding it:
self.startGame.bind('<Button-1>', self.hide_me)
def hide_me(self, event):
print('hide me')
event.widget.pack_forget()
It doesn't even get inside the hide_me function.
As pointed out in the comments you should use place_forget() for widgets that were set on the screen using place().
Same goes for pack() and grid(). You would use pack_forget() and grid_forget() respectively.
Here is a modified example of your code.
import tkinter as tk
class Example(tk.Tk):
def __init__(self):
super().__init__()
canvas = tk.Canvas(self)
canvas.pack()
self.startGame = tk.Button(canvas, text="Start", background='white', font=("Helvetica"))
self.startGame.place(x=150, y=100)
self.startGame.bind('<Button-1>', self.hide_me)
def hide_me(self, event):
print('hide me')
event.widget.place_forget()
if __name__ == "__main__":
Example().mainloop()
That said you do not need a bind here. Simply use a lambda statement in your command like this:
import tkinter as tk
class Example(tk.Tk):
def __init__(self):
super().__init__()
canvas = tk.Canvas(self)
canvas.pack()
self.startGame = tk.Button(canvas, text="Start", background='white', font=("Helvetica"),
command=lambda: self.hide_me(self.startGame))
self.startGame.place(x=150, y=100)
def hide_me(self, event):
print('hide me')
event.place_forget()
if __name__ == "__main__":
Example().mainloop()

I need to know how to exec two commands on the same var with Tkinter

from tkinter import *
class Janela:
def __init__(self, master):
self.master = master
self.master.geometry('800x480-3+0')
self.start = Button(text="Start", font="minecraftia 18", bg="grey", command=self.menu)
self.start.place(x=364, y=290)
def menu(self):
jan1 = Tk()
self.bt1 =Button(jan1, text = "next", command=self.jans)
self.bt1.place(x=200, y=200)
jan1.geometry("800x480-3+0")
def jans(self):
jan2 = Tk()
self.bt2 =Button(jan2, text="back", command=jan2.destroy, command=jan1.destroy)
self.bt2.place(x=200, y=200)
jan2.geometry("800x480-3+0")
root = Tk()
Janela(root)
root.mainloop()
A rather simple solution will be to create a function_A that calls 2 functions or methods. And then bind that function to the Tkinter button.
def function_A(func1, func2):
func_1() # or method
func_2() # or method
So in your function
def jans(self):
jan2 = Tk()
def double_command():
jan2.destroy()
jan1.destroy()
self.bt2 =Button(jan2, text="back", command=double_command)
self.bt2.place(x=200, y=200)
jan2.geometry("800x480-3+0")
and in Tkinter button you can
self.bt2 =Button(jan2, text="back", command=double_command)

tkinter button in class won't bind to key

Total noob can't make tkinter button bind to keyboard.
I've tried to bind they both in main() and in the init().
I've tried bunches of permutations of syntax. Nothing works.
I've tried around until the button(s) get focus and hitting then. NOTHING HAPPENS.
Anyone have the secret insider information on how to do it?
from tkinter import *
from tkinter.ttk import Frame, Button, Style
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
self.btn_convert.bind("<Return>", self.convert)
# -----------------------------------------------
def convert(self):
print("enter pressed")
# -----------------------------------------------
def quit(self):
self.root.destroy()
exit()
# -----------------------------------------------
def initUI(self):
self.master.title("Weight Converter")
self.pack(fill=BOTH, expand=True)
self.frame_btn = Frame(self)
self.frame_btn.pack(fill=BOTH, expand=True, padx=20, pady=5)
self.btn_convert=Button(self.frame_btn, text="Convert", command=self.convert)
self.btn_convert.pack(side=LEFT, padx=5, pady=5)
self.btn_close1=Button(self.frame_btn, text="Close", command=quit)
self.btn_close1.pack(side=LEFT, padx=5, pady=5)
def main():
root = Tk()
root.geometry("300x250+300+200")
app = Example()
root.bind("<Return>", lambda event: root.convert())
root.mainloop()
if __name__ == '__main__':
main()
Replace:
root.bind("<Return>", lambda event: root.convert())
with:
root.bind("<Return>", lambda event: app.convert())
or:
#in case you have multiple instances of Tk
app.bind("<Return>", lambda event: app.convert())
app.focus_set()
As convert is a method for Example instance(app) as opposed to Tk instance(root). Also, make sure that the object.bind is used on(root in above two lines and app onthe last line) has the focus by either manually focusing or calling object.focus_set().
Below is an example that prints "Enter" or "Escape" based on the keypress:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.button = tk.Button(self, text="Event")
self.button.bind('<Return>', lambda evt : self.event_handler(True))
self.button.focus_set() # ensure initial focus is on the button
self.button.pack()
def event_handler(self, is_enter):
if is_enter:
my_string = "Enter"
else:
my_string = "Escape"
print(my_string)
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
app.button.bind('<Escape>', lambda evt : app.event_handler(False))
app.pack()
root.mainloop()
Demo Example for all keys
Below demo should be displaying the pressed key for all keys:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def on_key_press(event):
global label
label['text'] = event.keysym
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root)
root.bind('<KeyPress>', on_key_press)
label.pack()
root.mainloop()
To add a general "press Enter to run convert" binding, you should apply it to root. To add further focus-based bindings, you should apply them on a per-button basis, like so:
from tkinter import *
from tkinter.ttk import Frame, Button, Style
class Example(Frame):
def __init__(self):
super().__init__()
self.initUI()
# -----------------------------------------------
def convert(self):
print("enter pressed")
# -----------------------------------------------
def quit(self):
print("quit pressed")
self.destroy()
exit()
# -----------------------------------------------
def initUI(self):
self.master.title("Weight Converter")
self.pack(fill=BOTH, expand=True)
self.frame_btn = Frame(self)
self.frame_btn.pack(fill=BOTH, expand=True, padx=20, pady=5)
self.btn_convert=Button(self.frame_btn, text="Convert", command=self.convert)
self.btn_convert.pack(side=LEFT, padx=5, pady=5)
self.btn_close1=Button(self.frame_btn, text="Close", command=quit)
self.btn_close1.pack(side=LEFT, padx=5, pady=5)
# When tab focus is on the "Close" button, change Return behaviour.
self.btn_close1.bind("<Return>", lambda event: self.quit())
def main():
root = Tk()
root.geometry("300x250+300+200")
app = Example()
root.bind("<Return>", lambda event: app.convert())
root.mainloop()
if __name__ == '__main__':
main()

Simple dialogbox multitasking

How do ask a string and a integer question in a single simpledialogbox in tkinter without opening another simpledialogbox
from tkinter import *
from tkinter import simpledialog
simpledialog. askstring("name", "what is your name ")
Mainloop()
You could use Toplevel() to create your own version of a simpledialog, something like the below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.button1 = Button(self.root, text="Ok", command=self.drawtop)
self.button1.pack()
def drawtop(self):
self.top = Toplevel(root)
self.entry1 = Entry(self.top)
self.entry2 = Entry(self.top)
self.button2 = Button(self.top, text="Done", command=self.printtop)
self.entry1.pack()
self.entry2.pack()
self.button2.pack()
def printtop(self):
print(self.entry1.get())
print(self.entry2.get())
self.top.destroy()
root = Tk()
App(root)
root.mainloop()

I have too fix something in my Copy&Paste program in Python

This is my Copy&Paste program:
from tkinter import *
import Pmw
class CopyTextWindow(Frame):
def __init__(self):
Frame.__init__(self)
Pmw.initialise()
self.pack(expand=YES, fill=BOTH)
self.master.title("ScrolledText Demo")
self.frame1=Frame(self, bg="White")
self.frame1.pack(expand=YES, fill=BOTH)
self.text1=Pmw.ScrolledText(self, text_width=25, text_height=12, text_wrap=WORD,
hscrollmode="static", vscrollmode="static")
self.text1.pack(side=LEFT, expand=YES, fill=BOTH, padx=5, pady=5)
options = ["Copy", "Paste"]
self.selectedOption = StringVar()
self.menu = Menu(self.frame1, tearoff=0)
for option in options:
self.menu.add_radiobutton( label=option, variable=self.selectedOption,
command=self.ExecuteOption)
self.text1.bind("<Button-3>", self.popUpMenu)
def popUpMenu(self, event):
self.menu.post(event.x_root, event.y_root)
def ExecuteOption(self):
if self.selectedOption.get()=="Copy":
self.CopiedText=self.text1.get(SEL_FIRST, SEL_LAST)
else:
self.text1.settext( self.text1.get()+self.CopiedText)
def main():
CopyTextWindow().mainloop()
if __name__=="__main__":
main()
In this program, I want to make a GUI, that in it you can copy and paste text that you have selected. when you press the right mouse button, a little menu with the Copy and Paste options.
The program opens up, but when I press the right mouse button, no menu appears. Python also doesn't complain with an error.
I need to understand my mistake in this code.
For a reason I ignore, the event doesn't seem to be triggered when the bind is on the Text or on the Frame, but it works when it's on the main window:
from tkinter import *
import Pmw
class CopyTextWindow(Frame):
def __init__(self, master=None):
# I've added a master option to pass to the frame
Frame.__init__(self, master)
Pmw.initialise()
self.pack(expand=YES, fill=BOTH)
self.master.title("ScrolledText Demo")
self.frame1=Frame(self, bg="White")
self.frame1.pack(expand=YES, fill=BOTH)
self.text1=Pmw.ScrolledText(self, text_width=25, text_height=12, text_wrap=WORD,
hscrollmode="static", vscrollmode="static")
self.text1.pack(side=LEFT, expand=YES, fill=BOTH, padx=5, pady=5)
options = ["Copy", "Paste"]
self.selectedOption = StringVar()
self.menu = Menu(self.frame1, tearoff=0)
for option in options:
self.menu.add_radiobutton( label=option, variable=self.selectedOption,
command=self.ExecuteOption)
def popUpMenu(self, event):
print("ok")
self.menu.post(event.x_root, event.y_root)
def ExecuteOption(self):
if self.selectedOption.get()=="Copy":
self.CopiedText=self.text1.get(SEL_FIRST, SEL_LAST)
else:
self.text1.settext( self.text1.get()+self.CopiedText)
def main():
# main window
root = Tk()
ctw = CopyTextWindow(root)
# bind on the main window
root.bind("<Button-3>", ctw.popUpMenu)
root.mainloop()
if __name__=="__main__":
main()

Categories

Resources