要实现修改日期,当不是指定条件时(今天),报错,并将其值设置有效(今天),代码如下
connect(ui->dateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(date1(QDate)));
void TestUI::date1(const QDate & date)
{
if (date != QDate::currentDate())
{
ui->dateEdit->blockSignals(true);
QMessageBox::warning(this, "a", QString::number(b));
ui->dateEdit->setDate(QDate::currentDate());
ui->dateEdit->blockSignals(false);
}
}
结果:当不满足条件时,弹出框弹了2次。
跟踪代码:
void QAbstractSpinBoxPrivate::setValue(const QVariant &val, EmitPolicy ep,
bool doUpdate)
{
Q_Q(QAbstractSpinBox);
const QVariant old = value;
value = bound(val);
pendingEmit = false;
cleared = false;
if (doUpdate) {
updateEdit();
}
q->update();
if (ep == AlwaysEmit || (ep == EmitIfChanged && old != value)) {
emitSignals(ep, old);
}
}
在updateEdit();(设置新值)之后又执行了emitSignals(ep, old); 这里再次发送了信号
void QDateTimeEditPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
{
Q_Q(QDateTimeEdit);
if (ep == NeverEmit) {
return;
}
pendingEmit = false;
const bool dodate = value.toDate().isValid() && (sections & DateSectionMask);
const bool datechanged = (ep == AlwaysEmit || old.toDate() != value.toDate());
const bool dotime = value.toTime().isValid() && (sections & TimeSectionMask);
const bool timechanged = (ep == AlwaysEmit || old.toTime() != value.toTime());
updateCache(value, displayText());
syncCalendarWidget();
if (datechanged || timechanged)
emit q->dateTimeChanged(value.toDateTime());
if (dodate && datechanged)
emit q->dateChanged(value.toDate());
if (dotime && timechanged)
emit q->timeChanged(value.toTime());
}
很可能是这里让其再执行槽函数。
官方也给出了这个bug:
http://bugreports.qt.nokia.com/browse/QTBUG-10220解决办法
1 修改QDateTimeEditPrivate::emitSignals,使其不发送信号。(未做测试)
2 修改我的代码,加个变量判断其状态,只有在第一次执行槽函数时做弹出框,代码如下:
void TestUI::date1(const QDate & date)
{
ui->dateEdit->blockSignals(true);
if (b)
{
QMessageBox::warning(this, "a", QString::number(b));
ui->dateEdit->setDate(QDate::currentDate());
b = false;
}
else
{
ui->dateEdit->setDate(QDate::currentDate());
b = true;
}
ui->dateEdit->blockSignals(false);
}
注意:2个分支里都要重新设置日期!