在使用透明的TKinter窗体时,是否有办法使字体光滑,并消除“伪影”?

3
我尝试使用TKinter创建一个简单的应用程序,总体上很符合我的要求。然而,在使用透明表单时,出现了一些美学问题。我在黑色背景上悬停时使用的字体会产生白色像素框。
有没有可能以某种方式摆脱这样的“伪影”?使用cleartype后,“伪影”会减少,但仍然存在,这使得应用程序变得丑陋。
以下是我相当简单的代码:
from tkinter import *
import tkinter.font
import sys
import pyglet
from datetime import datetime, timedelta
import re

bgc = "#ffffff"
fgc = "#e34646"
pyglet.font.add_file("digital_7mono.ttf")

def timer(start_time):
    now_time = datetime.now()
    delta = now_time-start_time
    delta = '{:02d}'.format(delta.days//3600) + ":" \
            + '{:02d}'.format(delta.seconds//60) + ":" \
            + '{:02d}'.format(delta.seconds)
    #delta = delta.strftime("%H:%M:%S")
    return [delta, now_time]

class timerWindows(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        self.overrideredirect(True)
        self.title("Timer")
        self.geometry('420x110')

        self.wm_attributes("-topmost", True)
        #self.wm_attributes("-disabled", True)
        self.wm_attributes("-transparentcolor", "white")

        self.resizable(width=False, height=False)
        self.configure(bg = bgc)
        font = tkinter.font.Font(family="digital-7 Mono", size=80)
        #self.start_time.strftime("%H:%M:%S")
        self.l1 = Label(text = "00:00:00", bg = bgc,  font=font, )#fg = fgc)
        self.l1.configure()
        self.l1.grid(row=0, column=0, )#padx=5, sticky=NW)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.bind("<Button-1>", self.form_click)
        self.bind('<Double-Button-1>', self.double_form_click)
        self.bind('<B1-Motion>', self.on_drag)

        self.menu = tkinter.Menu(self, tearoff=0)
        self.menu.add_command(label="Закрыть", command=self.close_time)
        self.bind("<Button-3>", self.show_popup)
        #self.text.grid()

        self.start_time = datetime.now()
        self.pause_time = self.start_time
        self.checkpoint = True
        self.time_delta = timedelta(0)

    def on_drag(self, event):
        rect = re.fullmatch(r'\d+x\d+\+(?P<x>-?\d+)\+(?P<y>-?\d+)',
                            self.geometry()).groupdict()
        # NOTE: self.winfo_root*() is content's coordinate without window decorations
        x = int(rect['x']) + (event.x - self.start_x)
        y = int(rect['y']) + (event.y - self.start_y)
        self.geometry(f'+{x}+{y}')

    def show_popup(self, event):
        self.menu.tk_popup(event.x_root, event.y_root)

    def close_time(self):
        self.quit()

    def form_click(self, event):
        self.start_x = event.x
        self.start_y = event.y
        if self.checkpoint==True:
            self.checkpoint=False
        else:
            self.checkpoint = True
            self.start_reading(self.checkpoint)


    def double_form_click(self, event):
        self.checkpoint=False
        self.start_time = datetime.now()
        self.pause_time = self.start_time
        self.time_delta = timedelta(0)
        self.l1['text']="00:00:00"

    def start_reading(self, arg):
        if arg:
            if self.pause_time>self.start_time:
                self.start_time=datetime.now()
            start_time_return = timer(self.start_time-self.time_delta)
            self.l1['text'] = start_time_return[0]
            self.l1.update()
            self.after(1000, self.start_reading, self.checkpoint)  # repeat the call
        if not arg:
            self.pause_time=datetime.now()
            self.time_delta = self.time_delta+(self.pause_time-self.start_time)


def main(argv):
    window = timerWindows()
    window.after(1000, window.start_reading, True)
    window.mainloop()


if __name__ == '__main__':
    main(sys.argv)
1个回答

2

在寻找一段时间后,似乎没有合法的方法可以去除这些“瑕疵”。

然而,我相信如果您将变量bgc设置为接近但不同于黑色的颜色(比如#000001),那么颜色上的微小差异会使这些瑕疵变得不明显。


记得将透明颜色设置为新的背景颜色。

self.wm_attributes("-transparentcolor", bgc)


评论后编辑:

我不确定您所说的“原则”是什么意思,但我猜想您想要一种动态更改颜色并且没有伪影的方法。

因此,我们需要将bgc设置为始终比fgc多1个值。

我们可以通过将十六进制值转换为整数并递增来实现这一点。然后将新值转换为十六进制代码。

首先,让我们将fgc设置为十六进制代码。

fgc =“#000000”

接下来,让我们将fgc配置为一个新变量(fgc_),以便我们可以将其转换为整数。我们将使用replace()删除#,并使用int的内置十六进制到十进制转换(参数为16)。

fgc_ = int(fgc.replace("#", ""), 16) #Output: 0

我们可以使用.format()将变量bgc设置为递增的值:

bgc = '#{:06x}'.format(fgc_ + 1)

这行代码确保bgc只有6个字符长(不包括#)。

请注意,由于我们是正向递增的,因此值#ffffff将无法使用。但是,如我上面提到的,您可以使用非常接近该值的值(#fffffe),而且肉眼几乎看不出来。

希望这更接近您要寻找的内容!

以下是最终代码:

fgc = "#000000" #whatever you want it to be (except #ffffff)

fgc_ = int(fgc.replace("#", ""), 16) #remove pound and convert from base-16 to base-10

bgc = '#{:06x}'.format(fgc_ + 1) #increment +1 and format back to hex.

它变得好多了!但是我想找出一些通用且易于理解的原则。例如,我为数字设置了另一种颜色(fgc =“#e34646”),然后我再次遇到了伪影,尽管使用黑色时一切看起来都很好。 - user7919275
1
@rack 编辑了我的答案。希望它更接近您所要寻找的内容。 - SanguineL
感谢您的帮助。 - user7919275

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接