How do I place tkinter buttons in a specific area? - python-3.x

I am making a program for finding booking contacts with ease. When I type in all of this information, the buttons stay to the top left of the window.
How can I get them in the middle of the screen? Better, how would I place them where-ever I want in general? (Don't worry about the webbrowser import for that is for later in the program.)
import webbrowser
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('GUI Booking')
root.geometry('600x400')
root.resizable(width=False, height=False)
style = ttk.Style()
style.configure("TButton",
font="TkDefaultFont",
height=20,
width=20,
padding=10)
main_frame = Frame()
main_frame.grid(row=0, columnspan=4)
# Starting Window
button_location = ttk.Button(main_frame, text='Location').grid(row=1, column=3)
button_name = ttk.Button(main_frame, text='Name').grid(row=2, column=3)
button_email = ttk.Button(main_frame, text='Email').grid(row=3, column=3)
root.mainloop()

use the .place option instead of .grid:
...
Button = Button(something, text='Something', command=Something)
Button.place(x=value(e.g:2), y=value(e.g:2))
...

You could use row/column configure to center up the buttons: http://www.effbot.org/tkinterbook/grid.htm
I've added this under your root configuration. Ultimately, the position of widgets will depend on the widgets that you use and adjusting their position with the grid manager.
import webbrowser
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('GUI Booking')
root.geometry('600x400')
root.resizable(width=False, height=False)
root.grid_rowconfigure(0, weight=1) # Added to center buttons
root.grid_columnconfigure(0, weight=1) # Added to center buttons
style = ttk.Style()
style.configure("TButton",
font="TkDefaultFont",
height=20,
width=20,
padding=10)
main_frame = Frame()
# Starting Window
button_location = ttk.Button(main_frame, text='Location').grid(row=1, column=1)
button_name = ttk.Button(main_frame, text='Name').grid(row=2, column=1)
button_email = ttk.Button(main_frame, text='Email').grid(row=3, column=1)
main_frame.grid(row=0, column=0)
root.mainloop()

if you want them to me in the middle of the screen, use .pack instead of .grid.
import webbrowser
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('GUI Booking')
root.geometry('600x400')
root.resizable(width=False, height=False)
style = ttk.Style()
style.configure("TButton",
font="TkDefaultFont",
height=20,
width=20,
padding=10)
main_frame=Frame()
# Starting Window
button_location = ttk.Button(main_frame, text='Location').grid()
button_name = ttk.Button(main_frame, text='Name').grid()
button_email = ttk.Button(main_frame, text='Email').grid()
main_frame.pack()
root.mainloop()
warning: do not use .pack and .grid in the same window.

Related

Tkinter Toplevel window not appearing

Python 3.8, Win 10 is the os, Toplevel widget does not appear to be working with new window not appearing. Any guidance would be appreciated, thanks!
from tkinter import *
root = Tk()
def popup():
top = Toplevel(root)
my_label_top = Label(top, text="This is a Tkinter Popup")
top.mainloop()
my_button = Button(root, text="Popup, click here", command="popup")
my_button.grid(row=0, column=0)
root.mainloop()
Problem:
The only issue here is that the callback command shouldn't be a string.
Solution:
Remove the quotes around popup and the Toplevel window should appear.
Fixed Code:
from tkinter import *
root = Tk()
def popup():
top = Toplevel(root)
my_label_top = Label(top, text="This is a Tkinter Popup")
my_label_top.pack()
my_button = Button(root, text="Popup, click here", command=popup)
my_button.grid(row=0, column=0)
root.mainloop()
Tips:
Using top.mainloop() is not necessary.
You also forgot to pack() the Label(my_label_top)

Why do two windows appear when I connect styles?

enter image description hereI have a code like this:
from tkinter import Tk
import tkinter.ttk as ttk
"""Styles"""
style = ttk.Style()
style.configure('OrangeButton.TButton', foreground='white', background='#ff9203')
style.map('OrangeButton.TButton',
foreground=[('pressed', 'white'), ('active', 'white')],
background=[('pressed', '!disabled', '#adadad'), ('active', '#de8e26')])
root = Tk()
button = ttk.Button(root, text="Ok", width=20, style='OrangeButton.TButton')
button.pack(padx=50, pady=50)
root.mainloop()
I'm new at this. I searched the Internet for a solution, but could not find it. Everywhere they write about widthdraw(), but this does not help. Two windows always appear and the customized style is not applied to the button. What am I doing wrong? How do I search Google for this problem? Tell me please. Thanks.
You just need to define ttk.Style() inside the root window.
from tkinter import Tk
import tkinter.ttk as ttk
root = Tk()
"""Styles"""
style = ttk.Style()
# add the these_use option and use the 'clam' theme
style.theme_use('clam')
style.configure('OrangeButton.TButton', foreground='white', background='#ff9203')
style.map('OrangeButton.TButton',
foreground=[('pressed', 'white'), ('active', 'white')],
background=[('pressed', '!disabled', '#adadad'), ('active', '#de8e26')])
button = ttk.Button(root, text="Ok", width=20, style='OrangeButton.TButton')
button.pack(padx=50, pady=50)
root.mainloop()
Hope this solves the problem.

Scrollbar doesn't scroll widgets inside a frame which is inside a canvas

I have the canvas and the scrollbar are on the Tk.
I have a frame on the canvas.
I adding into this frame new frames with the widgets on it and I want to scroll these widgets.
The scrollbar doesn't scroll the widgets at all, and when I add widgets which go below the window than the scrollbar turn into gray and I can't use it at all.
I am new to tkinter and python. I just don't know yet what am I doing. I didn't try to make it with a class(Should I?). I tried to use the ttk, and looked around sites for a non class answers but none of them worked.
from tkinter import *
from tkinter.ttk import *
actor_number=0
global tk
def new_actor_button_command():
global menu_frame
global actor_number
global canvas
new_actor_frame=Frame(menu_frame,width=500,height=200)
new_actor_frame.grid(row=1+actor_number,column=0,pady=20)
actor_name_label=Label(new_actor_frame,text="Actor Name")
new_actor_frame.place(relx=0.0, rely=0.0, anchor=CENTER)
delete_actor_button=Button(new_actor_frame,text="Delete
Actor",command=delete_actor_button_command)
new_actor_frame.grid(row=1+actor_number,column=1)
actor_name_label.grid(row=2+actor_number,column=1)
delete_actor_button.grid(row=2+actor_number,column=2)
actor_number+=1
canvas.update_idletasks()
scrollbar.config(command=canvas.yview)
canvas.configure(scrollregion=canvas.bbox("all"))
def make_new_actor():
global canvas
global menu_frame
new_actor_button=Button(menu_frame,text="Add New
Actor",command=new_actor_button_command)
new_actor_button.grid(row=0,column=0)
def new_command():
global actor_number
actor_number=0
make_new_actor()
tk=Tk()
tk.geometry("1200x800")
menubar=Menu(tk)
filemenu=Menu(menubar,tearoff=0)
filemenu.config(font=("Verdana",16))
filemenu.add_command(label="New",font=("Verdana",16),command=new_command)
menubar.add_cascade(label="File", menu=filemenu)
global scrollbar
canvas=Canvas(tk,width=1000,height=1000)
scrollbar=Scrollbar(tk,orient="vertical",command = canvas.yview)
menu_frame=Frame(canvas,width=1000,height=1000)
canvas.create_window(0,0,window=menu_frame)
canvas.configure(yscrollcommand=scrollbar.set)
canvas.configure(scrollregion=canvas.bbox("all"))
canvas.place(relx=0.0, rely=0.0)
menu_frame.pack(side=LEFT,expand=True)
scrollbar.pack(side=RIGHT,fill=Y)
tk.config(menu=menubar)
tk.mainloop()
It should scroll the vidgets inside"menu_frame".
Scrolling Canvas is not easy.
It scroll items (if you add enough items in menu_frame) but it may need other changes in new_actor_frame
from tkinter import *
from tkinter.ttk import *
def new_actor_button_command():
new_actor_frame = Frame(menu_frame, width=500, height=200)
new_actor_frame.grid(row=actor_number, column=0)
actor_name_label = Label(new_actor_frame, text="Actor Name")
actor_name_label.grid(row=0, column=1)
delete_actor_button=Button(new_actor_frame,text="Delete Actor")#, command=delete_actor_button_command)
delete_actor_button.grid(row=0, column=2)
def new_command():
global actor_number
actor_number += 1
new_actor_button = Button(menu_frame, text="Add New Actor", command=new_actor_button_command)
new_actor_button.grid(row=actor_number, column=0)
def update_canvas(event=None):
canvas.configure(scrollregion=canvas.bbox("all"))
actor_number=0
tk = Tk()
tk.geometry("1200x800")
menubar = Menu(tk)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New", command=new_command)
menubar.add_cascade(label="File", menu=filemenu)
tk.config(menu=menubar)
canvas = Canvas(tk, background='white')#, width=1000, height=1000)
canvas.pack(side='left', fill='both', expand=True)
scrollbar = Scrollbar(tk, orient="vertical", command=canvas.yview)
scrollbar.pack(side='right', fill='y')
menu_frame = Frame(canvas)
canvas.create_window(0, 0, window=menu_frame, anchor='nw')
canvas.configure(yscrollcommand=scrollbar.set)
canvas.bind('<Configure>', update_canvas) # update when change size
tk.mainloop()

How do I overlay these buttons on top of an image for a background in Python Tkinter

Currently, I'm attempting to create a simple main menu for a game using Tkinter as a simple GUI since it's a simple RPG game and Python however the image overlays the buttons in all circumstances.
I've tried using some other solutions like placing them or creating a window but I can't find a straight answer of how to make that either.
import tkinter
from tkinter import *
from PIL import ImageTk, Image
(PIL is from when I was using a JPG before.)
root = Tk()
content = ttk.Frame(root)
root.geometry("600x600")
background = ImageTk.PhotoImage(Image.open("bred.png"))
canvas = tkinter.Canvas(root, width=580, height=600)
content.grid(column=0, row=0)
Btn1 = Button(content, text="Play", width=5, height=1)
Btn2 = Button(content, text="Kill me", width=7, height=1, command =
root.quit)
backgroundlabel = tkinter.Label(root, image=background)
backgroundlabel.image = background
backgroundlabel.place(x=0, y=0, relwidth=1, relheight=1)
Btn1.grid(row=1, column=2, padx=(130))
Btn1.columnconfigure(1, weight=1)
Btn1.rowconfigure(1, weight=1)
Btn2.grid(row=1, column=3, pady=(130))
Btn2.columnconfigure(3, weight=1)
Btn2.rowconfigure(1, weight=1)
root.mainloop()
Currently your background's master is set to root while your buttons are set to a frame. The first thing you need to do is set both to the same master, i.e. changing background master to content:
backgroundlabel = tk.Label(content, image=background)
Next you need to deal with the stacking order. You can call widget.lift() to raise the buttons to top:
Btn1.grid(row=1, column=2, padx=(130))
...
Btn1.lift()
Btn2.grid(row=1, column=3, pady=(130))
...
Btn2.lift()

Multiple line text entry box in python

In python i have been making a text editor like Microsoft word but i don't know how to make a text entry box for the user to put input. Here is my code! (ps thank you!)
from tkinter import *
import sys
def doNothing():
print("Test")
root = Tk()
root.title("TextEditor")
root.geometry("300x200")
menu = Menu(root)
root.config(menu=menu)
subMenu = Menu(menu)
menu.add_cascade(label="File", menu=subMenu)
subMenu.add_command(label="New Project...", command =doNothing)
subMenu.add_command(label="Save", command=doNothing)
subMenu.add_separator()
editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editMenu)
editMenu.add_command(label="Undo",command=doNothing)
root.mainloop()
You can do that like this:
TextArea = Text()
TextArea.pack(expand=YES, fill=BOTH)
If you want a scrollbar with it:
TextArea = Text()
ScrollBar = Scrollbar(root)
ScrollBar.config(command=TextArea.yview)
TextArea.config(yscrollcommand=ScrollBar.set)
ScrollBar.pack(side=RIGHT, fill=Y)
TextArea.pack(expand=YES, fill=BOTH)
Hope this helped, good luck!
It is an old question but currently following is a very good method for scrollable multiline text entry:
ScrolledText(mainwin, width=50, height=5).pack()
Full program:
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
ScrolledText(mainwin, width=50, height=5).pack()
mainwin.mainloop()
Following demo application shows its usage further and comparison with entry box (for python3):
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
Label(mainwin, text="An Entry Box:").grid(row=0, column=0)
ent = Entry(mainwin, width=70); ent.grid(row=0, column=1)
Button(mainwin, text="Print Entry", command=(lambda: print(ent.get()))).grid(row=0, column=2, sticky="EW")
Label(mainwin, text="ScrolledText Box:").grid(row=1, column=0)
st = ScrolledText(mainwin, height=5); st.grid(row=1, column=1)
Button(mainwin, text="Print Text", command=(lambda: print(st.get(1.0, END)))).grid(row=1, column=2, sticky="EW")
Button(mainwin, text="Exit", command=sys.exit).grid(row=2, column=0, columnspan=3, sticky="EW")
mainwin.mainloop()

Resources