Прокрутите QSpinbox, когда дойдете до конца

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

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

from PyQt5.QtWidgets import QSpinBox
from music import TonoFactory

_tf = TonoFactory()


class StringBox(QSpinBox):
    def __init__(self, parent=None):
        super(StringBox, self).__init__(parent)
        strings = []
        for key in _tf.notas.keys():
            strings.append(key)
        self.setStrings(strings)
        self.editingFinished.connect(self.reset_spin)

    def strings(self):
        return self._strings

    def setStrings(self, strings):
        strings = list(strings)
        self._strings = tuple(strings)
        self._values = dict(zip(strings, range(len(strings))))
        self.setRange(0, len(strings) - 1)

    def textFromValue(self, value):
        return self._strings[value]

    def valueFromText(self, text):
        return self._values[text]

    def reset_spin(self):
        if self.value() == len(self.strings()) -1:
            self.setValue(0)

person Nicolas Quiroz    schedule 06.12.2017    source источник
comment
Покажите, что вы пробовали. SO не является службой кодирования, прочитайте следующее: Как спросить   -  person eyllanesc    schedule 07.12.2017
comment
@eyllanesc добавляет это сейчас   -  person Nicolas Quiroz    schedule 07.12.2017
comment
Нужно ли использовать TonoFactory для этого примера?   -  person eyllanesc    schedule 07.12.2017


Ответы (2)


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

Пример:

class StringBox(QSpinBox):
    def __init__(self, parent=None):
        super(StringBox, self).__init__(parent)
        strings = []
        texts = ["do", "re", "mi", "fa", "sol", "la", "si"]
        for key in texts:
            strings.append(key)
        self.setStrings([""] + strings + ["-"])
        self.setValue(1)

    def strings(self):
        return self._strings

    def setStrings(self, strings):
        strings = list(strings)
        self._strings = tuple(strings)
        self._values = dict(zip(strings, range(len(strings))))
        self.setRange(0, len(strings)-1)

    def textFromValue(self, value):
        return self._strings[value]

    def valueFromText(self, text):
        return self._values[text]

    def stepBy(self, step):
        if self.value() == 1 and step == -1:
            self.setValue(self.maximum())
        elif self.value() == self.maximum() -1  and step == 1:
            self.setValue(0)
        QSpinBox.stepBy(self, step)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    w = StringBox()
    w.show()
    sys.exit(app.exec_())

Примечание. Поскольку вы используете словарь и в нем не может быть повторяющихся ключей, я рекомендую, чтобы добавляемые вами элементы отличались от отображаемых текстов.

person eyllanesc    schedule 07.12.2017
comment
разве вы не должны добавить возврат в условные выражения, чтобы суперметод не вызывался? - person Nicolas Quiroz; 07.12.2017
comment
@NicolasQuiroz Моя идея состоит в том, чтобы использовать этот метод в качестве фильтра только до того, как значение будет обновлено, в вашем случае вы пытались использовать editFinished, но он выдается после изменения, поэтому он терпит неудачу. - person eyllanesc; 07.12.2017
comment
@NicolasQuiroz Прочтите мою заметку - person eyllanesc; 07.12.2017
comment
Вы должны добавить еще 2 значения в строки, одно в начале и одно в конце, они просто для заполнения. - person eyllanesc; 07.12.2017

Используйте метод spinbox.setWrapping(True)

Это встроенный метод для повторения значений счетчика.

person Rakshit Arora    schedule 28.05.2020