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

Recommended Answers

All 2 Replies

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_()

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

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.