Как сделать отмену и повтор для значения масштаба слайдера?

#python #tkinter

Вопрос:

У меня есть код ниже :

 var = DoubleVar()
scale = Scale(root, variable = var, command=self.scalfunc, from_=4, to=40, width=40,tickinterval=0,orient=VERTICAL,length=300,highlightthickness=0, background='#333333', fg='grey', troughcolor='#333333', activebackground='#1065BF')
scale.pack(anchor=CENTER)
scale.place(x=SCwidth/1.2, y=SCheight/15)
 

и у меня есть кнопка UNDO и кнопка пыльника REDO

Я хочу, чтобы при нажатии на эту кнопку значение ползунка отменялось или повторялось

Комментарии:

1. В объекте нет элементов управления для отмены или повтора Scale . Я разработал программу, которая реализует это, и опубликую ее сейчас.

Ответ №1:

Этот код позволяет использовать клавиши управления для изменения master цвета tkinter.tk окна.

Изменения в Scale хранятся в списке, называемом памятью, с использованием индекса int , называемого счетчиком.

Control-z отменит

Control-Z будет переделывать

Control-x очистит память

Не должно быть слишком сложно изменить его в соответствии с вашими потребностями.

 import tkinter as tk

class UndoRedo:

    def __init__(self):
        self.master = tk.Tk()
        self.master.withdraw()
        self.master.columnconfigure(0, weight = 1)
        self.master.columnconfigure(1, weight = 1)
        self.color = 15790320 # #f0f0f0 = SystemButtonFace
        self.var = tk.IntVar(self.master, value = self.color)
        self.label = tk.Label(self.master, anchor = tk.E)
        self.label.grid(row = 0, column = 0, sticky = tk.NSEW)
        self.clear() # define memory and counter
        self.scroll = tk.Scale(
            self.master, orient = "horizontal", resolution = 65793,
            label = "Brightness Control", from_ = 0, to = 16777215,
            variable = self.var, command = self.control)
        self.scroll.grid(row = 1, column = 0, columnspan = 2, sticky = tk.EW)
        for k, v in [
            ( "<Control-z>", self.undo ),
            ( "<Control-Z>", self.redo ),
            ( "<Control-x>", self.clear )]:

            self.master.bind(k, v)
        self.master.geometry("400x86")
        self.master.update()
        self.master.minsize(329, 86)
        self.master.resizable(True, False)
        self.master.deiconify()

    def display(self):
        col = "#"   ("000000"   hex(self.color)[2:])[~5:]
        self.var.set(self.color)
        self.label["text"] = col
        self.master.tk_setPalette(col)
        
    def control(self, n):
        self.color = int(n)
        self.display()
        if self.color not in self.memory:
            self.memory.append(self.color)
            self.counter = self.counter   1

    def action(self):
        self.color = self.memory[self.counter]
        self.display()

    def undo(self, ev = None):
        if self.memory:
            self.counter = max(0, self.counter - 1)
            self.action()

    def redo(self, ev = None):
        if self.memory:
            self.counter = min(len( self.memory ) - 1, self.counter   1)
            self.action()

    def clear(self, ev = None):
        self.memory, self.counter = [], 0
        self.label["text"] = "cleared"

if __name__ == "__main__":
    bright = UndoRedo()
    bright.master.mainloop()
 

Комментарии:

1. Спасибо за ваш ответ ,,, но теперь вопрос в том, если у меня больше слайдера и каждый слайдер имеет разное значение, как я мог бы отменить или повторить?

2. Для этого вы можете создать главное окно отдельно и поместить все компоненты слайдера в определенный класс, а затем инициализировать каждый слайдер. Все они будут иметь свою собственную структуру управления отменойповтором и память.

Ответ №2:

Если я правильно понимаю, вы можете сохранить все позиции, занятые ползунком, в списке и использовать указатель индекса для управления тем, где он находится в списке.

 silder_ind = 0
slider_positions = [4] # Or wherever you want to start by default
 

Когда пользователь изменяет положение ползунка

 new_pos = slider.get_current_value() # whatever the appropriate API call is to get the current value
slider_positions.append(new_pos)
slider_ind  = 1
 

Когда пользователь нажимает кнопку отменить

 if (slider_ind - 1) >= 0:
    slider_ind -= 1
 

переделывать

 if (slider_ind   1) < len(slider_positions):
    slider_ind  = 1
 

Комментарии:

1. если у меня несколько ползунков, и у каждого ползунка разное значение,как я могу их отменить или повторить ,,