如何使 tkinter 窗口变圆? [英] How to make a tkinter window rounded?

查看:116
本文介绍了如何使 tkinter 窗口变圆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作圆形的 tkinter overrideredirect 窗口.到目前为止,我已经这样做了:

I am trying to make a tkinter overrideredirect window round in shape. I've done this so far:

from tkinter import Tk, Canvas, BOTH, PhotoImage
from tkinter.constants import NW, RAISED
import pyautogui as pg

root = Tk()
root.overrideredirect(1)
root.attributes("-topmost", 1)
root.geometry("500x500")

# Creating a canvas for placing the squircle shape.
canvas = Canvas(root, height=500, width=500, highlightthickness=0)
canvas.pack()

def place_center(): # Placing the window in the center of the screen
    global x, y
    reso = pg.size()
    rx = reso[0]
    ry = reso[1]
    x = int((rx/2) - (500/2))
    y = int((ry/2) - (500/2))
    root.geometry(f"500x500+{x}+{y}")

def round_rectangle(x1, y1, x2, y2, radius=25, **kwargs): # Creating a rounded rectangle
        
        points = [x1+radius, y1,
                x1+radius, y1,
                x2-radius, y1,
                x2-radius, y1,
                x2, y1,
                x2, y1+radius,
                x2, y1+radius,
                x2, y2-radius,
                x2, y2-radius,
                x2, y2,
                x2-radius, y2,
                x2-radius, y2,
                x1+radius, y2,
                x1+radius, y2,
                x1, y2,
                x1, y2-radius,
                x1, y2-radius,
                x1, y1+radius,
                x1, y1+radius,
                x1, y1]

        return canvas.create_polygon(points, **kwargs, smooth=True)

place_center()

# Taking a screenshot and adding it to the canvas to create a transparent effect
root.withdraw()
s = pg.screenshot(region=(x, y, 500, 500))
tp = "C:\\Users\\username\\AppData\\Local\\Temp\\bg.png"
s.save(tp)
bg = PhotoImage(file=tp)
canvas.create_image(0, 0, image=bg, anchor=NW)
root.deiconify()
os.remove(tp)

# Creating the squircle
round_rectangle(0, 0, 500, 500, radius=70, fill="#1fa5fe")

root.mainloop()

我用这个函数来移动窗口:

I use this function to move the window:

def move(event):
    fx = root.winfo_pointerx() - 250
    fy = root.winfo_pointery() - 10
    root.geometry(f"500x500{fx}+{fy}")

我没有将它添加到代码中,因为当我移动窗口时,它再次变成方形,因为屏幕截图只截取了特定区域.

I haven't added it into the code because when I move the window, it becomes square again as the screenshot is taken only of a particular region.

搬家前:

搬家后:

即使我移动它,我怎样才能使它变圆?

How can I make it round even when I move it?

我尝试在 while True: 循环中使用 root.withdraw()root.deiconify() ,但它会导致闪烁.

I tried using root.withdraw() and root.deiconify() in a while True: loop, but it causes flickering.

任何帮助将不胜感激.

谢谢.

推荐答案

how to change window's shape in tkinter可能有问题,这意味着此确切代码可能无法正常工作并且无法提供所需的输出).代码注释中的说明:

how to change window's shape in tkinter (although this should work most certainly on Windows computers, some other OS (macOS, Linux) may have issues meaning that this exact code may not work and not give the desired output). Explanation in code comments:

from tkinter import Tk, Canvas
from PIL import Image, ImageTk
import requests


# load image from web but you can of course load it from file, this is
# just so you can run and immediately see the results
url = 'http://media-s3-us-east-1.ceros.com/g3-communications/images/2019/01/15/05eea4b9b9ce010d2dd6b0c063d2f5ca/p1-blob.png?imageOpt=1&fit=bounds&width=893'
data = requests.get(url, stream=True).raw
# just when loading your own image instead of `data` use the path, and resize
# if you need, can obvs change these numbers
image = Image.open(data).resize((600, 600), Image.ANTIALIAS)


root = Tk()
# set root bg color to some rare color because
# the `-transparentcolor` affects all colors on the window, all of them
root.config(bg='grey15')
# just simply set window to the middle, not necessary
root.geometry(f'+{root.winfo_screenwidth() // 2 - 300}+{root.winfo_screenheight() // 2 - 300}')
# the important part, set the transparentcolor to some rare color in this case `grey15`,
# can obvs be sth else depending on your theme
root.attributes('-transparentcolor', 'grey15')
# remove window from window manager
root.overrideredirect(True)

# create canvas and set the bg to the same "rare" color (width and height set
# to image width and height, can be sth different too)
canvas = Canvas(
    root, bg='grey15', width=image.width, height=image.height, highlightthickness=0
)
canvas.pack()
# convert image to PhotoImage for `tkinter` to understand
photo = ImageTk.PhotoImage(image)
# put the image on canvas because canvas supports transparent bg
canvas.create_image(0, 0, image=photo, anchor='nw')

root.mainloop()

关键部分是 .attributes('-transparentcolor', ...)(最有可能在某些操作系统上不起作用)并且窗口的形状由该形状的图像(图像应具有透明背景(.png 图像)).也可以使用 Canvas 方法 (.create_) 简单地绘制形状.同样重要的是要记住,该属性会影响窗口上的所有颜色,这意味着例如,如果您将透明颜色设置为白色并且您的背景图像包含白色,它很可能也是透明的(不过可能看起来不像好)所以我建议使用一些最不可能出现在 GUI 上的颜色

The key parts are .attributes('-transparentcolor', ...) (which is the most likely to not work on some OS) and that the shape of the window is formed by an image of that shape (the image should have transparent background (a .png image)). It is also possible to simply draw a shape using Canvas methods (.create_). Also important to remember that the attribute affects all the colors on the window meaning that for example if you were to set the transparentcolor to say white and your background image contained white, it will most likely be transparent too (tho probably won't look as good) so I would suggest using some color that is the least likely to be on the GUI

这篇关于如何使 tkinter 窗口变圆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