ttk.Spinbox和tk.Spinbox之间的行为差​​异是什么(ttk中的箭头方向越野车是?)

时间:2019-02-18 18:12:50

标签: python python-3.x tkinter tcl ttk

除了已记录的那些,ttk.Spinbox类和tk.Spinbox类之间有什么区别?

我发现了一些差异,例如:

  1. ttk.Spinbox按下箭头后设置为0,而tk.Spinbox则没有。
  2. ttk.Spinbox不能通过按箭头来验证更改,而tk.Spinbox可以通过。
  3. 在OSX上按下时,ttk.Spinbox箭头按钮不点亮,而tk.Spinbox箭头按钮则点亮。在Windows上,两者都亮起。
  4. 关键,检索方向适用于tk.Spinbox,但不适用于ttk.Spinbox:ttk.Spinbox打印'%d',而tk.Spinbox打印'up'或{ {1}}(下面的工作示例)

后者是一个错误吗?如果是,是否有办法解决此问题?我想将ttk.Spinbox用作tk。Spinbox无法正确设置样式,没有.set()等。

以下代码生成两个Spinboxes。第一个继承自tkinter,第二个继承自ttk。它们的修改是相同的。

'down'

2018年12月,对tkinter 8.6进行了更新,除其他功能外,还向ttk添加了Spinbox。据我了解,在tkinter 8.5中,虽然ttk.Spinbox确实遵循ttk的Style等,但没有特殊的ttk.Spinbox。所以必须定义一些内容,对吧?

我在tkinter 8.6和8.5中都尝试过(据说它没有Spinbox,但仍然可以正确设置Style),并且结果相同。即, ttk.Spinbox打印import tkinter as tk import tkinter.ttk as ttk class TkSpinbox(tk.Spinbox): def __init__(self, *args, **kwargs): super().__init__(*args, increment = 1, **kwargs) self.tcl_do_upon_clicking_arrows = self.register(self.do_upon_clicking_arrows) self.config(command = (self.tcl_do_upon_clicking_arrows, '%d')) self.tcl_validate = self.register(self.validate) self.config(validate = 'all', validatecommand = (self.tcl_validate, '%d')) def do_upon_clicking_arrows(self, direction): print(direction) def validate(self, typeOfAction): print(typeOfAction) return(True) class TtkSpinbox(ttk.Spinbox): def __init__(self, *args, **kwargs): super().__init__(*args, increment = 1, **kwargs) self.tcl_do_upon_clicking_arrows = self.register(self.do_upon_clicking_arrows) self.config(command = (self.tcl_do_upon_clicking_arrows, '%d')) self.tcl_validate = self.register(self.validate) self.config(validate = 'all', validatecommand = (self.tcl_validate, '%d')) def do_upon_clicking_arrows(self, direction): print(direction) def validate(self, typeOfAction): print(typeOfAction) return(True) root = tk.Tk() tkSpinbox = TkSpinbox() ttkSpinbox = TtkSpinbox() tkSpinbox.grid() ttkSpinbox.grid() root.mainloop() ,而tk.Spinbox打印'%d''up' 。然而,validatecommand确实在两种情况下都能正常工作。

我检查了the Tk source code bug repository的错误报告,但没有发现此问题。我是否正确使用了ttk.Spinbox的命令?

2 个答案:

答案 0 :(得分:1)

使用Tcl / Tk:

  • ttk.Spinbox按下箭头后设置为0,而tk.Spinbox 没有。

    必须设置-to值。

  • ttk.Spinbox不能通过按箭头来验证更改,而tk.Spinbox可以通过按箭头来验证。

    实际上是tk.spinbox中的错误-它做得太多。 如果该输入有效,则向上或向下操作不会使其无效。

  • 在tk.Spinbox上按OSX时,ttk.Spinbox箭头按钮不点亮。 箭头按钮。在Windows上,两者都亮起。

    OSX小部件实现与Windows分开,两者都尝试 符合原始外观。一个实施问题。

  • 至关重要的是,检索方向适用于tk.Spinbox,但不适用于ttk.Spinbox:ttk.Spinbox打印'%d',而tk.Spinbox打印'up'或'down'(下面的工作示例)

    这里的问题是,python在tcl_do_upon_clicking_arrows内部做什么? Tk中没有执行此操作的特定绑定。没有%d绑定参数 在Tk中返回上/下。

    这是python tkinter问题。

    在Tk中,有关变量或验证命令的跟踪 将用于跟踪更改。

答案 1 :(得分:0)

在继承上述问题的类之前,我通过修改ttk.Spinbox以利用生成的<<Increment>><<Decrement>>事件来解决了关键的错误行为(第四点)。

class UpDownSpinbox(ttk.Spinbox):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # bind the events that are triggered by pressing an arrow button  
        self.bind("<<Increment>>", self._do_on_increment)
        self.bind("<<Decrement>>", self._do_on_decrement)

    def _do_on_increment(self, *args, **kwargs):
        self.do_upon_clicking_arrows("up")
        # optional, prevent the event handler from doing other things by returning "break"
        return("break")

    def _do_on_decrement(self, *args, **kwargs):
        self.do_upon_clicking_arrows("down")
        # optional, prevent the event handler from doing other things by returning "break"
        return("break")

    def do_upon_clicking_arrows(self, direction):
        print(direction)

然后

class TtkSpinBox(UpDownSpinbox):
    def __init__(    # ..... fill in as in original question.

这将在按下这些按钮时在控制台上“向上”或“向下”打印。 do_upon_clicking_arrows()函数当然可以代替具有所需行为的任​​何事物。