I am trying to make an entry widget display beneath a Label using the .grid() function; however, it is simply not showing up. Here is my code:
#demonstrates how to use a class with Tkinter
from Tkinter import *
import tkMessageBox
class Application(Frame):
def __init__(self, master):
""" Initializes the Frame"""
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.previous_trans = Text(width = 100, height = 5, wrap = WORD)
self.previous_trans.grid(row = 0, column = 0, columnspan = 2)
self.items = Text(width = 50, height = 16, wrap = WORD)
self.items.grid(row = 1, column = 1, rowspan = 14, sticky = E)
self.additem = Label(text = "Add Item")
self.additem.grid(row = 1)
self.myentry = Entry(self)
self.myentry.grid(row = 2)
root = Tk();
root.title("Work In Progress")
app = Application(root)
root.mainloop();
The reason is because:
you don't specify a row or column for app, so it defaults to 0,0
you don't specify a parent for self.previous_trans so it defaults to the root window -- the same as for the application frame
you explicitly put self.previous_trans in row zero, column zero, which overwrites the label
You need to be giving an explicit parent of self to all of the widgets inside of Application:
self.previous_trans = Text(self, ...)
self.items = Text(self, ...)
self.additem = Label(self, ...)
self.myentry = Entry(self, ...)
Related
My goal is to have the application structure with classes and the MVC approach following the recommendations of Bryan Oakley Ref. Stackoverflow Questions How to get variable data from a class, Calling functions from a Tkinter Frame to another, etc. and the present minimum workable example is heavily relying on Bryan's code.
I am not understanding why the frame self.frame_base = ttk.Frame(self) does not expand with the container frame container = ttk.Frame(self).
I want the Labelframe "Select Data" to fill its base window and resize with it.
I tried several ideas with no success i.e. with self.frame_base = ttk.Frame(parent) the frame and its content disappears.
There is something in the parent references that I am not getting right and would appreciate any support.
Regards Alioth
import tkinter as tk
import tkinter.ttk as ttk
class progTest(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent)
self.parent = parent
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
self.frames["testGui"] = testGui(parent=container)
self.frames["testGui"].grid(row=0, column=0, sticky = 'nwes')
frame = self.frames["testGui"]
frame.tkraise()
class testGui(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent)
self.parent = parent
# Calling up of the main Gui window
self.createMainWindow(parent)
def createMainWindow(self, parent):
self.frame_base = ttk.Frame(self)
# self.frame_base = ttk.Frame(parent)
self.frame_base.grid(column = 0, row = 0, sticky = 'nwes')
self.frame_base.columnconfigure(0, weight = 1)
self.frame_base.rowconfigure(0, weight = 1)
self.labelframe_flt = ttk.LabelFrame(self.frame_base, text = "Select Data", padding = 2)
self.labelframe_flt.grid(column = 0, row = 0, sticky = "nwes", padx = 2, pady = 2)
ttk.Label(self.labelframe_flt, text="Parameter", width = 14).grid(column = 0, row = 0, sticky = "w")
self.combo_to = ttk.Combobox(self.labelframe_flt, width = 46)
self.combo_to.grid(column = 1, row = 0, padx = 10, pady = 2)
self.combo_to.config(values = ["aa", "bb", "cc", "dd"])
self.combo_to.current(0)
self.frame_base.columnconfigure(0, weight = 1)
self.frame_base.columnconfigure(1, weight = 1)
#------------------------------------------------------------------------------
def main():
root = tk.Tk()
progTest(root).pack()
root.minsize(500, 100)
root.mainloop()
#------------------------------------------------------------------------------
if __name__ == '__main__' :
main()
I want to set title for TopLevel, but TopLevel shows title of Root. I think that my next script corresponds with examples from TkInter documentation, but gives me bad result. Cann You explain me, why my setting master.title = 'Top' in class AppTop does not set new title for TopLevel?
import tkinter as tk
class AppTop(tk.Frame):
def __init__(self, master):
mon_h = 900
mon_w = 1250
master.title = 'Top'
tk.Frame.__init__(self, master)
master.minsize(height = 900, width = 600)
fr_button = tk.Frame(master)
fr_button.place(relx=0.01, rely=0.06)
butArrowPlus = tk.Button(fr_button, text=">", height = 1, width = 20, command=self.Cmd)
butArrowPlus.grid(column= 1, row= 1)
return
def Cmd(self):
return
class Application(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
frRoot = tk.Frame(master, width=700, height=400, bd=2)
frRoot.place(relx=0.1, rely=0.1, anchor="nw")
butIllumBall = tk.Button(frRoot, text= 'Light Ball', height = 1, width = 20, command=self.cmd_illuminated_ball)
butIllumBall.grid(column= 0, row= 0, pady=10)
master.minsize(height = 250, width = 300)
master.title('Root')
def cmd_illuminated_ball(self):
top = tk.Toplevel()
top.transient(self.master)
top.grab_set()
app = AppTop(master = top)
app.mainloop()
return
wndRoot = tk.Tk()
appapp = Application(master=wndRoot)
appapp.mainloop()
You try to set Toplevel title with:
master.title = 'Top'
but the correct syntax is:
master.title('Top')
There are a couple of additional things: You do not need an additional mainloop for the Toplevel window. From the code it looks like you think that the Toplevel is a new application, instantiating it with app = AppTop(master = top). But it's just a new window which runs under the appapp.mainloop().
AppTop() inherits from tk.Frame() but you never use it. Instead you put all the widgets directly in the Toplevel (master) window. Same goes for Application() as well.
I am writing a calculator program with python, and i keep getting an error message
AttributeError: 'Application' object has no attribute 'response_txt'
from tkinter import *
class Application(Frame):
""" GUI application calculator. """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
# Adds the grid layout manager
self.grid()
# The result string
self.response_str = ""
#sets up the controls in the frame
self.create_widgets()
def create_widgets(self):
""" Create and sequence """
#Text Sequence
self.sequence_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.sequence_txt.grid(row = 0, column = 0, columnspan = 2)
# Configure the Text to center
self.sequence_txt.tag_config("center_align", justify='center')
# Configure the Text to center
self.response_txt.tag_config("center_align", justify='center')
###buttons
# Button 1
Button(self,
bg='1',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
#buttons clicked
def one_btn_clicked(self):
"""This method is run when the one button gets clicked"""
#append a 1
self.response_str+="1"
#update text
self.response_txt.delete(0.0, END)
self.response_txt.insert(0.0, self.response_str, "center_align")
#add number
self.compare_sequences();
#main
root = Tk()
root.title("Calculator")
app = Application(root)
root.mainloop()
When i ran this through the module, it gave me this error:
AttributeError: 'Application' object has no attribute 'response_txt'
I tried importing a submodule like this:
`import self.response_txt`
And then it gave me this error message:
ImportError: No module named 'self'
I really need this to work, school assignment due tomorrow. Any ideas are appreciated, I am very new to programming. I am also aware that the program is not really that close to done, but before I can move to any other steps I need to make sure what I did here will work in the first place. Thank you.
You forgot to intitalise self.response_txt. Furthermore, '1' is not a valid argument for bg in the code:
Button(self,
bg='1',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
Corrected code:
from tkinter import *
class Application(Frame):
""" GUI application calculator. """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
# Adds the grid layout manager
self.grid()
# The result string
self.response_str = ""
#sets up the controls in the frame
self.create_widgets()
def create_widgets(self):
""" Create and sequence """
#Text Sequence
self.sequence_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.sequence_txt.grid(row = 0, column = 0, columnspan = 2)
self.response_txt = Text(self, height = 1, width = 30, wrap=WORD)
self.response_txt.grid(row = 0, column = 0, columnspan = 2)
# Configure the Text to center
self.sequence_txt.tag_config("center_align", justify='center')
# Configure the Text to center
self.response_txt.tag_config("center_align", justify='center')
###buttons
# Button 1
Button(self,
bg='white',
command = self.one_btn_clicked,
height = 2
).grid(row = 2, column = 0, sticky = NSEW)
#buttons clicked
def one_btn_clicked(self):
"""This method is run when the one button gets clicked"""
#append a 1
self.response_str+="1"
#update text
self.response_txt.delete(0.0, END)
self.response_txt.insert(0.0, self.response_str, "center_align")
#add number
self.compare_sequences();
#main
root = Tk()
root.title("Calculator")
app = Application(root)
root.mainloop()
Also you haven't created compare_sequences function.
How to do that the 'label' and the 'text' widgets fill all the space when 'root' is being resized?
I'd like to use the 'grid' method if it's possible.
from tkinter import *
root = Tk()
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.grid()
text = Text(root)
text.grid()
root.mainloop()
It doesn't work when I try to use in a class.
Application.py
from tkinter import *
import menu
import workPlace
class Application(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.master.title("Title")
self.master.grid_columnconfigure(0, weight = 1)
self.master.grid_rowconfigure(1, weight = 1)
self.master.resizable(width = True, height = True)
self.menu = menu.MenuBar(self)
self.menu.grid(sticky = W)
self.workPlace = workPlace.WorkPlace(self)
self.workPlace.grid(sticky = "NEWS")
if __name__ == "__main__":
Application().mainloop()
workPlace.py
from tkinter import *
import tkinter.scrolledtext as scr
class WorkPlace(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.scrText = scr.ScrolledText(self)
self.scrText.grid()
self.label = Label(self,text = "Label")
self.label.grid()
menu.py
from tkinter import *
class MenuBar(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
fileMenu = Menubutton(self, text = 'File')
fileMenu.grid(row = 0, column = 0)
me1 = Menu(fileMenu)
fileMenu.configure(menu = me1)
findMenu = Menubutton(self, text = 'Find')
findMenu.grid(row = 0, column = 1)
me1 = Menu(findMenu)
findMenu.configure(menu = me1)
optionMenu = Menubutton(self, text = 'Option')
optionMenu.grid(row = 0, column = 2)
me1 = Menu(optionMenu)
optionMenu.configure(menu = me1)
Two steps are required.
Call grid_rowconfigure and grid_columnconfigure to set the weight of each of the grid's rows and columns. Rows and columns with a weight of zero don't stretch at all during a resize. This is the default behavior.
When calling grid on your widgets, specify the sticky parameter so the widgets stretch whenever their row or column stretches.
from tkinter import *
root = Tk()
root.grid_columnconfigure(0, weight=1)
#uncomment this line if you want the Label widget to stretch vertically.
#or leave it as is if you only want the Text widget to stretch.
#root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.grid(sticky="NEWS")
text = Text(root)
text.grid(sticky="NEWS")
root.mainloop()
In the specific case of your WorkPlace object, you need to configure both the root object and the WorkPlace object, and you need to specify stickiness for the WorkPlace object and its child objects.
from tkinter import *
import tkinter.scrolledtext as scr
class WorkPlace(Frame):
def __init__(self, boss = None):
Frame.__init__(self)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.scrText = scr.ScrolledText(self)
self.scrText.grid(sticky="NEWS")
self.label = Label(self,text = "Label")
self.label.grid()
If you are okay with using pack instead of grid, you can do
from tkinter import *
root = Tk()
root.resizable(width = True, height = True)
label = Label(root, text = "Text")
label.pack(fill=X)
text = Text(root)
text.pack(fill=BOTH, expand=True)
root.mainloop()
I am trying to change a label automatically in python, I want it to change every half a second, this is my code for tkinter, the function being called (that is being put into "message") returns a new string every half a second, what am I doing wrong?
import Tkinter as tk
class Application(tk.Frame):
def __init__(self):
self.root = tk.Tk()
self.root.geometry("150x136")
tk.Frame.__init__(self, self.root)
self.create_widgets()
def create_widgets(self):
self.root.bind('<Return>', self.parse)
self.grid()
self.instruction = tk.Label(self, text = "QuickReader")
self.instruction.grid(row = 0, column = 0, columnspan = 4)
self.entry = tk.Entry(self)
self.entry.grid(row = 2, column = 0)
self.submit = tk.Button(self, text="Submit")
self.submit.bind('<Button-1>', self.parse)
self.submit.grid(row = 4, column = 0)
self.words = tk.Label(self, text = "Start")
self.words.grid(row = 5, column = 0, columnspan = 4)
def parse(self, event):
filename = self.entry.get()
message = open_txt(filename)
self.words.set(message)
def start(self):
self.root.mainloop()
Application().start()
To change label text, use one of following:
self.words.config(text=message)
self.words.configure(text=message)
self.words['text'] = message
http://effbot.org/tkinterbook/label.htm
You can associate a Tkinter variable with a label. When the contents of the variable changes, the label is automatically updated:
v = StringVar()
Label(master, textvariable=v).pack()
v.set("New Text!")
So, that should be pretty easy to implement.