QLineEdit编辑更改焦点时两次完成信号?

Tob*_*oby 5 c++ qt qlineedit qt-signals qt-slot

我发现了一些类似的问题,但这些问题似乎是指在插槽处理程序中使用消息框的情况。就我而言,我有点卡住,因为即使我的插槽处理程序什么也不做,但我两次都收到了editFinished信号。

为了进行测试,我有一个QLineEdit数组,该数组使用signalMapper将editFinished()信号连接到单个插槽。signalMapper传递数组索引,这样我就可以看到信号的来源。例如:

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
}
Run Code Online (Sandbox Code Playgroud)

在调试器中运行时,如果我在一个框中输入数据,然后按回车键或用鼠标选择另一个框(即更改焦点),则它将调用data_entry两次,第一次是丢失焦点的框的索引,第二次用获得焦点的盒子。

所以我的问题是:我缺少什么吗?这是预期的行为还是错误?如果有错误,任何人都知道如何解决,因为我想在输入数据时使用此信号对数据进行自定义验证(通过返回,制表符或鼠标单击以更改焦点)。

Lig*_*art 4

首先,不,这不是预期的行为,即选择 aQLineEdit不应导致其editingFinished信号被发射。

有几种可能导致此问题的原因:

  • 您不小心将一个信号两次连接到一个插槽
  • 该插槽map()导致新选择的框失去焦点
  • 同样,如果您正在调试并使用断点来检测插槽何时被调用,则QLineEdit当活动应用程序从您的调试器更改QWidget为调试器时,您可能会导致失去焦点,再次导致信号再次发送。

如果您由于双重连接插槽而遇到问题,但情况似乎并非如此,因为您专门从两个不同的QLineEdit插槽获取信号,则可以通过指定连接类型来确保不会发生这种情况,该connect方法实际上在末尾有一个额外的可选参数,它允许您将类型从 a 更改DefaultConnection为 a UniqueConnection

话虽这么说,数据验证是 Qt 已建立的机制,我建议您如果可能的话使用它,并考虑扩展QValidator抽象基类Ref Doc。然后你告诉你们每个QLineEdit人都使用相同的validator