首页 文章

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

提问于
浏览
4

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

对于测试,我有一个QLineEdit数组,它使用signalMapper将editingFinished()信号连接到一个插槽 . 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
}

当在调试器中运行时,如果我将数据输入到一个框中,然后点击返回或用鼠标选择另一个框(即更改焦点),然后它调用data_entry两次,第一次使用失去焦点的框的索引和第二次使用获得焦点的盒子 .

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

2 回答

  • 3

    我遇到了同样的问题 . 它确实发出两次信号,这是一个已知的错误:https://bugreports.qt.io/browse/QTBUG-40然而很长一段时间没有得到解决 .

    最后我发现在我的情况下,最好的解决方案是将信号从 editingFinished 更改为 returnPressed . 作为副作用,从用户角度来看,这可以更加可预测地发挥作用 . 另见:http://www.qtforum.org/article/33631/qlineedit-the-signal-editingfinished-is-emitted-twice.html?s=35f85b5f8ea45c828c73b2619f5750ba9c686190#post109943

  • 0

    首先,没有这不是预期的行为,即选择 QLineEdit 不应该导致它的 editingFinished 信号被发射 .

    有几种可能导致此问题的事情:

    • 您不小心将信号两次连接到插槽

    • 插槽 map() 导致新选择的框失去焦点

    • 同样徒劳无功,如果您正在调试并使用断点来检测插槽何时被调用,则当活动应用程序从 QWidget 更改为调试器时,可能会导致 QLineEdit 失去焦点,再次导致信号变为再发一次 .

    如果你似乎是因为你专门从两个不同的 QLineEdit 获取信号,你可以通过指定连接类型来确保没有发生这种情况, connect 方法实际上有一个额外的可选参数结束,它允许您将类型从 DefaultConnection 更改为 UniqueConnection .

    话虽这么说,数据验证是Qt已经 Build 的机制,我建议你尽可能使用它,看看扩展 QValidator 抽象基类Ref Doc . 然后你告诉每个 QLineEdit 使用相同的 validator .

相关问题