Hi!

I have a program with two QSpinBoxes with integers in them. When user clicks one spinbox it should affect to the other one. And vice versa. I can't use valueChanged() signal because it causes an endless loop that won't stop until the maximum values of the boxes have been reached. I don't the want computer to run valueChanged() when the value changes as the result of clicking another spinbox.

So basically the problem is how can I handle a mouse click event with spinboxes? Tried to search solutions but couldn't find clear ones enough.


Thanks,

Lasse

Not quite sure why you want to synchronize the two spinboxes, but here is one way (with the option to synchronize just to one spinbox) ...

# pqt_spinbox_LCD2.py
# create a PyQt form with 2 spinboxes and 2 LCD readouts
# sychronize the 2 spinboxes
# vegaseat

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class SigSlot(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle('spinbox value')
        self.resize(250,150)

        self.lcd1 = QLCDNumber(self)
        self.lcd2 = QLCDNumber(self)
        # by default range is 0-99 and starts at 0
        self.spinbox1 = QSpinBox(self)
        self.spinbox2 = QSpinBox(self)

        # create a Grid Layout
        grid = QGridLayout()
        # addWidget(QWidget, row, column, rowSpan, columnSpan)
        grid.addWidget(self.lcd1, 0, 0)
        grid.addWidget(self.lcd2, 0, 1)
        grid.addWidget(self.spinbox1, 1, 0)
        grid.addWidget(self.spinbox2, 1, 1)
        self.setLayout(grid)

        # allows access to the spinbox value as it changes
        self.connect(self.spinbox1, SIGNAL('valueChanged(int)'),
            self.change_value1)
        self.connect(self.spinbox2, SIGNAL('valueChanged(int)'),
            self.change_value2)

    def change_value1(self, event):
        """show the changing spinbox1 value in the LCD display"""
        val = self.spinbox1.value()
        if val != self.spinbox2.value(): self.spinbox2.setValue(val)
        # display in the LCD widget
        self.lcd1.display(val)

    def change_value2(self, event):
        """show the changing spinbox2 value in the LCD display"""
        val = self.spinbox2.value()
        # comment out the next line if you want to synchronize
        # to one spinbox only
        if val != self.spinbox1.value(): self.spinbox1.setValue(val)
        # display in the LCD widget
        self.lcd2.display(val)


app = QApplication([])
qb = SigSlot()
qb.show()
app.exec_()

Edited 6 Years Ago by vegaseat: option

Hi!
I have a program with two QSpinBoxes with integers in them. When user clicks one spinbox it should affect to the other one. And vice versa. I can't use valueChanged() signal because it causes an endless loop that won't stop until the maximum values of the boxes have been reached.

Yes, you can. I had a similar problem - two QDoubleSpinBoxes that need to be synchronized in dependence of a certain QCheckBox's check state - and was able to avoid an endless loop by disconnecting the valueChanged()-SIGNAL before updating the spinbox. It looks something like that:

self.sp1 = QDoubleSpinBox()
self.sp2 = QDoubleSpinBox()
self.sync_cb = QCheckBox(self.tr(u"Synchronize spinboxes")

QObject.connect(self.sp1, SIGNAL("valueChanged(double)"), self.sync_spinbox)
QObject.connect(self.sp2, SIGNAL("valueChanged(double)"), self.sync_spinbox)

def sync_spinbox(self, new_value):
  sender = QObject.sender(self)
  if self.sync_cb.checkState() == Qt.Checked:
    if sender == sp1:
      QObject.disconnect(self.sp2, SIGNAL("valueChanged(double)"), self.sync_spinbox)
      self.sp2.setValue(new_value)
      QObject.connect(self.sp2, SIGNAL("valueChanged(double)"), self.sync_spinbox)
    elif sender == sp2:
      QObject.disconnect(self.sp1, SIGNAL("valueChanged(double)"), self.sync_spinbox)
      self.sp1.setValue(new_value)
      QObject.connect(self.sp1, SIGNAL("valueChanged(double)"), self.sync_spinbox)

Most likely that's not a very elegant solution, but it works nonetheless.

Regards,
Markus

This question has already been answered. Start a new discussion instead.