2014-11-06 157 views
4

我发现了一些类似的问题,但这些似乎指的是在插槽处理程序中使用消息框的情况。在我的情况下,我有点卡住,因为即使我的插槽处理程序没有任何操作,我也会得到两次editFinished信号。Qt:改变焦点时QLineEdit编辑完成信号两次?

对于测试,我有一个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两次,第一次用失去焦点的盒子的索引以及获得焦点的盒子的第二次。

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

+0

托比,Qt的信号插槽机制可以是一个有趣的野兽来搏斗。你遇到这种行为的条件是什么? (一世。e在一个带有中断点的调试器中,运行时没有进行调试并且出现了两次结果) – Lightheart 2014-11-06 18:18:38

回答

2

首先,这不是预期的行为,即选择一个QLineEdit不应该导致它的编辑结束信号被发射。

有几个可能的事情,可能会导致此问题:

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

如果由于双重连接的插槽而出现问题,似乎并非如此,因为您专门从两个不同的QLineEdit获取信号,可以确保这不是通过指定连接类型发生,connect方法实际上在最后有一个附加的可选参数,它允许您将类型从DefaultConnection更改为UniqueConnection。这就是说,数据验证是Qt已经建立的机制,我建议你尽可能使用它,考虑扩展QValidator抽象基类Ref Doc。然后你告诉你的每个QLineEdit使用同一个验证器。

+0

我又玩了一次,看起来你的第三个选项是问题。即。调试器正在引起焦点更改。 qDebug()<<“index”<< entry; 工作得很好。即每个焦点只有一个输出变化。 我确实发现了QValidator函数,但想在继续之前了解这种行为。感谢所有的信息! – Toby 2014-11-07 06:17:27

0

我遇到了同样的问题。它真的发出信号两次,这是一个已知的错误: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