Python Tkinter Tabs and Canvas - python

Objective:
I am trying to create a GUI with a portion of the screen having "tabs" (information displayed can be changed based on selected tab), and another portion constantly displaying the same thing.
import ttk
import Tkinter
def demo():
#root = tk.Tk()
schedGraphics = Tkinter
root = schedGraphics.Tk()
root.title("Testing Bot")
universal_height = 606
canvas = schedGraphics.Canvas(root,width = 900, height = universal_height)
nb = ttk.Notebook(root)
# adding Frames as pages for the ttk.Notebook
# first page, which would get widgets gridded into it
page1 = ttk.Frame(nb,width = 300,height = universal_height)
# second page
page2 = ttk.Frame(nb,width = 300,height = universal_height)
nb.add(page1, text='One')
nb.add(page2, text='Two')
#
nb.grid()
day_label = schedGraphics.Label(page1, text="Day1:")
day_label.pack()
day_label.place(x=0, y=30)
day_label = schedGraphics.Label(page2, text="Day2:")
day_label.pack()
day_label.place(x=0, y=30)
canvas.create_rectangle(50,500,300,600,fill = "red")
canvas.grid()
root.mainloop()
if __name__ == "__main__":
demo()
Problems:
In the current configuration the tabs are located in the MIDDLE of the screen not on the left side.
If I change canvas.grid() to canvas.pack() it doesn't actually open any window?
The rectangle on canvas does not appear!
Thank you.

To do this, when gridding your notebook, pass the argument column and choose 0, so that it will be located at the far left, like this:
nb.grid(column=0)
That's because you have to chose, for your tkinter app, between .grid() and .pack(): the two are not compatible. As you used .grid() before, the window won't open and a TclError pops up.
Your canvas is in fact hidden under the notebook. To fix that, set the row argument when using grid to 0, so that it is at the top, like this:
canvas.grid(column=1, row=0)
Final code:
import Tkinter
import ttk
def demo():
#root = tk.Tk()
schedGraphics = Tkinter
root = schedGraphics.Tk()
root.title("Testing Bot")
universal_height = 606
nb = ttk.Notebook(root)
# adding Frames as pages for the ttk.Notebook
# first page, which would get widgets gridded into it
page1 = ttk.Frame(nb, width= 300,height = universal_height)
# second page
page2 = ttk.Frame(nb,width = 300,height = universal_height)
nb.add(page1, text='One')
nb.add(page2, text='Two')
nb.grid(column=0)
day_label = schedGraphics.Label(page1, text="Day1:")
day_label.pack()
day_label.place(x=0, y=30)
day_label = schedGraphics.Label(page2, text="Day2:")
day_label.pack()
day_label.place(x=0, y=30)
canvas = schedGraphics.Canvas(root, width=900, height=universal_height)
canvas.create_rectangle(50, 500, 300, 600, fill="red")
canvas.grid(column=1, row=0)
root.mainloop()
if __name__ == "__main__":
demo()
I hope this helps !

Related

Tkinter login page layout problem - Python

I'm trying to create a login page in Tkinter with .pack(). I wold like to place the loginFrame at the center of the small window. And inside the loginFrame, the username section on top of the password section.
def main():
window = tk.Tk()
window.geometry("400x200")
window.title("PySploit")
window.resizable(False, False)
window.configure(background="#E1E5F2")
loginFrame = tk.Frame(window).pack(anchor="center")
usernameFrame = tk.Frame(loginFrame).pack(side=LEFT)
passwordFrame = tk.Frame(loginFrame).pack(side=LEFT)
tk.Label(usernameFrame, text="Username").pack(side=LEFT)
tk.Entry(usernameFrame, name="username").pack(side=LEFT)
tk.Label(passwordFrame, text="Password").pack(side=LEFT)
tk.Entry(passwordFrame, name="password").pack(side=LEFT)
window.mainloop()
return
if __name__ == "__main__":
main()
This is my wrong output:
For your requirement, you don't need usernameFrame and passwordFrame, just loginFrame is enough.
You can put loginFrame at the center of the window using place() instead and put those labels and buttons inside loginFrame using grid():
import tkinter as tk
def main():
window = tk.Tk()
window.geometry("400x200")
window.title("PySploit")
window.resizable(False, False)
window.configure(background="#E1E5F2")
loginFrame = tk.Frame(window)
# place loginFrame at the center of window
loginFrame.place(relx=0.5, rely=0.5, anchor='c')
# use grid() instead of pack() to lay out labels and entries
tk.Label(loginFrame, text="Username").grid(row=0, column=0)
tk.Entry(loginFrame, name="username").grid(row=0, column=1)
tk.Label(loginFrame, text="Password").grid(row=1, column=0)
tk.Entry(loginFrame, name="password").grid(row=1, column=1)
window.mainloop()
if __name__ == "__main__":
main()

