Reputation: 214
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.
Upvotes: 2
Views: 278
Reputation: 843
Based on @eyllanesc answer, but ported to PyQt6 (also works on PyQt5).
Create your own class that overrides the original QSpinBox. Override the stepBy()
and stepEnabled()
methods:
import sys
from PyQt6 import QtWidgets
class ReverseSpinBox(QtWidgets.QSpinBox):
def stepEnabled(self):
if self.wrapping() or self.isReadOnly():
return super().stepEnabled()
ret = QtWidgets.QAbstractSpinBox.StepEnabledFlag.StepNone
if self.value() > self.minimum():
ret |= QtWidgets.QAbstractSpinBox.StepEnabledFlag.StepUpEnabled
if self.value() < self.maximum():
ret |= QtWidgets.QAbstractSpinBox.StepEnabledFlag.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())
It differs from the @eyllanesc code by fully qualified enums, and removing underscore in app.exec()
.
Upvotes: 0
Reputation: 149
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() )
Upvotes: 0
Reputation: 243897
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_())
Upvotes: 2