槽和信号无限循环

3

我写了一个包含年/月/日的旋转框的日期转换器,希望当我更改日期时,同时其他日期也会相应地转换,反之亦然。

所以我做了以下操作:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("Shamsi/Miladi Converter");
    setFixedSize(400, 165);

    connect(ui->shy,SIGNAL(valueChanged(int)),this,SLOT(MiladiSet()));
    connect(ui->shm,SIGNAL(valueChanged(int)),this,SLOT(MiladiSet()));
    connect(ui->shd,SIGNAL(valueChanged(int)),this,SLOT(MiladiSet()));

    connect(ui->ghy,SIGNAL(valueChanged(int)),this,SLOT(ShamsiSet()));
    connect(ui->ghm,SIGNAL(valueChanged(int)),this,SLOT(ShamsiSet()));
    connect(ui->ghd,SIGNAL(valueChanged(int)),this,SLOT(ShamsiSet()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ShamsiSet()
{
    int inputYear = ui->ghy->text().toInt();
    int inputMonth = ui->ghm->text().toInt();
    int inputDay = ui->ghd->text().toInt();

    int year = inputYear - 1;
    int month = inputMonth - 1;
    int day;

    int temp = 0;

    int nonKabise[12] = {0,31,29,31,30,31,30,31,31,30,31,30};
    int kabise[12] = {0,31,28,31,30,31,30,31,31,30,31,30};

    if(year%4 == 0)
    {
        for(int i=0; i <= month; ++i)
        {
            temp += kabise[i];
        }
        day = (year*365.25)+temp+inputDay;

    }
    else
    {
        for(int i=0; i <= month; ++i)
        {
            temp += nonKabise[i];
        }
        day = (year*365.25)+temp+inputDay;
    }

    day -= 226899;

    year = (day/365.25)+1;
    temp = day/365.25;

    day = day - (temp*365.25) + 0.25;

    if      (year%4==3) day=day+1;
    if      (day>336) month=12,day=day-336;
    else  if(day>306) month=11 ,day=day-306;
    else  if(day>276) month=10 ,day=day-276;
    else  if(day>246) month=9 ,day=day-246;
    else  if(day>216) month=8 ,day=day-216;
    else  if(day>186) month=7 ,day=day-186;
    else  if(day>155) month=6 ,day=day-155;
    else  if(day>124) month=5 ,day=day-124;
    else  if(day>93) month=4 ,day=day-93;
    else  if(day>62) month=3 ,day=day-62;
    else  if(day>31) month=2 ,day=day-31;
    else  if(day>0) month=1,day=day;
    else  if(day==0){
    if(year%4!=0)year=year-1,month=12,day=29;
    else year=year-1,month=12,day=30;
    }

    ui->shy->setValue(year);
    ui->shm->setValue(month);
    ui->shd->setValue(day);
}

void MainWindow::MiladiSet()
{
    int inputYear = ui->shy->text().toInt();
    int inputMonth = ui->shm->text().toInt();
    int inputDay = ui->shd->text().toInt();

    int year = inputYear - 1;
    int month = inputMonth - 1;
    int day = inputDay;

    int temp = 0;

    if(month <= 6)
    {
       day = (year * 365.25) + (month * 31) + day + 0.25;
    }
    else
    {
        day = (year *365.25) + (month-6)*30 + 186 + day + 0.25;
    }
    day += 226899;

    year = (day/365.25) + 1;
    temp = (day/365.25);
    temp *= 365.25;

    day -= temp;

    if(year%4==0){
    if(day==0) year-=1,month=12,day=31;
    if(day<=31) month=1;
    else if(day<=60) month=2, day-=31;
    else if(day<=91) month=3, day-=60;
    else if(day<=121) month=4, day-=91;
    else if(day<=152) month=5, day-=121;
    else if(day<=182) month=6, day-=152;
    else if(day<=213) month=7, day-=182;
    else if(day<=244) month=8, day-=213;
    else if(day<=274) month=9, day-=244;
    else if(day<=305) month=10, day-=274;
    else if(day<=335) month=11, day-=305;
    else if(day<=366) month=12, day-=335;
    }

    else{

    if(day==0) year-=1,month=12,day=31;
    else if(day<=31) month=1;
    else if(day<=59) month=2, day-=31;
    else if(day<=90) month=3, day-=59;
    else if(day<=120) month=4, day-=90;
    else if(day<=151) month=5, day-=120;
    else if(day<=181) month=6, day-=151;
    else if(day<=212) month=7, day-=181;
    else if(day<=243) month=8, day-=212;
    else if(day<=273) month=9, day-=243;
    else if(day<=304) month=10, day-=273;
    else if(day<=334) month=11, day-=304;
    else if(day<366) month=12, day-=334;
    else if(day=366) year+=1,month=1 , day=1;
    }

    ui->ghy->setValue(year);
    ui->ghm->setValue(month);
    ui->ghd->setValue(day);
}

但是,如果我改变第一个条件,我的代码会进入无限循环并导致崩溃。 请帮我解决这个问题。
1个回答

6
你可以使用 QObject::blockSignals 停止递归:
ui->ghy->blockSignals(true);
ui->ghy->setValue(year);
ui->ghy->blockSignals(false);
// and similarly for other spinboxes

2
当您调用setValue而不阻塞信号时,Qt会递归地调用一个信号并调用连接的插槽。如果由同一插槽调用setValue,则会导致无限递归。当您调用blockSignals(true)时,对象停止发送信号,setValue将不会导致调用连接的插槽。blockSignals(false)调用重新启用发送信号。 - Pavel Strakhov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接