Create scrollbar in tKinter without displacing widgets to the left (python)

I'm creating a program by learning from youtube tutorials (I'm a complete beginner) and I have come to some difficulties. This time, I'm trying to create a scrollbar, and I want my widgets to stay on the center of my window, not the left (I'm following the Codemy.com tutorial on scrollbars).
Here is the current aspect of my program:
with scrollbar
And here is how I want it to look:
without scrollbar
This is my code right now:
import tkinter as tk
root = tk.Tk()
root.geometry("600x400")
my_canvas = tk.Canvas(root)
my_canvas.pack(side = "left", fill = "both", expand = 1)
my_scrollbar = tk.Scrollbar(root, orient = "vertical", command = my_canvas.yview)
my_scrollbar.pack(side = "right", fill = "y")
my_canvas.configure(yscrollcommand = my_scrollbar.set)
my_canvas.bind("<Configure>", lambda e: my_canvas.configure(scrollregion = my_canvas.bbox("all")))
my_frame = tk.Frame(my_canvas)
for i in range(100):
my_label = tk.Label(my_frame, text = "Label")
my_label.pack()
my_canvas.create_window((0,0), window = my_frame, anchor = "nw")
root.mainloop()
Include width = 600, anchor = "nw" in my_canvas declaration.
my_canvas.create_window((0,0), window = my_frame, width = 600, anchor = "nw")

Make tkinter window draw on top of fullscreen applications

I'm wondering if there is a way to draw tkinter windows over fullscreen applications, so far I have this:
from tkinter import *
#MAIN WINDOW
root = Tk()
root.title('Test Title')
root.geometry("500x200")
root.wm_attributes('-transparentcolor', root['bg'])
root.wm_attributes("-topmost", 1)
my_frame = Frame(root, width=500, height=200)
my_frame.pack(pady=20, ipady=20, ipadx=20)
#STAT TEXT
my_label = Label(my_frame, font=("Helvetica", 40), fg="#09d2f6")
my_label.config(text="TEST TEXT")
my_label.pack(pady=20)
root.mainloop()
This draws the window on top of all applications but not fullscreen ones. I had the idea to have a loop where it will constantly bring the window forward but have no idea how to do that.
This code will enable you to choose a picture to view on the fullscreen.
Your code will run in transparent mode above it - no problems
Press Escape key to exit
Try making your widget fullscreen using title button for weird effect!
Had to edit this due to the effect of filedialog on results.
Moved the attribute setting so that it is invoked after image is loaded.
import os
import tkinter as tk
from tkinter import filedialog
def closer( ev ):
ev.widget.destroy()
# FULL SCREEN
master = tk.Tk()
master.rowconfigure( 0, weight = 1 )
master.columnconfigure( 0, weight = 1 )
master.bind( "<Escape>", closer )
pathfile = filedialog.askopenfilename( title = 'pick mage' )
my_image = tk.PhotoImage( file = pathfile ).zoom( 2,2 )
label = tk.Label( master, text = 'Image', compound = "top", image = my_image )
label.grid(row=0, column=0,sticky='nsew')
master.wm_attributes("-fullscreen", 1)
# removed for first time use - unrem this for second time
# master.wm_attributes("-topmost", 1)
# Your code
root = tk.Toplevel(master)
root.title('Test Title')
root.geometry("500x200")
root.bind( "<Escape>", closer )
root.wm_attributes('-transparentcolor', root['bg'])
root.wm_attributes("-topmost", 1)
my_frame = tk.Frame(root, width=500, height=200)
my_frame.pack(pady=20, ipady=20, ipadx=20)
#STAT TEXT
my_label = tk.Label(my_frame, font=("Helvetica", 40), fg="#09d2f6")
my_label.config(text="TEST TEXT")
my_label.pack(pady=20)
master.mainloop()

Buttons getting misplaced after using background image in Tkinter

