Python tkinter - Text not showing (GUI) - python

I have no bug errors and I was wondering why 'TIMER' is not showing up in the GUI when I run it. It just shows a white box. I`ve tried searching the forums for an issue similar to mine but I failed to find any.
CODE:
import tkinter
class study_timer:
def __init__(self, master):
self.master = master
self.mainframe = tkinter.Frame(self.master, bg='white')
self.mainframe.pack(fill = tkinter.BOTH, expand=True)
self.build_grid()
self.build_banner()
def build_grid(self):
self.mainframe.columnconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
self.mainframe.rowconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
def build_banner(self):
banner = tkinter.Label(
self.mainframe,
bg='black',
text='TIMER',
fg='white',
font=('Ravie Regular', 30)
)
banner.grid(
row=0, column=0,
stick='ew',
padx=10, pady=10
)
if __name__ == "__main__":
root = tkinter.Tk()
root.mainloop()

You should instantiate an object of the class if you want to run the functions that you defined. The functions are called from constructor(init) in your class structure.
Second, if statement's indentation is wrong.
Third, you should send the root object to init function as parameter.
This will work
import tkinter
class study_timer:
def __init__(self, master):
self.master = master
self.mainframe = tkinter.Frame(self.master, bg='white')
self.mainframe.pack(fill = tkinter.BOTH, expand=True)
self.build_grid()
self.build_banner()
def build_grid(self):
self.mainframe.columnconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
self.mainframe.rowconfigure(0, weight=1)
self.mainframe.rowconfigure(0, weight=0)
def build_banner(self):
banner = tkinter.Label(
self.mainframe,
bg='black',
text='TIMER',
fg='white',
font=('Ravie Regular', 30)
)
banner.grid(
row=0, column=0,
stick='ew',
padx=10, pady=10
)
if __name__ == "__main__":
root = tkinter.Tk()
ss = study_timer(root)
root.mainloop()

Related

Unable to resize button height in tkinter python

import tkinter
from tkinter import *
root = Tk()
root.title("Demo")
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid(sticky="ewns")
self.feet = StringVar()
self.meters = StringVar()
self.create_widgets()
def calculate(self):
try:
self.meters.set(int(0.3048 * 10000.0 + 0.5)/10000.0)
except ValueError:
pass
def create_widgets(self):
self.master.resizable(width=TRUE, height=TRUE)
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
b1=Button(self, text="7", command=self.calculate,bg="lime")
b1.grid(column=1, row=4, columnspan=1, rowspan=1, padx=0, pady=0, ipadx=0, ipady=0, sticky='we')
''' configuring adjustability of column'''
self.columnconfigure(1, minsize=10, pad=0,weight=1)
''' configuring adjustability of rows'''
self.rowconfigure(4, minsize=10, pad=0,weight=1)
app = Application(master=root)
app.mainloop()on(master=root)
app.mainloop()
Here's the output
before resizing [the same what appears after compiling]
after resizing
As you can see, I am able to resize the width but not the height. Why so???
You have to use sticky='news' to make it sticky to all sides - top (north), right (east), left (west), botton (south).
Almost the same code with few comments
import tkinter as tk # popular method to make it shorter
#from tkinter import * # PEP8: `import *` is not preferred
# --- classes ---
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid(sticky="ewns")
self.feet = tk.StringVar()
self.meters = tk.StringVar()
self.create_widgets()
def calculate(self):
try:
self.meters.set(int(0.3048 * 10000.0 + 0.5)/10000.0)
except ValueError:
print("value error") # it is good to see problems
def create_widgets(self):
self.master.resizable(width=True, height=True)
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
b1 = tk.Button(self, text="7", command=self.calculate, bg="lime")
b1.grid(column=1, row=4, columnspan=1, rowspan=1, padx=0, pady=0, ipadx=0, ipady=0, sticky='news') # <-- `news`
# configuring adjustability of column
self.columnconfigure(1, minsize=10, pad=0,weight=1)
# configuring adjustability of rows
self.rowconfigure(4, minsize=10, pad=0,weight=1)
# --- main ---
root = tk.Tk()
root.title("Demo")
app = Application(root)
app.mainloop()
PEP 8 -- Style Guide for Python Code

Trouble adding new elements inside a new window executed through a button

I made a button inside a class and that calls a define function which creates a new window, but whenever I try to put something inside the window like a Label, nothing appears. What is it am I doing wrong? What am I supposed to call when creating the Label because it seems like I'm not calling the right thing
from tkinter import *
class mainTitle(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
myTitle = Label(self, text="Arithmetic & Geometric Sequence", font=("bold", 15))
myTitle.grid(row=1, column=1, pady=50)
opLabel = Label(self, text="Chooose either Arithmetic & Geometric series to calculate")
opLabel.grid(row=2, column=1, pady=10)
self.ariButton = Button(self, text="Arithmetic Sequence", command=self.ariClick)
self.ariButton.grid(row=3, column=1)
self.geoButton = Button(self, text="Geometric Sequence", command=self.geoClick)
self.geoButton.grid(row=4, column=1, pady=10)
self.grid_rowconfigure(0, weight=1)
self.grid_rowconfigure(5, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(2, weight=1)
def ariClick(Frame):
ariWindow = Toplevel()
ariWindow.geometry("300x300")
ariWindow.title("Arithmetic Sequence")
aLbl = Label(Frame, text="a")
aLbl.place(anchor=CENTER) #This is not appearing in the new window
def geoClick(Frame):
geoWindow = Toplevel()
geoWindow.geometry("300x300")
geoWindow.title("Geometric Sequence")
def qProgram(Frame):
root.destroy()
if __name__ == "__main__":
root = Tk()
root.geometry("450x350")
mainTitle(root).grid(sticky="nsew")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
this should work
class mainTitle(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
myTitle = Label(self, text="Arithmetic & Geometric Sequence", font=("bold", 15))
myTitle.grid(row=1, column=1, pady=50)
opLabel = Label(self, text="Chooose either Arithmetic & Geometric series to calculate")
opLabel.grid(row=2, column=1, pady=10)
self.ariButton = Button(self, text="Arithmetic Sequence", command=self.ariClick)
self.ariButton.grid(row=3, column=1)
self.geoButton = Button(self, text="Geometric Sequence", command=self.geoClick)
self.geoButton.grid(row=4, column=1, pady=10)
self.grid_rowconfigure(0, weight=1)
self.grid_rowconfigure(5, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(2, weight=1)
def ariClick(Frame):
ariWindow = Toplevel()
ariWindow.geometry("300x300")
ariWindow.title("Arithmetic Sequence")
#i called as parent the toplevel() instance ariwindow
aLbl = Label(ariWindow, text="aqwertyui")
aLbl.place(anchor=CENTER) # This is not appearing in the new window
def geoClick(Frame):
geoWindow = Toplevel()
geoWindow.geometry("300x300")
geoWindow.title("Geometric Sequence")
def qProgram(Frame):
root.destroy()
if __name__ == "__main__":
root = Tk()
root.geometry("450x350")
mainTitle(root).grid(sticky="nsew")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
vote the answer if it runs.

Resizing Canvas with Scrollbar dynamically by using the layout_manager grid

I built a canvas and I don't know why, I wont make it to resize with the frame.
Either something obvious is missing and by craftig all the stuff inside I lost my mind or something weird happens and I dont get it. Anyway here is my code, hope it can be clearify.
import tkinter as tk
root = tk.Tk()
class my_figure(tk.Frame):
def __init__(self, master,
width=450,height=590):
tk.Frame.__init__(self, master)
self.master = master
self.width=width
self.bind("<Configure>", self.update)
#DownFrame
self.body = tk.Frame(self, width=width,height=height,relief='sunken',bd=2)
self.vscrbar = tk.Scrollbar(self.body)
self.hscrbar = tk.Scrollbar(self.body,orient=tk.HORIZONTAL)
self.Display = tk.Canvas(self.body, width=width,height=height,
background='#f0f0f0',highlightthickness=0,
yscrollcommand=self.vscrbar.set,
xscrollcommand=self.hscrbar.set)
self.vscrbar.config(command=self.Display.yview)
self.hscrbar.config(command=self.Display.xview)
self.body.grid(column=0,row=1, sticky='nswe')
self.vscrbar.grid(column=1,sticky='ns')
self.hscrbar.grid(row=1,sticky='we')
self.Display.grid(column=0,row=0,
sticky='nswe')
self.grid_rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
def update(self, event):
print(event.widget.winfo_width())
## self.Header.config(width=event.width)
## self.Button.config(width=event.width)
## self.body.config(width=event.width)
## self.Display.config(width=event.width)
figure = my_figure(root)
figure.grid(column=0, row=0)
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)
root.mainloop()
You used nested parent container.Your my_figure is a widget inherit from Frame.And there are also a Frame widget in your my_figure.You need to set columnconfigure and rowconfigure for both of them.
Also need to use sticky="nwes" for your figure.
Though it could work normally,pack manager would be the best choice.
Code:
import tkinter as tk
root = tk.Tk()
class my_figure(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.master = master
# self["bd"] = 10
self.bind("<Configure>", self.update)
# DownFrame
self.body = tk.Frame(self, relief='sunken')
for i in range(self.body.grid_size()[1] + 1):
self.body.grid_rowconfigure(i, weight=1)
for i in range(self.body.grid_size()[0] + 1):
self.body.grid_columnconfigure(i, weight=1)
for i in range(self.grid_size()[1] + 1):
self.grid_rowconfigure(i, weight=1)
for i in range(self.grid_size()[0] + 1):
self.grid_columnconfigure(i, weight=1)
self.vscrbar = tk.Scrollbar(self.body)
self.hscrbar = tk.Scrollbar(self.body, orient=tk.HORIZONTAL)
self.Display = tk.Canvas(self.body,
background='#f0f0f0', highlightthickness=0,
yscrollcommand=self.vscrbar.set,
xscrollcommand=self.hscrbar.set)
self.vscrbar.config(command=self.Display.yview)
self.hscrbar.config(command=self.Display.xview)
self.body.grid(column=0, row=0, sticky='nswe')
self.vscrbar.grid(row=0, column=1, sticky='ns')
self.hscrbar.grid(row=1, column=0, sticky='we')
self.Display.grid(column=0, row=0,
sticky='nswe')
def update(self, event):
print(event.widget.winfo_width())
## self.Header.config(width=event.width)
## self.Button.config(width=event.width)
## self.body.config(width=event.width)
## self.Display.config(width=event.width)
figure = my_figure(root)
figure.grid(column=0, row=0, sticky="nwes")
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)
root.mainloop()

Passing values between classes for Tkinter

I'm working on a small GUI to query information from our CMDB to display for users. The trouble I am having is after an event in one class occurs(button), I want to update a combobox in another class. I thought I should use tk.StringVar() to pass the list, but the combobox only shows a 'PC_VAR#' value and doesn't update. Could anyone offer any assistance please?
#!/usr/bin/python
import Tkinter as tk
import ttk
import signal
class LoginUI:
def __init__(self, frame):
self.frame = frame
# Set default list entry
self.dc_list = tk.StringVar()
self.dc_list.set(['Login first'])
# Add a button to log in
self.button = tk.Button(self.frame, text='Login', command=self.change_combobox)
self.button.grid(column=0, row=0, pady=5)
def change_combobox(self):
# Change combobox values
dc_list = ['Site_1', 'Site_2', 'Site_3']
self.dc_list.set(dc_list)
class QueryUI:
def __init__(self, frame, dc_list):
self.frame = frame
self.dc = tk.StringVar()
self.dc_list = tk.StringVar()
self.dc_list.set(dc_list)
# Create site combobox
tk.Label(self.frame, text='Site:').grid(column=0, row=0, sticky="w")
self.dc_combobox = ttk.Combobox(
self.frame,
textvariable=self.dc,
width=20,
state='readonly'
)
self.dc_combobox['values'] = self.dc_list.get()
self.dc_combobox.grid(column=1, row=0, sticky="w")
class App:
def __init__(self, root):
self.root = root
self.root.title('Logging Handler')
self.root.columnconfigure(0, weight=1)
self.root.rowconfigure(0, weight=1)
# Create the left frame panels
left_frame = tk.Frame(self.root, padx=5, pady=5)
login_frame = tk.LabelFrame(left_frame, text="Login", borderwidth=2, relief="groove", padx=5, pady=5)
query_frame = tk.LabelFrame(left_frame, text="Query", borderwidth=2, relief="groove", padx=5, pady=5)
# Align frames
left_frame.grid(row=0, column=0, sticky="nw")
login_frame.grid(row=0, column=0, pady=5, sticky="nw")
query_frame.grid(row=1, column=0, pady=5, sticky="nw")
# Initialize all frames
self.login = LoginUI(login_frame)
self.query = QueryUI(query_frame, self.login.dc_list)
self.root.protocol('WM_DELETE_WINDOW', self.quit)
self.root.bind('<Control-q>', self.quit)
signal.signal(signal.SIGINT, self.quit)
def quit(self, *args):
self.root.destroy()
def main():
root = tk.Tk()
app = App(root)
app.root.mainloop()
if __name__ == '__main__':
main()
What I would do here is pass the controlling class (app) to the class needed to update the combobox. This way we can interact with it later if need be. By passing self of App to LoginUI we can then interact with the class attributes and methods of App from within LoginUI. This makes it a simple matter to update the combobox.
That said you really don't Need all the StringVars. Just past the list as a list and you will be good to go.
import Tkinter as tk
import ttk
import signal
class LoginUI:
def __init__(self, controller, frame):
self.controller = controller
self.frame = frame
self.dc_list = ['Login first']
self.button = tk.Button(self.frame, text='Login', command=self.change_combobox)
self.button.grid(column=0, row=0, pady=5)
def change_combobox(self):
self.controller.query.dc_combobox['values'] = ['Site_1', 'Site_2', 'Site_3']
self.controller.query.dc.set('Site_1')
class QueryUI:
def __init__(self, frame, dc_list):
self.frame = frame
self.dc = tk.StringVar()
tk.Label(self.frame, text='Site:').grid(column=0, row=0, sticky="w")
self.dc_combobox = ttk.Combobox(self.frame, textvariable=self.dc, width=20, state='readonly')
self.dc_combobox['values'] = dc_list
self.dc_combobox.grid(column=1, row=0, sticky="w")
class App:
def __init__(self, root):
self.root = root
self.root.title('Logging Handler')
self.root.columnconfigure(0, weight=1)
self.root.rowconfigure(0, weight=1)
left_frame = tk.Frame(self.root, padx=5, pady=5)
login_frame = tk.LabelFrame(left_frame, text="Login", borderwidth=2, relief="groove", padx=5, pady=5)
query_frame = tk.LabelFrame(left_frame, text="Query", borderwidth=2, relief="groove", padx=5, pady=5)
left_frame.grid(row=0, column=0, sticky="nw")
login_frame.grid(row=0, column=0, pady=5, sticky="nw")
query_frame.grid(row=1, column=0, pady=5, sticky="nw")
self.login = LoginUI(self, login_frame)
self.query = QueryUI(query_frame, self.login.dc_list)
self.root.protocol('WM_DELETE_WINDOW', self.quit)
self.root.bind('<Control-q>', self.quit)
signal.signal(signal.SIGINT, self.quit)
def quit(self, *args):
self.root.destroy()
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
app.root.mainloop()

How to add a xscrollbar to Text widget in tkinter

According to this source: both x and y scrollbars can be added to the Text() widget of tkinter. The codes which work in procedural method are:
from tkinter import *
root = Tk()
frame = Frame(master, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)
text = Text(frame, wrap=NONE, bd=0,
xscrollcommand=xscrollbar.set,
yscrollcommand=yscrollbar.set)
text.grid(row=0, column=0, sticky=N+S+E+W)
xscrollbar.config(command=text.xview)
yscrollbar.config(command=text.yview)
frame.pack()
root.mainloop()
However, i choose the class method and wrote the below codes, according to the below codes y scrollbar works but x scrollbar doesn't work. Why doesn't x scrollbar work in this example?
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.x_scrollbar = tk.Scrollbar(master=self, orient="horizontal")
self.x_scrollbar.grid(row=1, column=0, sticky="w, e")
self.y_scrollbar = tk.Scrollbar(master=self)
self.y_scrollbar.grid(row=0, column=1, sticky="n, s")
self.text = tk.Text(master=self, width=100, height=25, bg="black", fg="white", wrap=None)
self.text.grid(row=0, column=0, sticky="n, s, e, w")
self.configure_widgets()
self.pack()
def configure_widgets(self):
self.text.configure(xscrollcommand=self.x_scrollbar.set, yscrollcommand=self.y_scrollbar.set)
self.x_scrollbar.config(command=self.text.xview)
self.y_scrollbar.config(command=self.text.yview)
if __name__ == "__main__":
root = tk.Tk()
app = App(master=root)
app.mainloop()
The problem here is not the scrollbar code but the assignment of None in wrap config of your textbox.
Change
wrap=None
To
wrap='none'
on an unrelated note
change sticky="n, s, e, w" to sticky="nsew" the commas mean nothing in a quote here. And your other stickys should be "we" and "ns"
You might have been trying to do the tkinter CONSTANTS version of the stick. That would look like this: sticky=(N, S, E, W). However because you did not import * this will not work. You could import each constant from tkinter individually but in this case its best to use sticky="nsew" instead.
Just for reference here is a list of the 'nsew' constants you get when you import * from tkinter
N='n'
S='s'
W='w'
E='e'
NW='nw'
SW='sw'
NE='ne'
SE='se'
NS='ns'
EW='ew'
NSEW='nsew'

Categories