How do I put a button on a Canvas? - python

So I can do a button in a simple window but not on a Canvas.
from tkinter import *
window = Tk()
def function():
print('Hello World')
tk_button = Button(window, text = 'Click me!', command = function)
I want to position the button on a tkinter Canvas and have graphics around it, not just the bare window with the button.

You can use the create_window function on a canvas to put a frame on it, then use that frame to pack other widgets normally.
import tkinter as tk
mw = tk.Tk()
canvas = tk.Canvas(mw, bg='grey75')
canvas.pack()
frame = tk.Frame(canvas, width=50, height=5)
canvas.create_window((1,1), window=frame, anchor='nw')
button = tk.Button(frame, text='Hello World')
button.pack()
mw.mainloop()

Related

How to switch screens using tkinter?

I want to switch the screen using the tkinter module.
Is it possible to switch screens without frame?
This is the code I did.
#frame1.py
from tkinter import *
root=Tk()
root.title('page1')
def goto_p2():
root.destroy()
import frame2
Button(root, text="goto page1", command=goto_p2).pack()
mainloop()
.
#frame2.py
from tkinter import *
root=Tk()
root.title('page1')
def goto_p1():
root.destroy()
import frame1
Button(root, text="goto page2", command=goto_p1).pack()
mainloop()
Here you go, example code how it can be done.
import tkinter as tk
from tkinter import Button,Label
def clear_frame():
for widget in window.winfo_children():
widget.destroy()
def screen_two():
clear_frame()
button_2 = Button(window, text="Go to screen one", command=lambda: screen_one())
button_2.pack(pady=10)
label_2 = Label(window, text="Label on window two")
label_2.pack(pady=10)
def screen_one():
clear_frame()
button_1 = Button(window, text="Go to screen two", command=lambda: screen_two())
button_1.pack(pady=10)
label_1 = Label(window, text="Label on window one")
label_1.pack(pady=10)
window = tk.Tk()
window.title("Test")
window.geometry('250x100')
screen_one()
window.mainloop()
[EDITED]
Function clear_frame() will destroy every widget in frame ( basicly it will clear screen). Besides clear_frame(), there are two more functions, screen_two() and screen_one(). Both of those functions are doing the same thing, calling clear_frame() function, and displaying one button and one label. (Only difference is text inside label and text inside button).
When code runs, it will create window with geometry of 250x100. It will call screen_one() function and run mainloop().

How to Move a button from one frame to another on click using tkinter?

I have 2 frames, one of them has a button "click". On clicking that button, the same button should be destroyed from the original frame and move to frame2. How to achieve it using tkinter.
there is tow frames frame1 and frame2 first we want to show this button using pack(). now we want to add function on command of my_btn then we want to destroy that button and re define it in the second frame.
final code:
from tkinter import *
window = Tk()
frame1 = Frame(window, width=50, height=50, bg='red')
frame2 = Frame(window, width=50, height=50, bg='blue')
frame1.propagate(0); frame2.propagate(0)
frame1.pack(); frame2.pack()
def click():
global my_btn
my_btn.destroy()
my_btn = Button(master=frame2)
my_btn.pack()
my_btn = Button(master=frame1, command=click)
my_btn.pack()
window.mainloop()
Hope this works.

Center an image when resizing

Working with Tkinter, I need to center entities. When trying to center labels, it will only center it within the first row, and not the window.
I want it centered within the entire window. i.e. the middle. So far, it is only the middle of the top. is this possible?
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
root.title("I Love You")
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.pack(side=LEFT)
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.pack()
root.mainloop()
You can use grid instead of pack, with rowconfigure and columnconfigure methods like this :
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
root.title("I Love You")
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.grid(row=0, column=0, sticky='w')
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.grid(row=1, column=1)
root.rowconfigure([0,1,2], weight=1)
root.columnconfigure([0,1,2], weight=1)
root.mainloop()
Answer to comment
This also works, but it's not centered the same way :
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
root.title("I Love You")
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.grid(row=0, column=0, sticky='w')
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.grid(row=0, column=1, sticky='')
root.rowconfigure(0, weight=1)
root.columnconfigure([0,1], weight=1)
root.mainloop()
After some tinkering (no pun intended), I added expand=YES to frame.pack() in the whatsup() function.
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack(expand=YES) # This was the changed line!
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
This allows for the popup text to become centered.

how to fix the position of scrollbar of scrolledtext widget in tkinter?

i want to fix the postion of scrollbar of scrolledtext widget of tkinter.
i'am creating a chatbot where after every new message there is need to drag the scrollbar down to see conversation which has a bad impact.
here is the code of scrolledtext
self.conversation = ScrolledText.ScrolledText(self,
state='disabled',borderwidth=5,
highlightthickness=1,
bg='#15202b',fg='#16202A',
font=('Arial Bold',8))
self.conversation.grid(column=0, row=1, columnspan=2, sticky='nesw', padx=3, pady=3)
from tkinter import *
from tkinter import scrolledtext
root = Tk()
scroll_x = Scrollbar(root, orient="horizontal")
text = scrolledtext.ScrolledText(root, wrap=NONE)
text.config(xscrollcommand=scroll_x.set)
scroll_x.configure(command=text.xview)
text.pack(fill=X)
scroll_x.pack(fill=X)
for i in range(10000):
text.insert(END, str(i)+"\n")
text.see("end")
root.update()
root.mainloop()
The command you are looking for is see("end")
text.see("end")
root.update()

frame.destroy() and frame.quit() does not work

I am using python 3 I want to close an tkinter window to continue in code, but it doesn't work.
Here is my code:
import tkinter as tk
from tkinter import *
from tkinter import messagebox
def window():
global frame
frame = Tk()
Button1 = tk.Button(frame, text="No.", command=frame.quit)
Button1.pack(anchor=S, fill=X, side=RIGHT)
Button2 = tk.Button(frame, text="Yes!", fg="dark green", command=func)
Button2.pack(anchor=S, fill=X, side=LEFT)
frame.mainloop()
def func():
frame.destroy()
frame.quit()
messagebox.showinfo("Help", "Please help me.")
#Next step ....
window()
I want to exit the script with Button1 and continue and close the window with Button2, but I can't close the window in use of an other function.
import tkinter as tk
from tkinter import messagebox
def window():
global frame
frame = tk.Tk()
Button1 = tk.Button(frame, text="No.", command=func)
Button1.pack(anchor=tk.S, fill=tk.X, side=tk.RIGHT)
Button2 = tk.Button(frame, text="Yes!", fg="dark green", command=func)
Button2.pack(anchor=tk.S, fill=tk.X, side=tk.LEFT)
frame.mainloop()
def func():
global frame
frame.destroy()
messagebox.showinfo("Help", "Please help me.")
#Next step ....
window()
I have solved it,
the problem was: Evry messagebox need an main window, I have destroyed this main window before starting the massagebox and the messagebox started an new emty main window. My resulution is to minimize the main window, start the messagebox and after that to close the massagebox for cotinueing in code.
from tkinter import *
from tkinter import messagebox
main = Tk()
main.geometry("500x400+300+300")
def message():
main.geometry("0x0")
messagebox.showwarning("Say Hello", "Hello World")
main.destroy()
B1 = Button(main, text = "Start Dialog",fg="dark green", command = message)
B1.pack()
main.mainloop()
print("finish dialog")

Categories