How to reverse spinbox selection in PyQt5?

Question:

I have a spinbox in PyQt5 like below. How can I make the selection reversed? i.e. If I click down arrow, the value goes up, vice versa.

spinbox

Asked By: Gaz Zhao

||

Answers:

A possible solution is to override the stepBy() and stepEnabled() methods:

import sys
from PyQt5 import QtWidgets


class ReverseSpinBox(QtWidgets.QSpinBox):
    def stepEnabled(self):
        if self.wrapping() or self.isReadOnly():
            return super().stepEnabled()
        ret = QtWidgets.QAbstractSpinBox.StepNone
        if self.value() > self.minimum():
            ret |= QtWidgets.QAbstractSpinBox.StepUpEnabled
        if self.value() < self.maximum():
            ret |= QtWidgets.QAbstractSpinBox.StepDownEnabled
        return ret

    def stepBy(self, steps):
        return super().stepBy(-steps)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = ReverseSpinBox()
    w.resize(320, 20)
    w.show()
    sys.exit(app.exec_())
Answered By: eyllanesc

A fully working app:

# ReverseSpinbox.py    2022-10-25 4:43:56 PM
# 
# Based on 'How to reverse spinbox selection in PyQt5?'
# https://stackoverflow.com/questions/62821244/how-to-reverse-spinbox-selection-in-pyqt5
# 'A possible [ed: now verified] solution is to override the stepBy() and stepEnabled() methods:'
# 
# Also based on 'PyQt5 - Creating String Spin Box'
# https://www.geeksforgeeks.org/pyqt5-creating-string-spin-box/

import sys
from PyQt5.QtWidgets import * 
from PyQt5 import QtCore, QtGui
from PyQt5.QtGui import * 
from PyQt5.QtCore import * 

class MyAppWindow( QMainWindow ) :
    
    def __init__( self ) :
        super().__init__()
    
        self.setWindowTitle( 'Creating Reverse String Spin Box ' )
        self.setWindowIcon( QIcon( 'Python_and_Qt.PNG' ) )
        self.resize( 600, 400 )
        self.move( QApplication.desktop().screen().rect().center() - self.rect().center() )
        
        self.UiComponents()
        self.show()
    
    def UiComponents( self ) :
    
        #string_pin_box = StringBox( self )
        string_revSpinBox = ReverseSpinBox( self )
        
        string_revSpinBox.setGeometry( 100, 100, 200, 40 )
    
#end MyAppWindow class

class ReverseSpinBox( QSpinBox ) :
    
    def __init__( self, parent = None ) :
        super( QSpinBox, self ).__init__( parent )
    
        strings = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
    
        # Make the spinbox items strings.
        self.SetStrings( strings )
    
    # Define method SetStrings similarly to the setValue method.
    def SetStrings( self, strings ) :
    
        #strings = list( strings )   # 'strings' is already a list.
    
        self.strings_tuple = tuple( strings )
        
        # A QSpinBox/ReverseSpinBox's items' indices.
        self.setRange( 0, len( strings )-1 )
    
    # Overide the QSpinBox 'textFromValue' method.
    # Maps 'strings' integer indices to its string values.
    def textFromValue( self, int_index ) :
    
        # Returning a string associated to the dictionary's item key value.
        return self.strings_tuple[ int_index ]
    
    # Overide the QSpinBox 'stepEnabled' method.
    def stepEnabled( self ) :
        
        if self.wrapping() or self.isReadOnly() :
            return super().StepEnabled()
        
        spinbox_operation_flags = QAbstractSpinBox.StepNone
        
        # Set according to whether the up or down button has been pushed (?)
        if self.value() >= self.minimum() :
            spinbox_operation_flags |= QAbstractSpinBox.StepUpEnabled
        
        if self.value() <= self.maximum() :
            spinbox_operation_flags |= QAbstractSpinBox.StepDownEnabled
        
        return spinbox_operation_flags
    
    # Overide the QSpinBox 'stepEnabled' method.
    # Reverse the operation of the up and down buttons.
    def stepBy( self, steps ) :
        return super().stepBy( -steps )

#end ReverseSpinBox class

if __name__ == "__main__" :
    
    App = QApplication( sys.argv )
    window = MyAppWindow()
    sys.exit( App.exec() )
Answered By: Hewey Dewey
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.