YOGYUI

PyQt5 - QSpinBox 0x7FFFFFFFF 이상 최대값으로 설정하기 본문

Software/Python

PyQt5 - QSpinBox 0x7FFFFFFFF 이상 최대값으로 설정하기

요겨 2022. 2. 8. 11:06
반응형

PyQt5 - Set maximum value over 0x7FFFFFFFF of Spin Box

 

PyQt5의 QSpinBox는 4바이트 부호 있는 정수 (singed integer)를 표현할 수 있다

(자세히 알아보지는 않았는데, QSpinBox 내부 QLineEdit의 validator가 Qt에서 제공하는 default QIntValidator인듯?)

from PyQt5.QtWidgets import *

app = QApplication([])
spinbox = QSpinBox()
lineedit = spinbox.lineEdit()
validator = lineedit.validator()
print(validator)
In [1]: print(validator)
Out[1]: <PyQt5.QtGui.QValidator object at 0x0000026604C06C18>

(그냥 QValidator인 것 같긴 하지만... 사실 잘 모르겠다)

 

결국 정수형 QSpinBox의 설정 가능한 최대 범위는 -2,147,483,648 ~ 2,147,483,647 (0x80000000 ~ 0x7FFFFFFFF)이 된다 

이 사실은 QIntValidator로도 확인 가능하다

from PyQt5.QtGui import QIntValidator

validator = QIntValidator()
In [2]: print(validator.top())
Out[2]: 2147483647
In [3]: print(validator.bottom())
Out[3]: -2147483648

 

만약 0x7FFFFFFF 이상의 값을 최대값으로 설정하고자 할 경우 OverflowError 예외가 발생한다

from PyQt5.QtWidgets import *

app = QApplication([])
spinbox = QSpinBox()
spinbox.show()
spinbox.setRange(0, 0xFFFFFFFF)
spinbox.setValue(spinbox.maximum())
print(spinbox.value())
app.exec_()
Traceback (most recent call last):
  File "./test.py", line 6, in <module>
    spinbox.setRange(0, 0xFFFFFFFF)
OverflowError: argument 2 overflowed: value must be in the range -2147483648 to 2147483647

해결책

Qt에 익숙하다면 QAbstractSpinBox를 상속해서 QLineEdit의 validator를 커스터마이즈해서 구현해도 되지만, 정말 간단하게 구현하고자 한다면 단순히 QDoubleSpinBox를 상속해서 다음과 같이 구현해도 된다

class BigIntSpinBox(QDoubleSpinBox):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setDecimals(0)
        self.setSingleStep(1)

    def value(self) -> int:
        return int(super().value())

setDecimals을 통해 소수점 아래 자리수를 0으로 만들고, value 메서드를 상속해 정수형 값을 반환하도록 만들어준다

if __name__ == '__main__':
    app = QApplication([])
    spinbox = BigIntSpinBox()
    spinbox.show()
    spinbox.setRange(0, 0xFFFFFFFF)
    spinbox.setValue(spinbox.maximum())
    print(spinbox.value())
    app.exec_()

[실행 결과]

만약 정수형 관련 동작이 필요하다면 필요한 메서드를 상속해서 구현하면 된다 (setRange 인자를 정수형으로 제한한다던가 등등)

 

이제 시스템에서 표현 가능한 최대값만큼 표현할 수 있는데, 이는 sys 패키지를 통해 확인할 수 있다

import sys

print(sys.maxsize)
9223372036854775807

위 값은 0x7FFFFFFFFFFFFFFF 로, 부호있는 8바이트(64비트) 정수의 최대값이다

(64비트 운영체제에서 호출 시)

요샌 32비트 운영체제를 구하기 힘들어서 테스트해보지는 못했다

 

굉장히 초급수준의 해결책이긴 하지만, 무리없이 필요한 기능을 구현할 수 있는 방법!

(Qt에 익숙하지 않은 사람도 쉽게 알아볼 수 있는 가독성 좋은 코드를 짤 수 있다)

 

[참고]

https://stackoverflow.com/questions/15654769/how-to-subclass-qspinbox-so-it-could-have-int64-values-as-maxium-and-minimum

반응형