c++qtqlineeditqt-signalsqt-slot

QLineEdit editingFinished signal twice when changing focus?


I've found a few similar questions on this but these appear to refer to cases where a message box is used in the slot handler. In my case I am a bit stuck as I am getting the editFinished signal twice even when my slot handler is doing nothing.

For a test, I have an array of QLineEdit which use a signalMapper to connect the editingFinished() signals to a single slot. The signalMapper passes the array index so I can see where the signal came from. eg:

testenter::testenter(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::testenter)
{
    // setup the UI according to the .h file
    ui->setupUi(this);

    signalMapper = new QSignalMapper(this);

    // init the labels and edit boxes
    for (int i = 0; i < 10; i++)
    {
        pm_label[i] = new QLabel(ui->scrollArea);
        QString text = QString("Number %1").arg(i);
        pm_label[i]->setText(text);
        pm_label[i]->setGeometry(10,20+i*30, 50, 20);
        pm_label[i]->show();

        pm_editBox[i] = new QLineEdit(ui->scrollArea);
        pm_editBox[i]->setGeometry(80,20+i*30, 50, 20);
        pm_editBox[i]->show();

        signalMapper->setMapping(pm_editBox[i], int(i));
        connect(pm_editBox[i], SIGNAL(editingFinished()), signalMapper, SLOT(map()));
    }
    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(data_entry(int)));
}

void testenter::data_entry(int entry)
{
    //dummy
}

When run in the debugger, if I enter data into one box then either hit return or select another box with the mouse (ie change focus) , then it calls data_entry twice, the first time with index of the box that is losing focus and the 2nd time with the box which gets the focus.

So my question: Am I missing something? Is this expected behaviour or a bug? If a bug, anyone know a way round it as I wanted to use this signal to do custom validation on data when it is entered (by either return, tab or mouse click to change focus).


Solution

  • First off, no this isn't expected behavior, i.e. selecting a QLineEdit should not cause it's editingFinished signal to be emitted.

    There are a couple of possible things that may cause this problem:

    If you're having problems because of a doubly connected slot, which doesn't seem to be the case because you're specifically getting a signal from two different QLineEdits, you can make sure that this isn't happening by specifying the connection type, the connect method actually has an additional optional argument at the end which allows you to change the type from a DefaultConnection to a UniqueConnection.

    That being said, data validation is something that Qt has an established mechanism for, and I suggest that you use it if possible, look into extending the QValidator abstract base class Ref Doc. You then tell each of your QLineEdit's to use the same validator.