#declare gui object and classes
app = Tk() #creates instance of Tk()
app.title('Check sort DCA') # sets title of gui
#---------------------------------------
def keepSuggested(): #button press actions
es.JournalOut('test2')
def UseNew():
es.JournalOut('test1')
#------------------------------
frame=Frame(app,width=500,height=500)
frame.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=500,height=500,scrollregion=(0,0,500,500))
hbar=Scrollbar(frame,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=500,height=500)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(expand=True,fill=BOTH)
spacer1 = Label(canvas, text='|')
spacer2 = Label(canvas, text='|')
spacer3 = Label(canvas, text='|')
spacer4 = Label(canvas, text='|')
spacer5 = Label(canvas, text='|')
Chan_Num = Label(canvas,text='Channel Number')
Chan_Name = Label(canvas, text='Channel Name')
NewChan_Num = Label(canvas, text='New Channel Number')
Set_Title = Label(canvas, text='Set New')
std_Num=Label(canvas, text='Standard Channel Number')
std_Name = Label(canvas, text='Standard Channel Name')
Chan_Num.grid(row=0, column=0)
spacer1.grid(row=0, column=1)
Chan_Name.grid(row=0, column=2)
spacer2.grid(row=0, column=3)
NewChan_Num.grid(row=0, column=4)
spacer3.grid(row=0, column=5)
Set_Title.grid(row=0, column=6)
spacer4.grid(row=0,column=7)
std_Num.grid(row=0,column=8)
spacer5.grid(row=0,column=9)
std_Name.grid(row=0,column=10)
n=0
i = 0 # loops through all channel numbers to get print table value.
while i < nchan: # prints out all present channels with index and channel number and title #populates tables
ch_name = tsin.GetChanTitle(i)
ch_num = tsin.GetChanNumber(i)
ch_name_list = Label(canvas, text=ch_name )
ch_num_list = Label(canvas, text=str(ch_num))
ch_name_list.grid(row=i + 1, column=2)
ch_num_list.grid(row=i + 1, column=0)
UserInput=StringVar()
EntryBox= Entry(canvas, textvariable = UserInput)
EntryBox.grid(row=i+1,column=4 )
i = i + 1
j=0
while j< len(CorrectChannels):
stdList= CorrectChannels[j]
stdListNum = j
std_ch_num= Label(canvas,text=stdListNum+1)
std_ch_name = Label(canvas,text=stdList)
std_ch_name.grid(row=j+1, column=10)
std_ch_num.grid(row=j+1, column=8)
j=j+1
#build gui elements
Buttonnew = Button(canvas, text='Set Channels', bg='blue', fg='white',command=UseNew)
Buttonnew.grid(row=1, column=6)
Buttonkeep = Button(canvas, text='keep channels', bg='blue', fg='white', command=keepSuggested)
Buttonkeep.grid(row=2, column=6)
app.mainloop()
When I run my tkinter code python code I get a scroll bar with no scroll ability, all of my widgets are in canvas and display properly however scroll is needed to scroll down to see them all, this code is producing a scroll bar however it isn't working.
Your scrollbar works fine. However, you've defined the scrollregion exactly the same as the size of the canvas. Therefore there is nothing to scroll to. Try
canvas=Canvas(frame,bg='#FFFFFF',width=500,height=500,scrollregion=(0,0,500,800))
And you will see that you can scroll down 300 pixels.
Full working example code:
app = Tk()
frame=Frame(app,width=500,height=500)
frame.grid(row=0,column=0)
canvas=Canvas(frame,bg='#FFFFFF',width=500,height=500,scrollregion=(0,0,500,800))
vbar=Scrollbar(frame,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(yscrollcommand=vbar.set)
canvas.pack()
canvas.create_rectangle((200,300,300,600))
app.mainloop()
From your comment, I get the impression that you are using grid to place widgets on your Canvas. You should not do that, a Canvas is not a Frame in which you can grid widgets. You can create shapes on a Canvas or create a window that contains widgets. If you are trying to make a grid of widgets scrollable, you should place the Frame on the Canvas, not the other way around. See this answer for a great example of making a grid of widgets scrollable.
Related
I'm doing the Angela Yu 100 days of code python course and im having trouble with the grid layout in tkinter package. I don't understand why my Entry objects aren't directly under each other. I used the same padding and size values as in the course and i tried to change them to look better but the password entry and the add button are more on the left then other entries while they have the same column number in the grid function. Thank u for ur help ^^
Here is the code i used for interface:
window = Tk()
window.title("Password Manager")
window.config(padx=50, pady=50)
logo = PhotoImage(file="logo.png")
image = Canvas(width=200, height=200, highlightthicknes=0)
image.create_image(100, 100, image=logo)
image.grid(column=1, row=0)
website = Label(text="Website:")
website.grid(column=0, row=1)
email = Label(text="Email/Username:")
email.grid(column=0, row=2)
password = Label(text="Password:")
password.grid(column=0, row=3)
website_blank = Entry(width=36)
website_blank.grid(column=1, row=1, columnspan=2)
website_blank.focus()
email_blank = Entry(width=36)
email_blank.grid(column=1, row=2, columnspan=2)
email_blank.insert(0, "aleksander.jaloszynski#gmail.com")
password_blank = Entry(width=21)
password_blank.grid(column=1, row=3)
generate_password = Button(text="Generate Password")
generate_password.grid(column=2, row=3)
add = Button(text="Add", width=36, command=save)
add.grid(column=1, row=4, columnspan=2)
window.mainloop()
And here is how it looks:
enter image description here
import tkinter as tk
from tkinter import *
HEIGHT = 600
WIDTH = 600
root = tk.Tk()
def button_event1():
import ThreePlayers
print(ThreePlayers)
def button_event2():
import TwoPlayersGame
print(TwoPlayersGame)
def button_event3():
print("")
def button_event4():
print("")
def button_event5():
quit()
root = Tk()
root.title('Connect 4 Game')
canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH)
canvas.pack()
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.config(anchor=CENTER)
L.pack()
button = tk.Button(root, text="3 Player Game", command=button_event1)
button.pack()
button = tk.Button(root, text="2 Player Game", command=button_event2)
button.pack()
button = tk.Button(root, text="1 Player Game", command=button_event3)
button.pack()
button = tk.Button(root, text="Options", command=button_event4)
button.pack()
button = tk.Button(root, text="QUIT", command=button_event5)
button.pack()
root.mainloop()
Above is my Code for a Tkinter GUI but I want the have the label at the center of the root/window how do I do that? Currently its sitting on top of the buttons everything else is fine the button events and such works
In my opinion, you should have used place or grid instead of pack. Because pack only gives few alignment options.
otherwise, maybe divide the main window into two frames then pack the label at the top of the lower frame
frame = Frame(root)
frame.pack()
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
L.pack(side = TOP)
I wish this helps. but you should use grid for better alignment or place.
You can use the following commands to place the label in the center
L = Label(root, text="Welcome to 3P Connect 4!!!",font=("Ariel",20,"bold", "underline"))
# L.config(anchor=CENTER)
# L.pack()
L.place(x=HEIGHT/2, y=WIDTH/2, anchor="center")
Similarly, you can also use button.place(x=100, y=25) for buttons
REF: Tkinter: Center label in frame of fixed size?
I'm working on Tkinter window, and I want to set up the height and width of the screen without the geometry function, so I made 2 scales vertical and horizontal, then I use a button with a command that set up the window size in the following code:
root = Tk()
root.title("Root window")
label = Label(root, text="The height").pack()
slay = Scale(root, from_=0, to=200)
slay.pack()
my_label = Label(root, text="The width").pack()
hor = Scale(root, from_=0, to=250, orient=HORIZONTAL)
hor.pack()
def btns():
root.geometry(str(f"{slay.get} x {hor.get}"))
btn = Button(root, text="Setup the window size", command=btns).pack()
And the error is:
line 20, in btns
root.geometry(str(f"{slay.get} x {hor.get}"))
You are just referencing the .get() function, never actually calling them. So you will receive an error.
Call the function using (). Also, there is no space between str(f"{slay.get()} x {hor.get()}").
So it would look something like this:
root.geometry(str(f"{slay.get()}x{hor.get()}"))
This works.
The problem was root.geometry(str(f"{vert.get} x {hori.get}"))
I changed it to this root.geometry(str(f"{vert.get()}x{hori.get()}"))
Simply removed the spaces around 'x' and added () to the get
Also added orient = VERTICAL to slay
root = Tk()
root.title("Root window")
label = Label(root, text="The height").pack()
slay = Scale(root, from_=0, to=200, orient=VERTICAL)
slay.pack()
my_label = Label(root, text="The width").pack()
hor = Scale(root, from_=0, to=250, orient=HORIZONTAL)
hor.pack()
def btns():
print( slay.get(), hor.get() )
root.geometry(str(f"{slay.get()}x{hor.get()}"))
btn = Button(root, text="Setup the window size", command=btns).pack()
root.mainloop()
so i was trying to make a python calculator, that opens like a window, but before the calculations i was trying to make it display the numbers that i clicked, everything was normal, the append, the list, everything was normal until it had to display the actual numbers, where it displays nothing, i tried to make change the label to "hi" for example to see if the problem is with the list, but nothing is being displayed, can someone help me get numbers to be displayed in the "results" area? here is my code:
root = tk.Tk()
color = '#263D42'
numbers = []
Background = tk.Canvas(root, height=600, width=601, bg=color)
Background.pack()
resultBack = tk.Canvas(root, height=150, width=400, bg="#E4E0E0")
resultBack.place(x=50, y=1)
root.title('Calculator')
root.iconphoto(False, tk.PhotoImage(file='plus.ico'))
root.resizable(width = False, height = False)
root.geometry("500x600")
for number in numbers:
label = tk.Label(root, text="hi", bg="black")
label.pack()
frame = tk.Frame(root, bg="white")
frame.place(relwidth=0.8, relheight=0.8, relx=0.1, rely=0.1) #frame
def addOne():
for widget in frame.winfo_children():
widget.destroy()
numbers.append('1')
for number in numbers:
print(number)
label = tk.Label(root, text=number, bg="black")
label.pack()
print(numbers)
one = tk.Button(root, text="1", padx=10, pady=5, fg="#000000", bg="#ffffff", command=addOne)
one.place(x=30, y=30)
root.mainloop()
You should not be creating and deleting your labels like that; you can just change them.
Maybe try something like this:
import tkinter as tk
root = tk.Tk()
numbers = []
root.title('Calculator')
root.resizable(width = False, height = False)
root.geometry("500x600")
label_text = tk.StringVar()
label_text.set('hi')
label = tk.Label(root, textvariable=label_text)
label.pack()
frame = tk.Frame(root, bg="white")
frame.place(relwidth=0.8, relheight=0.8, relx=0.1, rely=0.1) #frame
def addOne():
numbers.append(1)
work = ""
for i in numbers:
work+=str(i)
label_text.set(work)
one = tk.Button(root,
text="1",
padx=10,
pady=5,
fg="#000000",
bg="#ffffff",
command=addOne)
one.place(x=30, y=30)
root.mainloop()
That should get the numbers showing up. StringVars are your friend for these sorts of things. As you update them, tk automatically updates the widget they are attached to.
From here, you will probably want to move things around to look better etc. and you probably don't want to have to add a method for each button (addTwo, addThree, addFour etc.) Let us know if you need more help.
I'm creating a very simple UI using Tkinter and python, but I'm having trouble sizing GUI elements and using the grid format to place them correctly. Here's a first-order approximation of what I'm trying to have:
Here's the code I have so far. I keep getting close, but I don't think I really understand what I'm doing. Any help is much appreciated!
#User interface
root = Tk()
window_width = root.winfo_screenwidth()
window_height = root.winfo_screenheight()
root.geometry ("%dx%d"%(window_width,window_height))
menu_bar = Menu(root)
menu = Menu(menu_bar, tearoff=0)
menu.add_command(label="Open", command = open_file)
menu.add_command(label="Save", command = save)
menu.add_separator()
menu.add_command(label="Quit", command = exit)
menu_bar.add_cascade(label="File",menu=menu)
root.config(menu=menu_bar)
#textbox is the window in which the code is written
textbox = Text(root, width=50, height = window_height/20+4)
#canvas is where the car will go
canvas_frame= Frame(root, width = window_width/1.5, height = window_height-200)
canvas_frame.configure(borderwidth=1.5,background='black')
canvas = Canvas(canvas_frame, width = window_width/1.5, height = window_height-200)
#console to print to
console = Text(root, width = int(window_width/1.5), height = 10)
run_button = Button(root, text = "Run", command = lambda:generate_program(textbox.get(1.0,END)))
clear_button = Button(root, text = "Clear text", command = clear)
#add them to frame
textbox.grid(row=0, column=0, rowspan=20, columnspan=10)
run_button.grid(row=21,column=0)
clear_button.grid(row=21,column=1)
canvas_frame.grid(row=0,rowspan=10,column=21,columnspan=25)
canvas.grid(row=0, rowspan=1, column=21, columnspan=25)
console.grid(row = 1, rowspan=1, column = 21, columnspan=25)
root.mainloop()
In my opinion, this is layout can be much easier with the pack geometry manager. One of the problems is that you are trying to make the width and the height of each widget fit in its place with rowspan and columspan options. Also, since canvasis inside a frame, you have to think that it is like inside a new window, so a simple call to canvas.grid() would be enough.
However, with pack() you just have to put textbox, run_button and clear_button inside a new frame:
left_frame = Frame(root)
textbox = Text(left_frame, ...)
run_button = Button(left_frame, ...)
clear_button = Button(left_frame, ...)
canvas_frame= Frame(root, ...)
canvas_frame.configure(borderwidth=1.5,background='black')
canvas = Canvas(canvas_frame, ...)
console = Text(root, ...)
left_frame.pack(side=LEFT)
textbox.pack()
run_button.pack(side=LEFT)
clear_button.pack()
canvas_frame.pack()
canvas.pack()
console.pack()