Whenever I run this code with a background Image the button grid gets misplaced and pushed towards the bottom. Fortunately, it works as intended when no background is added .I want them to cover the background when executed. Pictures for reference are added below. Your help is highly appreciated.
# importing the module
import tkinter.messagebox
from tkinter import *
import random
# importing the module
# initialising tkinter
class window(Frame):
def __init__(self,master = None):
Frame.__init__(self,master)
self.master = master
# initialising tkinter
# creating the window
root = Tk()
app = window(root)
root.geometry("630x630")
root.title('Odd Even Game')
C = Canvas(root, bg="blue", height=250, width=300)
filename = PhotoImage(file = "BG.png")
background_label = Label(root,image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
C.pack()
frame = Frame(root)
frame.pack()
# creating the window
# image
level_1e = "p1.png"
level_1o = "pe.png"
level_2e = "r1.png"
level_2o = "re.png"
# image
def create_cards(odd_image,even_image,next_level,fno,order,suc,err,w,h):
rx = random.randint(0,order-1)
ry = random.randint(0,order-1)
for i in range(0,order):
for j in range(0,order):
if i == rx and j == ry:
create_button(i,j,suc,odd_image,next_level,fno,odd_image,w,h)
else:
create_button(i,j,err,even_image,next_level,fno,odd_image,w,h)
def second_level(fno):
fno.pack_forget()
frame2 = Frame(root)
frame2.pack()
suc = "Congratulations! You have cleared level 2..Keep Going Buddy!"
err = "Wrong Answer..Don't give up yet!"
create_cards(level_2o,level_2e,final_level,frame2,4,suc,err,157.5,157.5)
def final_level(fno):
fno.pack_forget()
root.geometry("700x700")
ap = App(root)
# creating a button function
def create_button(x,y,msg,picture,next_level,fno,odd,w,h):
if picture == odd:
image = PhotoImage(file=picture)
click = Button(fno, image=image, width= w, height=h, bd = 0,command = lambda : [score_update(),next_level(fno),tkinter.messagebox.showinfo( "Odd One Out Project",msg)])
click.image = image
click.grid( row = x, column = y)
else:
image = PhotoImage(file=picture)
click = Button(fno, image=image, width= w, height=h, bd = 0,command = lambda : [next_level(fno),tkinter.messagebox.showinfo( "Odd One Out Project",msg)])
click.image = image
click.grid( row = x, column = y)
# creating a button function
def create_frame(fno):
root.geometry("630x630")
fno.pack_forget()
frame = Frame(root)
frame.pack()
suc = "Congratulations! You have cleared level 1..Time to increas[![enter image description here][1]][1]e the difficulty!"
err = "Wrong Answer..Please Try again !!"
create_cards(level_1o,level_1e,second_level,frame,3,suc,err,200,200)
def intro():
root.geometry("630x630")
frame0 = Frame(root)
frame0.pack()
click = Button(frame0,text="Start!" ,command = lambda [create_frame(frame0),tkinter.messagebox.showinfo( "Odd One Out Project","The game has begun!!")])
click.pack()
intro()
# starting the widget
root.mainloop()
# starting the widget
The first image is the error. Second Image is the required output.
Note: I'm still a beginner in Python and Tkinter hence various terms and methods might be something out of my scope. Would be appreciated if taken into consideration.
In case needed, you might know that this is a tkinter project for picking the odd one out image out of A*A grid.
I got the answer myself so will be sharing for future use.
C = Canvas(root, bg="blue", height=250, width=300)
This part draws a canvas of 250*300 dimensions hence does not let the buttons draw over it.
just change it to,
C = Canvas(root, bg="blue", height=0, width=0)
for the desired result

Adding an image to a button in Tkinter

I am trying to add an image to a button, but I have got some issues when I try to execute the current code. All it shows is an image with no words. I can't even see the button either. Is there some way of fixing my current code?
from tkinter import *
import tkinter as tk
root = tk.Tk()
root.geometry("960x600")
canvas = Canvas(root, width=500, height=500)
canvas.pack()
imagetest = PhotoImage(file="giftest.gif")
canvas.create_image(250, 250, image=imagetest)
button_qwer = Button(root, text="asdfasdf", image=imagetest)
root.mainloop()
You need to pack (or grid) your button in the window, here is how you could do:
import tkinter as tk
from tkinter import PhotoImage
def print_hello():
print('hello')
root = tk.Tk()
root.geometry("960x600")
imagetest = PhotoImage(file="giftest.gif")
button_qwer = tk.Button(root, text="asdfasdf", image=imagetest, command=print_hello)
button_qwer.pack() # <-- don't forget to place the button in the window
root.mainloop()
You can have both text and image displayed on your button, using the compound option, like this:
button_qwer = tk.Button(root, image=imagetest, text="asdfasdf", compound="top", command=print_hello)
compound options are bottom, center, left, none, right, or top
You are making the button successfully but you are not drawing it onto the screen/interface. Use pack , place or grid.
button_qwer = Button(root, text="asdfasdf", image=imagetest)
button_qwer.pack()
Your full code can be like:
from tkinter import *
import tkinter as tk
root = tk.Tk()
root.geometry("960x600")
canvas = Canvas(root, width=500, height=500)
canvas.pack()
imagetest = PhotoImage(file="giftest.gif")
canvas.create_image(250, 250, image=imagetest)
button_qwer = Button(root, text="asdfasdf", image=imagetest)
button_qwer.pack()
root.mainloop()

Categories

Resources