andreas
andreas

Reputation: 101

How to user input an infinity value to a QDoubleSpinBox?

I'm trying to set up a QDoubleSpinBox in Python 3.7 with PyQt5, that can take a range of values from -np.inf to np.inf. I would also like the user to set the values to either of those, -np.inf or np.inf. How would I/the user do that?

After adjusting the minimum and maximum of the QDoubleSpinBox it is possible to set the value in code and either "-inf" or "inf" shows up in the displayed box.

from PyQt5.QtWidgets import QDoubleSpinBox

[...]

dsbTest = QDoubleSpinBox()

# first set the desired range 
dsbTest.setRange(-np.inf, np.inf)

# set the value to positive infinity, successfully
dsbTest.setValue(np.inf)

However, after changing it to any other value, let's say 5, I find myself unable to enter "-inf" or "inf" back into the GUI.

When I type "i" or "inf", no input is taken, by which I mean, the displayed current value does not change from 5.

Upvotes: 4

Views: 1773

Answers (2)

user8234870
user8234870

Reputation:

float("inf") or float("INF") or float("Inf") or float("inF") or float("infinity") creates a float object holding infinity

float("-inf") or float("-INF") or float("-Inf") or float("-infinity") creates a float object holding negative infinity

We can set -infinity as the minimum value and +infinity as maximum value to a QDoubleSpinBox

box = QDoubleSpinBox()
box.setMinimum(float("-inf"))
box.setMaximum(float("inf"))

Source:

import sys

from PySide6.QtWidgets import QMainWindow, QApplication, QDoubleSpinBox, QWidget, QFormLayout, QLineEdit, QPushButton


def getDoubleSpinBox() -> QDoubleSpinBox:
    box = QDoubleSpinBox()
    box.setPrefix("₹")
    box.setMinimum(float("-inf"))
    box.setMaximum(float("inf"))
    box.setSingleStep(0.05)
    box.setValue(25_000)
    return box


def getLineEdit(placehoder: str, password: bool = False):
    lineEdit = QLineEdit()
    lineEdit.setPlaceholderText(placehoder)
    if password:
        lineEdit.setEchoMode(QLineEdit.Password)
    return lineEdit


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Open Bank")
        self.widget = QWidget()
        self.widgetLayout = QFormLayout()
        self.widgetLayout.addRow("ID", getLineEdit(placehoder="Investor name"))
        self.widgetLayout.addRow("Investment", getDoubleSpinBox())
        self.widgetLayout.addRow("Password", getLineEdit(placehoder="Enter secret password", password=True))
        self.widgetLayout.addRow(QPushButton("Invest"), QPushButton("Cancel"))
        self.widget.setLayout(self.widgetLayout)
        self.setCentralWidget(self.widget)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

Window:

Open Bank

Upvotes: 0

andreas
andreas

Reputation: 101

I ended up doing it like this, making a subclass.

class InftyDoubleSpinBox(QDoubleSpinBox):

    def __init__(self):
        super(QDoubleSpinBox, self).__init__()

        self.setMinimum(-np.inf)
        self.setMaximum(np.inf)

    def keyPressEvent(self, e: QtGui.QKeyEvent):

        if e.key() == QtCore.Qt.Key_Home:
            self.setValue(self.maximum())
        elif e.key() == QtCore.Qt.Key_End:
            self.setValue(self.minimum())
        else:
            super(QDoubleSpinBox, self).keyPressEvent(e)

I set minimum and maximum at the beginning to -np.inf, np.inf. In the keyPressEvent Home and End Buttons will be caught, to set the value to minimum or maximum.

For any other key, the QDoubleSpinBox will react as usual, as the base function is called.

This also works for other assigned min/max values after init() is called. Which was desirable for my case.

Upvotes: 6

Related Questions