Менять отображаемое изображение внутри mainl oop на Tkinter? - PullRequest
0 голосов
/ 12 января 2020

Я пытаюсь сделать программу для отображения одного цвета, полноэкранного. Идея состоит в том, чтобы использовать его на большом экране для создания обстановки в комнате, когда экран меняется от цвета к цвету через определенное время.

Отображение полноэкранного цвета не является проблемой, но как я могу плавно изменить указанный цвет?

Для полноэкранного отображения я использовал окно Tkinter того же размера, что и экран: imagesprite = canvas.create_image(w/2, h/2, image=image) где image - это определенный цвет. Но чтобы изменить цвет, мне нужно уничтожить окно, используя root.after(2000, root.destroy), а затем создать новое. Это не гладко, так как рабочий стол можно увидеть на короткое время.

Как я могу изменить изображение, отображаемое в окне Tkinter на go, или как я могу закрыть одно окно и открыть другое гладко?

1 Ответ

2 голосов
/ 12 января 2020

У вас есть возможность вместо изображения использовать фон для объекта Canvas. Вот минимальный код, чтобы иметь один цветной фон.

from tkinter import Tk, Canvas
root = Tk()
root.attributes("-fullscreen",True)#Makes the window fullscreen
canvas = Canvas(root, width=root.winfo_width(),height=root.winfo_height(), background="red") #Makes a canvas with a red coloured background
#The width and height of the Canvas are taken from the root object
canvas.pack()
root.mainloop()

Здесь вместо постоянного удаления окна можно просто изменить атрибуты виджетов Tkinter. Это делается с помощью метода конфигурации.

canvas.config(background="green")

Отличительной особенностью tkinter является то, что вы можете дать ему шестнадцатеричный код для цвета, и он будет использовать его. Она должна быть в строке, отформатированной следующим образом: "#RRGGBB" где каждая группа представляет собой шестнадцатеричное число от 0 до FF.

Имея это в виду, вы можете увеличивать шестнадцатеричное число на каждый кадр или на сколько угодно кадров. хочу между двумя цветами. Чтобы получить хороший переход, вы можете использовать цвета Hue, Saturation, Value (HSV) и изменять только значение Hue.

Вы можете сохранить HSV в списке:

hsv = [0,0.7,0.7]

Чтобы преобразовать, вы сначала хотите преобразовать в 0 до 255 RGB, а затем в шестнадцатеричный.

import colorsys
rgb = colorsys.hsv_to_rgb(*hsv) #Uses list unpacking to give it as arguments

Далее вы используете rgb и превращаете его в форму Hexcode.

def getHexCode(rgb):
    r = hex(int(rgb[0]*255))[2:] #converts to hexadecimal
    #With the hex() function, it returns a number in "0xFE" format (0x representing hex).
    #To ignore this, we can take the substring using [2:]
    if len(r) < 2: #If the value is a 1-digit number, then we want to add a zero at the front for hexcode form
        r = "0"+r
    g = hex(int(rgb[1]*255))[2:]
    if len(g) < 2:
        g = "0"+g
    b = hex(int(rgb[2]*255))[2:]
    if len(b) < 2:
        b = "0"+b

    return "#" + r + g + b

Наконец, мы на самом деле вызываем метод change.

changeSpeed = 200
def changeColor():
    rgb = colorsys.hsv_to_rgb(*hsv)
    hexCode = getHexCode(rgb)
    canvas.config(background = hexCode)
    hsv[0]+=0.01
    root.after(changeSpeed,changeColor)

root.after(changeSpeed, changeColor)

(EDITED) Ранее были две проблемы: root.winfo_width() и root.winfo_height(), а также полноэкранный режим, дающий границу.

Чтобы решить первую проблему, нам нужно как-то обновить объект root, так как по умолчанию это 1x1. Для этого мы можем создать объект Canvas и затем обновить его. Это выглядит так:

canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())

Вторая проблема также решается путем создания объекта canvas с заданным атрибутом c, highlightthickness=0. Если вы заметили, инициализация объекта canvas теперь такова:

canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0)

Еще одна вещь, которая, на мой взгляд, была полезной, - это если кнопка закрывает программу. Я связал клавишу «Escape» с закрытием, используя следующее:

def quit(event):
    root.destroy()

root.bind("<Escape>", quit)

Как полная программа, она выглядит так:

import colorsys
from tkinter import Tk, Canvas

hsv = [0,1,0.8]
changeSpeed = 200

root = Tk()
root.attributes("-fullscreen",True)
canvas = Canvas(root, width=100,height=100, background="white",highlightthickness=0) #Makes a canvas with a white coloured background
canvas.pack()
canvas.update()
canvas.config(width = root.winfo_width(), height = root.winfo_height())


def getHexCode(rgb):
    r = hex(int(rgb[0]*255))[2:]
    if len(r) < 2:
        r = "0"+r
    g = hex(int(rgb[1]*255))[2:]
    if len(g) < 2:
        g = "0"+g
    b = hex(int(rgb[2]*255))[2:]
    if len(b) < 2:
        b = "0"+b

    return "#" + r + g + b

def changeColor():
    rgb = colorsys.hsv_to_rgb(*hsv)
    hexCode = getHexCode(rgb)
    canvas.config(background = hexCode)
    hsv[0]+=0.01
    root.after(changeSpeed,changeColor)

def quit(event):
    root.destroy()

root.after(changeSpeed, changeColor)
root.bind("<Escape>", quit)

root.mainloop()

Некоторые переменные, которые вы можете изменить в этом: changeSpeed, исходный список hsv и 0.01, которые добавляются к оттенку каждый раз, увеличиваются

...