I have done a simple tkinter GUI, i wanted a browse button but it doesn't seem to appear
#!/usr/bin/env python
import Tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.quit_program()
def quit_program(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.grid()
def browse_file(self):
self.browseButton = tk.Button(self, text='Browse',
command=tkFileDialog.askopenfilename(parent=root,title='Open file to encrypt'))
self.browseButton.grid()
app = Application()
app.master.title('Sample application')
app.mainloop()
#!/usr/bin/env python
import Tkinter as tk
import tkFileDialog
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.quit_program()
self.browse_file()
self.file_opt = options = {}
options['defaultextension'] = '.txt'
options['filetypes'] = [('musicfiles', '.mp3'),('vediofiles', '.mp4')]
options['parent'] = self
options['title'] = 'This is a title'
def quit_program(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.grid()
def browse_file(self):
self.browseButton = tk.Button(self, text='Browse',command=self.askopenfile)
self.browseButton.grid()
def askopenfile(self):
return tkFileDialog.askopenfile(**self.file_opt )
app = Application()
app.master.title('Sample application')
app.mainloop()
Three mistakes in your code
What is tkFileDialog? Have you imported it? Import it by adding import tkFileDialog at the top of your file
What is root? Change root to self.
The command argument in the tk.Button is not meant to be used the way you have. You should not call the method in the command argument. You should specify a method to be called when the button is clicked. In your example, you are telling tkinter, to call the value returned by tkFileDialog.askopenfilename() instead of calling tkFileDialog.askopenfilename. So replace it with another method or use a lambda.
command=lambda : tkFileDialog.askopenfilename(parent=root,title='Open file to encrypt')
Related
I want to have several Checkboxes in an CustomFrame, but currently have the following missbehaviour:
If I click on a Checkbox, the whole column gets active and I want to have one the clicked one to be active. Is it possible to "reuse" Checkboxes in tk-derived classes and declare them in Subclasses?
Mainwindow which uses SubFrames:
import tkinter as tk
import zmq
from time import sleep
import time
from threading import Thread
from glmPygameGlue import *
from networkRenderGlue import *
from quatLTI import *
import guiWidgets as gw
class Window(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
#super().__init__()
self.accWidget = gw.Widget_Vector(self, "ACC")
self.gyroWidget = gw.Widget_Vector(self, "GYRO")
self.magWidget = gw.Widget_Vector(self, "MAG")
self.accWidget.grid(column=0, row=0)
self.gyroWidget.grid(column=0, row=1)
self.magWidget.grid(column=0, row=2)
self.grid(column=0, row=0)
def AccBiasEnable(self):
print("window accBiasEnable")
def onClose(self):
exit()
root = tk.Tk()
app = Window(root)
root.protocol("WM_DELETE_WINDOW", app.onClose)
root.wm_title("Input-Gui Quaternion-HP")
root.geometry("500x500")
root.mainloop()
SubFrames:
import tkinter as tk
class TripleCheckboxVertical(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.xBias = tk.Checkbutton(self, text='bias', command=master.master.AccBiasEnable)
self.yBias = tk.Checkbutton(self, text='cos')
self.zBias = tk.Checkbutton(self, text='noise')
self.xBias.grid(column=0, row=0)
self.yBias.grid(column=1, row=0)
self.zBias.grid(column=2, row=0)
def callBackFunc(self, event=None):
print("cb event!1")
class Widget_Vector(tk.LabelFrame):
def __init__(self, master=None, text_=""):
tk.LabelFrame.__init__(self, master, text=text_)
self.master = master
self.labelX = tk.Label(self, text="x")
self.labelY = tk.Label(self, text="y")
self.labelZ = tk.Label(self, text="z")
self.cb3X = TripleCheckboxVertical(self)
self.cb3Y = TripleCheckboxVertical(self)
self.cb3Z = TripleCheckboxVertical(self)
self.labelX.grid(column=0, row=0)
self.labelY.grid(column=0, row=1)
self.labelZ.grid(column=0, row=2)
self.cb3X.grid(column=1,row=0)
self.cb3Y.grid(column=1,row=1)
self.cb3Z.grid(column=1,row=2)
Any ideas?
Thank you
To resolve your issue, add a variable to each checkbutton. I've created 3 BooleanVar which store the value of the checkbutton and makes them behave independently. I've also added a get method to return the value of each checkbox:
class TripleCheckboxVertical(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.xBiasVar = tk.BooleanVar()
self.yBiasVar = tk.BooleanVar()
self.zBiasVar = tk.BooleanVar()
self.xBias = tk.Checkbutton(self, text='bias', variable = self.xBiasVar, command=master.master.AccBiasEnable)
self.yBias = tk.Checkbutton(self, text='cos', variable = self.yBiasVar)
self.zBias = tk.Checkbutton(self, text='noise', variable = self.zBiasVar)
self.xBias.grid(column=0, row=0)
self.yBias.grid(column=1, row=0)
self.zBias.grid(column=2, row=0)
def get(self):
return {"bias":self.xBiasVar.get(), "cos":self.yBiasVar.get(), "noise":self.zBiasVar.get()}
I also added a get method to Widget_Vector:
def get(self):
return {"x":self.cb3X.get(), "y":self.cb3Y.get(), "z":self.cb3Z.get()}
If you wanted the value of x bias for GYRO, for example, you can do self.gyroWidget.get()["x"]["bias"]
i am using tkinter for python gui app development.
i want to disappear a page when user will sweep to new page.
i am just open a new object of new class, and want to disappear it by destroy() but destroy not works
code -
import reg as r
from tkinter import *
import tkinter as tk
LARGE_FONT = ("Verdana", 12)
class Main(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
label = tk.Label(self, text="Tech Eye", font=LARGE_FONT)
label.pack()
self.button2 = Button(self.parent, text="Admin Registration", command=self.reg).place(x=260, y=300)
self.button3 = Button(self.parent, text="Exit", command=self.destroy).place(x=220, y=350)
#this destroy also not working
def reg(self):
new = tk.Tk()
new.geometry("600x600")
new.title("Third Eye")
self.destroy()
st = r.Registration(new)
#r is the another python file what i imported and Registration is the class
st.mainloop()
if __name__ == '__main__':
root = tk.Tk()
root.geometry("600x600")
root.title("Third Eye")
run = Main(root)
root.mainloop()
what i can do now?
I am creating 2 window in my program and i am using two class, since the code is complex, i separate it in 2 different python file. After i imported the second window file, how can i make sure it open without having this error which show in this picture
The original result should look like this after the new window button clicked:
Coding for Main Window:
from tkinter import *
import classGUIProgram
class Window(Tk):
def __init__(self, parent):
Tk.__init__(self, parent)
self.parent = parent
self.initialize()
def initialize(self):
self.geometry("600x400+30+30")
self.wButton = Button(self, text='newWindow', command = self.OnButtonClick)
self.wButton.pack()
def OnButtonClick(classGUIProgram):
classGUIProgram.top = Toplevel()
master = Tk()
b = classGUIProgram.HappyButton(master)
master.mainloop()
if __name__ == "__main__":
window = Window(None)
window.title("title")
window.mainloop()
Coding for Second Window:
from tkinter import *
class HappyButton:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.printButton = Button(frame, text="Print message", command=self.printMessage)
self.printButton.pack(side=LEFT)
self.quitButton = Button(frame, text="Quit", command= quit)
self.quitButton.pack(side=LEFT)
self.downloadHistoryCB=Checkbutton(frame, text="Download History")
self.downloadHistoryCB.pack(side=LEFT)
def printMessage(self):
print("Wow this actually worked!")
master = Tk()
b = HappyButton(master)
master.mainloop()
You're creating extra Tk windows. Here is an example of using Toplevel widgets and another file.
mainWindow.py
import tkinter as tk
import secondWindow as sW
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
self.title("Main Window")
self.geometry("600x400+30+30")
tk.Button(self, text = "New Window", command = self.new_window).pack()
tk.Button(self, text = "Close Window", command = self.close).pack()
self._second_window = None
def new_window(self):
# This prevents multiple clicks opening multiple windows
if self._second_window is not None:
return
self._second_window = sW.SubWindow(self)
def close(self):
# Destory the 2nd window and reset the value to None
if self._second_window is not None:
self._second_window.destroy()
self._second_window = None
if __name__ == '__main__':
window = MainWindow()
window.mainloop()
secondWindow.py
import tkinter as tk
class SubWindow(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.title("Sub Window")
self.geometry("400x300+30+30")
# Change what happens when you click the X button
# This is done so changes also reflect in the main window class
self.protocol('WM_DELETE_WINDOW', master.close)
tk.Button(self, text = "Print", command = self.printMessage).pack()
def printMessage(self):
print("Wow this actually worked!")
When using another file be sure to not have any global code you don't want running. Your classes don't have to inherit from Tk and Toplevel, this is just an example. But you need to ensure you only ever have one instance of Tk otherwise you get the behaviour you encountered
I am trying to create multiple windows using tkinter , but i am having no success so far ... When i create a child window and put a button on it , the button is created in the parent window!
from tkinter import *
class Login_screen(Frame):
def __init__(self,master):
Frame.__init__(self, master)
self.grid()
self.button1 = Button(text = "Open",command = lambda: self.open_login())
self.button1.grid()
def open_login(self):
self.root2 = Toplevel()
self.root2.geometry("400x200")
self.app2 = Main_screen(self.root2)
class Main_screen(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.grid()
self.button = Button(text = "Close",command = lambda: self.close_windows())
self.button.grid()
def close_windows(self):
self.grid_forget()
root = Tk()
root.geometry("800x600")
app = Login_screen(root)
root.mainloop()
You need to supply the Button() with the master argument:
self.button = Button(master = self, text = "Close",command = lambda: self.close_windows())
master is the first arg to a widget so it can also be done via: Button(self, text=...)
This is good practice and you should get in the habit of always explicitly providing master, otherwise Tk defaults this arg to None and will place it on the root window.
I have attached my code so that you can all see if you can identify the problem. Everything is working, and the window is popping up, but the button widgets are not showing:
from Tkinter import *
class Application(Frame):
"""Login"""
def _init_(self, master):
self.master = master
def create_widgets(self):
btn1 = Button(self.master, text = "Login")
btn1.pack()
btn2 = Button(self.master, text = "Sign Up")
btn2.pack()
btn3=Button(self.master, text = "Exit")
btn3.pack()
root = Tk()
root.title("Parent Pool")
root.geometry("500x500")
app = Application(root)
root.mainloop()
You forgot to call create_widgets. And your defs need to be indented inside the class.
from Tkinter import *
class Application(Frame):
"""Login"""
def __init__(self, master):
self.master = master
def create_widgets(self):
btn1 = Button(self.master, text = "Login")
btn1.pack()
btn2 = Button(self.master, text = "Sign Up")
btn2.pack()
btn3=Button(self.master, text = "Exit")
btn3.pack()
root = Tk()
root.title("Parent Pool")
root.geometry("500x500")
app = Application(root)
app.create_widgets()
root.mainloop()
By the way, your _init_ function won't get called when you create an Application instance. You need to name it __init__ if you want that behavior. (Your Buttons can still reference self.master even though _init_ never runs, because Frame.__init__ gets called as a fallback during instantiation, and creates the master attribute by coincidence)