Каковы поведенческие различия между ttk.Spinbox и tk.Spinbox (и является ли направление стрелки ошибочным в ttk?) - PullRequest
0 голосов
/ 18 февраля 2019

В чем различия между классами ttk.Spinbox и классами tk.Spinbox, кроме документированных?

Я обнаружил несколько различий, например:

  1. ttk.Spinboxустанавливает значение 0 после нажатия стрелок, в то время как tk.Spinbox этого не делает.
  2. ttk.Spinbox не проверяет изменения, нажимая стрелки, в то время как tk.Spinbox делает.
  3. Кнопки со стрелками ttk.Spinboxне загораются при нажатии на OSX, в то время как кнопки со стрелками tk.Spinbox горят.В Windows оба загораются.
  4. Важно , получение направления работает для tk.Spinbox, но не для ttk.Spinbox: ttk.Spinbox печатает '%d', в то время как tk.Spinbox печатает'up' или 'down' (рабочий пример ниже)

Является ли последняя ошибка? Если так, есть ли способ исправить это?Я хотел бы использовать ttk.Spinbox, так как tk.Spinbox неправильно устанавливает стиль, не имеет .set () и т. Д.

Следующий код генерирует два Spinbox.Первый наследуется от tkinter, а второй от ttk.Их модификации идентичны.

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()

В декабре 2018 года вышло обновление для tkinter 8.6, которое добавляет, помимо прочего, Spinbox к ttk.Насколько я понимаю, в tkinter 8.5 нет специального ttk.Spinbox, хотя ttk.Spinbox действительно следует стилю ttk и т. Д. Поэтому должно быть что-то определенное, верно?

Я пробовал это и в tkinter 8.6, и в8.5 (который предположительно не имеет Spinbox, но все еще правильно устанавливает стиль) и имел тот же результат.А именно, ttk.Spinbox печатает '%d', а tk.Spinbox печатает 'up' или 'down'.Тем не менее, команда validate работает как и ожидалось в обоих случаях.

Я проверил репозиторий ошибок исходного кода Tk для отчетов об ошибках, но не нашел этой проблемы.Я правильно использую команду ttk.Spinbox?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Я решил решающее неправильное поведение (четвертая точка), изменив 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() можно, конечно, заменить на что угодно с желаемым поведением.

0 голосов
/ 19 февраля 2019

С Tcl / Tk:

  • ttk.Spinbox устанавливается в 0 после нажатия стрелок, тогда как tk.Spinbox нет.

    Значение -to должно бытьset.

  • ttk.Spinbox не проверяет изменения нажатием стрелок, а tk.Spinbox делает.

    На самом деле ошибка в tk.spinbox - она ​​тоже делаетмного.Если запись действительна, действие вверх или вниз не может сделать ее недействительной.

  • Кнопки со стрелками ttk.Spinbox не загораются при нажатии на OSX, в то время как кнопки со стрелками tk.Spinbox делают,В Windows оба загораются.

    Реализация виджета OSX отделена от окон, и оба пытаются соответствовать собственному внешнему виду.Проблема реализации.

  • Важно, что получение направления работает для tk.Spinbox, но не для ttk.Spinbox: ttk.Spinbox печатает «% d», в то время как tk.Spinbox печатает «вверх».'или' вниз '(рабочий пример ниже)

    Вопрос здесь в том, что делает python внутри tcl_do_upon_clicking_arrows?Там нет конкретного связывания в Tk, который делает это.В Tk нет параметра% d связывания, который возвращает вверх / вниз.

    Это проблема Python tkinter.

    В Tk будет использоваться трассировка связанной переменной или команда проверкиотслеживать изменения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...