0

I'm having a QSpinbox inside a QTreeWidget following an approach similar to the approach for a combobox described here https://stackoverflow.com/a/4849010/10220019.

I've read here https://forum.qt.io/topic/103667/qdoublespinbox-why-isn-t-valuechanged-signal-fired-when-content-is-empty/5 that if you use the valueChanged(const QString&)signal this should fire when you backspace from a number to empty. However this is not the case for me. The only difference I can see between that post and my code is that I use a QSpinBox and not a QDoubleSpinBox but that shouldn't be the problem I guess.

I think I might be connecting the signal wrongly because the behavior I get completely matches the behavior I would expect from valueChanged(int). But I wouldn't know how to write the connect then. Does somebody see the error?

My code is: QTreeWidgetItemSpinBox.h

#pragma once

#pragma warning (push)
#pragma warning (disable: 26451 26495 26498 26439)
#include <QtWidgets/QSpinbox>
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QToolTip>
#pragma warning (pop)

class QTreeWidgetItemSpinBox :
    public QSpinBox
{
    Q_OBJECT

public:
    QTreeWidgetItemSpinBox(QTreeWidgetItem* treeItem, int column);

public slots:
    void validateValue(const QString& input);

private:
    QTreeWidgetItem* treeItem;
    int column;
};

QTreeWidgetItemSpinBox.cpp

#include "QTreeWidgetItemSpinBox.h"
#include <QtCore/QDebug>

QTreeWidgetItemSpinBox::QTreeWidgetItemSpinBox(QTreeWidgetItem* treeItem, int column)
    : treeItem(treeItem), column(column)
{
    connect(this, SIGNAL(valueChanged(const QString&)), SLOT(validateValue(const QString&)));
}

void QTreeWidgetItemSpinBox::validateValue(const QString& input)
{
    qDebug() << "Called"; //Is called when changed to another number but not if the change is to empty or if I add zeros before a number
}
C. Binair
  • 419
  • 4
  • 14
  • Try Qt 5 Connection syntax with right signals `connect(this , &QSpinBox::valueChanged , &QTreeWidgetItemSpinBox::validateValue);` – Mohammad Kanan Sep 07 '19 at 13:56
  • Actually it would be `connect(this , QOverload::of(&QSpinBox::valueChanged), &QTreeWidgetItemSpinBox::validateValue);` But it won't make any difference how the connection is made. – Maxim Paperno Sep 07 '19 at 23:40
  • @MaximPaperno "It won't make any difference how the connection is made" so why is there a difference in syntax then? Why would one be preferred over the other? – C. Binair Sep 08 '19 at 14:10
  • https://wiki.qt.io/New_Signal_Slot_Syntax – Maxim Paperno Sep 08 '19 at 14:44

1 Answers1

0

I'm not sure why that Qt forums post says QDoubleSpinBox::valueChanged(const QString &) is emitted when the value is blank because it is not (as of Qt 5.12 anyway). Both versions of the signal are emitted consecutively from the same place in the code. Maybe it was different in a previous version. Same for QSpinBox. I guess the reasoning is that since the value is invalid, it hasn't actually changed (because eg. if you lose focus/finish editing right then, it will auto-revert to the last known good value... so the value hasn't actually changed).

You could instead connect to the QLineEdit (obtained with QAbstractSpinBox::lineEdit()) textChanged() (or textEdited()) signal to get the actual value of the editor.

Maxim Paperno
  • 4,485
  • 2
  • 18
  • 22
  • Could you give me the code for the connect since how I do it I get the error "no such signal" – C. Binair Sep 09 '19 at 08:01
  • Okay the connect was not difficult, but I just didn't say it for some time. For others with the same problem, the connect would look like this: ````QLineEdit* lineEdit = QAbstractSpinBox::lineEdit(); connect(lineEdit, &QLineEdit::textChanged,this, &QTreeWidgetItemSpinBox::validateValue);```` – C. Binair Sep 09 '19 at 11:37