LoginSignup
0
1

More than 3 years have passed since last update.

Tkinter 相互関連があるCallbackをテストする2

Last updated at Posted at 2020-10-28

最近忙しく、Markdownの書き方も少し忘れていたため、思い出す意味も込めて投稿。
下記相互関係のCallbackを使った場合に、複数のオブジェクトを関係を作ると
ソースが雑多となるため、ペアとしてまとめられるようにソース修正。
https://qiita.com/Nomisugi/items/8d11e0419091ac21866d (修正前のコード)

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
        self.handle_obj = 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_pair(self, obj):
        self.pair_obj = obj
        self.add_callback = self.handle

    def handle(self, val):
        self.set(val)
        self.pair_obj.set(val)

    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
        self.pair_obj = 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 setCallback_pair(self, obj):
        self.pair_obj = obj
        self.add_callback = self.handle

    def handle(self, val):
        self.set(val)
        self.pair_obj.set(val)

    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)

    hx.setCallback_pair(be)
    be.setCallback_pair(hx)

    win.mainloop()

外部にCallback関数を追加せずに、相互の数値を変更できる仕組みができました。
これを使って特殊バイナリエディタを作ってみます。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1