sdbbs
sdbbs

Reputation: 5384

QSpinBox with editingFinished signal in PyQt5?

When I use valueChanged signal for QSpinBox, it reacts both when I click on the arrows, and when I type any character in the text field of the QSpinBox.

I would like to have a editingFinishedsignal for QSpinBox, so it reacts only on Enter or Tab, when I change values in the spinbox textfield.

Apparently, this used to be a possibility, according to these links:

Unfortunately, when I use this code:

self.spinbox.editingFinished.connect(self.on_spinbox_change_value)

... I get:

...
  File "test/test.py", line 63, in __init__
    self.spinbox.editingFinished.connect(self.on_spinbox_change_value)
TypeError: decorated slot has no signature compatible with editingFinished()

So, apparently, this is not a possibility anymore in PyQt5? Is there a workaround I could use instead?


EDIT: A minimal reproducible example:

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

class Example(QWidget):
  def __init__(self):
    super(Example, self).__init__()
    self.initUI()

  def initUI(self):

    self.slider_hbox = QHBoxLayout()

    self.tspinbox = QSpinBox()
    self.tspinbox.setMinimumSize(1,1)
    self.tspinbox.setMaximum(100)

    #self.tspinbox.valueChanged.connect(self.on_tspinbox_change) # works, but reacts on every new character typed in textbox of spinbox
    self.tspinbox.editingFinished.connect(self.on_tspinbox_change) # TypeError: decorated slot has no signature compatible with editingFinished()

    self.slider_hbox.addWidget(self.tspinbox, 1)

    self.setLayout(self.slider_hbox)

    self.setGeometry(300, 300, 220, 170)
    self.setWindowTitle('Tester')
    self.show()

  @pyqtSlot(int)
  def on_tspinbox_change(self, value):
    print("on_tspinbox_change {}".format(value))


if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = Example()
  sys.exit(app.exec_())

Upvotes: 1

Views: 1725

Answers (1)

sdbbs
sdbbs

Reputation: 5384

Actually, turns out it works - I just made a mistake copy-pasting @pyqtSlot(int) - it should have just been @pyqtSlot() (and respectively, just def on_tspinbox_change(self):); here is the corrected code that works:


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

class Example(QWidget):
  def __init__(self):
    super(Example, self).__init__()
    self.initUI()

  def initUI(self):

    self.slider_hbox = QHBoxLayout()

    self.tspinbox = QSpinBox()
    self.tspinbox.setMinimumSize(1,1)
    self.tspinbox.setMaximum(100)

    #self.tspinbox.valueChanged.connect(self.on_tspinbox_change) # works, but reacts on every new character typed in textbox of spinbox
    self.tspinbox.editingFinished.connect(self.on_tspinbox_change) # works now, if not using int argument (so @pyqtSlot(), instead of @pyqtSlot(int), etc)

    self.slider_hbox.addWidget(self.tspinbox, 1)

    self.setLayout(self.slider_hbox)

    self.setGeometry(300, 300, 220, 170)
    self.setWindowTitle('Tester')
    self.show()

  @pyqtSlot()
  def on_tspinbox_change(self):
    print("on_tspinbox_change {}".format( self.tspinbox.value() ))


if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = Example()
  sys.exit(app.exec_())

Now you will have a printout only when you press Enter, after you type in the spinbox textfield - and not on every keypress in the textfield of the spinbox ...

Upvotes: 3

Related Questions