[PYTHON] Test Tkinter interrelated Callback

Operate Hex SpinBox and Bin Editor with each other

What you want to do

hextobin.png If you change that, this will change. If you change this, that will change. Is it a little troublesome to operate the GUI with each other?

What i did

By registering callback functions in each other's handlers I tried to be able to communicate each other's changes. There may be a more straightforward implementation, but first we were able to interact.

hextobin2.png

def callback (i): #Callback function generation Set a value in each box hx.set(i) be.set(i)

hx.setCallback (callback) #Call callback when there is a handler registration change in HexSpinbox be.setCallback (callback) #Hander registration in BinEditor Call callback when there is a change

MultiBinEditor.py


import tkinter as tk

class HexSpinbox(tk.Spinbox):
    def __init__(self, *args, **kwargs):
        self.var = tk.StringVar()
        self.bytenum = kwargs.pop('bytenum', 1)
        self.add_callback = None
        max_val = 0x1<<(self.bytenum*8)
        super().__init__(*args, **kwargs, textvariable=self.var, from_=0,to=max_val,
                         increment=1, command=self.callback )

    def set(self, val):
        s = "0x{:0%dx}" % (self.bytenum*2)
        self.var.set(s.format(int(val)))
        
    def get(self):
        hstr = super().get()
        return int(hstr, 16)

    def callback(self):
        val = super().get()
        self.set(val)
        self.add_callback(val) if self.add_callback != None else None

    def setCallback(self, func):
        self.add_callback = func

class BinEditFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.val = 0x00
        self.bits = []
        self.add_callback = None
        for i in range(8):
            btn = tk.Button(self,text=str(i), relief='raised', command=self.callback(i))
            btn.pack(sid='right')
            self.bits.append(btn)

    def callback(self, i):
        def push():
            self.val ^= (1<<i)
            self.redraw()
            self.add_callback(self.val) if self.add_callback != None else None
        return push

    def redraw(self):
        #All Button Delete
        for bit in self.bits:
            bit.destroy()
        self.bits.clear()
            
        #All Button ReCreate
        for i in range(8):
            if (self.val & (1<<i) > 0):
                btn = tk.Button(self,text=str(i), relief='sunken',
                                command=self.callback(i) )
            else:
                btn = tk.Button(self,text=str(i), relief='raised',
                                command=self.callback(i) )
            btn.pack(sid='right')
            self.bits.append(btn)
        
        
    def setCallback(self, func):
        self.add_callback = func

    def set(self, val):
        self.val = int(val)
        self.redraw()

if __name__ == "__main__":
    print("BinHexEditor")
    win = tk.Tk()
    hx = HexSpinbox(win)
    hx.pack(side=tk.LEFT)
    be = BinEditFrame(win)
    be.pack(side=tk.LEFT)

    def callback(i):
        hx.set(i)
        be.set(i)

    hx.setCallback(callback)
    be.setCallback(callback)
        
    win.mainloop()

Recommended Posts

Test Tkinter interrelated Callback
Test Tkinter interrelated Callback 2
test