I have a fullscreen window with a fullscreen canvas. First I place a fullscreen background image in this canvas.
canvas = tk.Canvas(window, bg="white", bd=0)
canvas.pack(fill=tk.BOTH, expand=True)
canvas.update()
image = Image.open('bild.jpg')
newimage = image.resize((canvas.winfo_width(),canvas.winfo_height()),Image.LANCZOS)
photo = ImageTk.PhotoImage(newimage, master=canvas)
canvas.create_image(0, 0, anchor="nw", image=photo)
canvas.update()
Then I place a headline text on the top right and below this a longer text. The text is much longer than the screen height.
rectangle_width = int(canvas.winfo_width() * 0.45)
rectangle_x = canvas.winfo_width() - rectangle_width
headblock = canvas.create_text(
rectangle_x+10, 10,
anchor='nw',
text=headline,
font=('Helvetica', 18, 'bold'),
fill='black',
width=rectangle_width - 20
)
x1, y1, x2, y2 = canvas.bbox(headblock)
textblock = canvas.create_text(
rectangle_x+10, y2+10,
anchor='nw',
text=fulltext,
font=('Helvetica', 14, 'normal'),
fill='black',
width=rectangle_width - 20
)
canvas.update()
Now I wan't to animate the long text, like a telepromter, moving slowly upwards, so that viewers can read the full text. This works fine with canvas.move()
def animate():
canvas.move(textblock, 0, -1)
x1, y1, x2, y2 = canvas.bbox(textblock)
if y2 > canvas.winfo_height():
window.after(60, animate)
But while the textblock is moving up it is shown behind the headline. The problem is the background image. That should always be visible. If I place headline and text in different objects, labels, canvas, whatever, they are not transparent anymore.
Has anyone a good idea, how move the only the long text, while the image is always visible and the headline stays static?
You can use another Canvas
widget as the telepromter with a cropped image from the background image that makes it looks like transparent, then scroll the text inside it:
import tkinter as tk
from PIL import Image, ImageTk, ImageGrab
headline = 'Headline'
with open(__file__) as f:
fulltext = f.read()
window = tk.Tk()
window.geometry('800x600')
canvas = tk.Canvas(window, bg="white", bd=0)
canvas.pack(fill=tk.BOTH, expand=True)
canvas.update()
image = Image.open('lena.jpg')
newimage = image.resize((canvas.winfo_width(),canvas.winfo_height()),Image.LANCZOS)
photo = ImageTk.PhotoImage(newimage, master=canvas)
canvas.create_image(0, 0, anchor="nw", image=photo)
#canvas.update()
rectangle_width = int(canvas.winfo_width() * 0.45)
rectangle_x = canvas.winfo_width() - rectangle_width
headblock = canvas.create_text(
rectangle_x+10, 10,
anchor='nw',
text=headline,
font=('Helvetica', 18, 'bold'),
fill='black',
width=rectangle_width-20
)
x1, y1, x2, y2 = canvas.bbox(headblock)
rectangle_height = canvas.winfo_height() - y2 - 10
telepromter = tk.Canvas(canvas, width=rectangle_width-20, height=rectangle_height-10, highlightthickness=0)
canvas.create_window(rectangle_x+10, y2+10, window=telepromter, anchor='nw')
# get the image at the required region
img = newimage.crop((rectangle_x+10, y2+10, newimage.width, newimage.height))
bg = ImageTk.PhotoImage(img)
telepromter.create_image(0, 0, image=bg, anchor='nw')
textblock = telepromter.create_text(
0, 0,
anchor='nw',
text=fulltext,
font=('Helvetica', 14, 'normal'),
fill='black',
width=rectangle_width
)
def animate():
telepromter.move(textblock, 0, -1)
x1, y1, x2, y2 = telepromter.bbox(textblock)
if y2 > telepromter.winfo_height():
window.after(50, animate)
animate()
window.mainloop()
Result: