Blocking signal one time in Qt doesn't work correctly



  • Hi i have following code:

    void MainWindow::on_listWidgetNotes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)//Test!
    {
        if(current != NULL)
        {
            ui->plainTextEditContent->setEnabled(true);
            change = false;
            if(isModified)
            {
                auto reply = QMessageBox::question(this, "Test", "Do you want save changes?", QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
                if (reply == QMessageBox::Yes) on_pushButtonSave_clicked();
                else if(reply == QMessageBox::No) notes.closeFile();
                else
                {
                    //ui->listWidgetNotes->blockSignals(true);
                    ui->listWidgetNotes->setCurrentItem(previous);
                    //ui->listWidgetNotes->blockSignals(false);
                    return;
                }
            }
            isModified = false;
            this->setWindowTitle(current->text()+" - VfNotes 1.0");
            ui->plainTextEditContent->setPlainText(notes.openFile(current->text()));
        }
    }
    

    In specified case code have to show message box and set focus on previous item, after select cancel button.

    But setCurrentItem calls on_listWidgetNotes_currentItemChanged again with this message box. After use blockSignals focus doesn't come back on previous element. What to do to set focus on previous item after click cancel, that on_listWidgetNotes_currentItemChanged wasn't call again?


  • Moderators

    @arkadiusz97 said in Blocking signal one time in Qt doesn't work correctly:

    void MainWindow::on_listWidgetNotes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)

    Try disconnecting the currentItemChanged() signal only and then connecting it again.

    Or do it more explicitly: add a boolean member, for example bool ignoreItemChange = false;, then in your slot do this:

    void MainWindow::on_listWidgetNotes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
    {
      if (ignoreItemChange) {
        ignoreItemChange = false;
        return;
      }
    
      // [...]
      else
      {
        ignoreItemChange = true;
        ui->listWidgetNotes->setCurrentItem(previous);
        return;
      }
    }
    


  • @sierdzio I was trying this:

    void MainWindow::on_listWidgetNotes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)//Test!
    {
        if(ignoreItemChange)
        {
            ignoreItemChange = false;
            return;
        }
        if(current != NULL)
        {
            ui->plainTextEditContent->setEnabled(true);
            change = false;
            if(isModified)
            {
                auto reply = QMessageBox::question(this, "Test", "Do you want save changes?", QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
                if (reply == QMessageBox::Yes) on_pushButtonSave_clicked();
                else if(reply == QMessageBox::No) notes.closeFile();
                else
                {
                    //ui->listWidgetNotes->blockSignals(true);
                    ignoreItemChange = true;
                    ui->listWidgetNotes->setCurrentItem(previous);
                    //ui->listWidgetNotes->blockSignals(false);
                    return;
                }
            }
            isModified = false;
            this->setWindowTitle(current->text()+" - VfNotes 1.0");
            ui->plainTextEditContent->setPlainText(notes.openFile(current->text()));
        }
    }
    

    But still focus doesn't come back. ignoreItemChange is set in constructor to false. Disconnecting signal doesn't work too.

    disconnect(ui->listWidgetNotes, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT
    
    (on_listWidgetNotes_currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
                    ui->listWidgetNotes->setCurrentItem(previous);
                    connect(ui->listWidgetNotes, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT
    
    (on_listWidgetNotes_currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
    

  • Qt Champions 2016

    Hi
    wondering if you just want a
    ui->listWidgetNotes->setFocus();
    so the listWidgetNotes get focus back after losing it to the QMessageBox



  • @mrjj Did you mean it?

           else
            {
                //ui->listWidgetNotes->blockSignals(true);
                //ui->listWidgetNotes->setCurrentItem(previous);
                ui->listWidgetNotes->setFocus();
                //ui->listWidgetNotes->blockSignals(false);
                return;
            }
    

    I was trying this and focus doesn't come back on previous element too. BTW. Here is full code of project with this problem: https://github.com/arkadiusz97/VfNotes


  • Qt Champions 2016

    @arkadiusz97
    Hi
    Together with
    ui->listWidgetNotes->setCurrentItem(previous);
    ui->listWidgetNotes->setFocus();

    But after reading again, it sounds like the previous are not being selected ?
    Current still is ?



  • @mrjj Using ui->listWidgetNotes->setFocus(); has no effects. Now, i used it both with ui->listWidgetNotes->setCurrentItem(previous);. I was testing on blocked signals and without blocking signals.



  • This solution was helpful: https://4programmers.net/Forum/C_i_C++/302329-qt5_problem_z_jednorazowa_blokada_sygnalu?p=1437140#id1437140

    void MainWindow::on_listWidgetNotes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
    {
        ...
        else
        {
            QTimer::singleShot(0, qApp, [this, previous]
            {
                ui->listWidgetNotes->blockSignals(true);
                ui->listWidgetNotes->setCurrentItem(previous);
                ui->listWidgetNotes->blockSignals(false);
            });
            return;
        }
        ...
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.