Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Check state QListWidget



  • Hello guys.

    I have created some checkboxes but this is inelastic more. So I created QListWidget with flags

     QListWidgetItem* item = 0;
    
           for(int i = 0; i < ui->listWidget->count(); ++i){
               item = ui->listWidget->item(i);
               item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
               item->setCheckState(Qt::Unchecked);
               item->setTextAlignment(Qt::AlignCenter);
           }
    

    but I don't know how I can check isChecked() for created items.
    I tried this:

           if(item->checkState() == Qt::Checked)
           {
               qDebug() << "test";
               Euro+=100;
           }
    

    but is happing nothing.



  • @naax said in Check state QListWidget:

    ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable;

    I typed exactly what you want:

    Task->setFlags(Task->flags() & ~Qt::ItemIsUserCheckable);
    

    Apply that to your ui->listWidget->item(0) if that is what you want to do (I doubt that is right, why would you want to apply to specifically/only item(0)?).



  • @naax
    Where do you do this? What is item pointing to? Have you checked the item before you call it?



  • void MainWindow::ListWidgetSettings()
    {
        QListWidgetItem* item = 0;
    
           for(int i = 0; i < ui->listWidget->count(); ++i){
               item = ui->listWidget->item(i);
               item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
               item->setCheckState(Qt::Unchecked);
               item->setTextAlignment(Qt::AlignCenter);
    
    
               if((item)->checkState() == Qt::Checked)
               {
                   qDebug() << "test";
                   Euro+=100;
               }
           }
    }
    

  • Lifetime Qt Champion

    And why should return item->checkState() Qt::Checked when you set it to Qt::Unchecked two lines before?



  • @Christian-Ehrlicher

    I used it for new items. If I create a new item should be unchecked first.


  • Lifetime Qt Champion

    @naax This does not answer my question.



  • @Christian-Ehrlicher

    All items are unchecked. After "check" I want to do something like with normal checkboxes.

    if (item.isChecked()) 
    {
    //code
    }
    

    I used this:

    item->checkState() Qt::Checked
    

    because I don't know how I can do it right


  • Lifetime Qt Champion

    @naax said in Check state QListWidget:

    After "check" I want to do something like with normal checkboxes.

    Then write a function which is called when you e.g. press on a 'Save' button or something else and read out the states.


  • Lifetime Qt Champion

    Hi,

    Connect a slot to the QListWidget::itemChanged signal and act there.



  • @SGaist

    Can you show me how I can do it?


  • Lifetime Qt Champion

    connect(ui->listWidget, &QListWidget::itemChanged, this, &MainWindow::onItemChanged);
    

    Add the corresponding slot to your MainWindow class and do whatever you need in there.



  • @SGaist said in Check state QListWidget:

    void MainWindow::ListWidgetSettings()
    {
    
           for(int i = 0; i < ui->listWidget->count(); ++i){
               Task = ui->listWidget->item(i);
               Task->setFlags(Task->flags() | Qt::ItemIsUserCheckable);
               Task->setCheckState(Qt::PartiallyChecked);
               Task->setTextAlignment(Qt::AlignCenter);       
           }
    }
    
    void MainWindow::highlightChecked(QListWidgetItem *Task)
    {
        if(Task->checkState() == Qt::Checked)
        {
            qDebug() << "Checked";
            Euro+=100;
            UpdateData();
        }
           else
               qDebug() << " Else";
    }
    
    void MainWindow::createConnections()
    {
        connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
                             this, SLOT(highlightChecked(QListWidgetItem*)));
    }
    

    Its works, but only for the last item in my QListWidget


  • Lifetime Qt Champion

    What does UpdateData() do ?



  • @SGaist

    This function update "Euro" label.

       QString str;
        ui->ShowTotalEuro->setText(str.asprintf("%.1f", Euro));
    


  • @naax said in Check state QListWidget:

    Its works, but only for the last item in my QListWidget

    This should not be the case. How do you know it is?



  • @JonB @SGaist

    Ok, guys, I got this.

    I forget change it :

    //connect(ui->listWidget, &QListWidget::itemChanged, this, &MainWindow::on_pushButton_clicked);
    

    into this

    
        connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
                             this, SLOT(highlightChecked(QListWidgetItem*)));
    

    Do you know how I can "block" Task? I mean if I set one task to "checked" and after this, I cant uncheck this?
    Before when I used normal QCheckbox I used "setEnabled(false), but here I can't do it or I just don't know-how.



  • @naax said in Check state QListWidget:
    setEnabled(false) disables a checkbox. Since you used item->setFlags(item->flags() | Qt::ItemIsUserCheckable); to allow user to check/uncheck the checkbox here, I imagine you need item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);?



  • @JonB

    if I use this, I can't "check" items. And I want this after "check".

    item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
    
    void MainWindow::ListWidgetSettings()
    {
    
           for(int i = 0; i < ui->listWidget->count(); ++i){
               Task = ui->listWidget->item(i);
               Task->setFlags(Task->flags() | Qt::ItemIsUserCheckable);
               Task->setCheckState(Qt::PartiallyChecked);
               Task->setTextAlignment(Qt::AlignCenter);       
           }
    }
    
    void MainWindow::highlightChecked(QListWidgetItem *Task)
    {
        if(Task->checkState() == Qt::Checked)
        {
            qDebug() << "Checked";
            Euro+=100.0;
            UpdateData();
    
    
        }
           else
               qDebug() << " Else";
    }
    


  • @naax said in Check state QListWidget:

    if I use this, I can't "check" items.

    You asked for:

    Do you know how I can "block" Task? I mean if I set one task to "checked" and after this, I cant uncheck this?

    Before when I used normal QCheckbox I used "setEnabled(false), but here I can't do it or I just don't know-how.

    If you went setEnabled(false) on a particular checkbox, perhaps after it was checked(?), then it seems to me this would do the same thing? Perhaps someone else understands what you seek....


  • Lifetime Qt Champion

    To add to @JonB: you can change the flags anytime you need. So I would say, for example in highlightChecked after the item has been changed.



  • @JonB

    Sorry. My English is not enough good.

    Also.

    I have some items in my QListWidget.
    All items are unchecked first.
    For example, I will pick two items for this list and I change these items to "checked".
    After this action, I want to block these picked items before being unchecked



  • @naax
    So in your highlightChecked(QListWidgetItem *Task) slot, immediately after UpdateData();, maybe you want Task->setFlags(Task->flags() & ~Qt::ItemIsUserCheckable);?



  • @JonB

    I tried this but my program crash.

    if(Task->checkState() == Qt::Checked)
       {
           qDebug() << "Checked";
           Euro+=100.0;
           UpdateData();
           Task->setFlags(Task->flags() & ~Qt::ItemIsUserCheckable);
    
    
       }
          else
              qDebug() << " Else";
    
    The program has unexpectedly finished.
    


  • @naax
    It should not be from the line you added. Whenever you get a "crash", run your programmer [EDIT: that would be: program :-; ] in the Debugger, it will break on the crash, look at the "stack trace" to trace back to the exact line of your code which caused the fault.


  • Lifetime Qt Champion

    @JonB said in Check state QListWidget:

    run your programmer in the Debugger

    You would need a debug build of that programmer :-D



  • @jsulm
    :) Indeed so, corrected, but in this case that might have been a good idea ;-)



  • @JonB @SGaist @jsulm

    void MainWindow::ListWidgetSettings()
    {
           QListWidgetItem* item = 0;
               for(int i = 0; i < ui->listWidget->count(); ++i)
               {
                   item = ui->listWidget->item(i);
                   item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
                   item->setCheckState(Qt::Unchecked);
               }
    }
    
    void MainWindow::highlightChecked(QListWidgetItem *item)
    {
         if(item->checkState() == Qt::Checked)
        {
            qDebug() << "Checked";
            Euro+=100.0;
            UpdateData();
            ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable;
        }
           else
        {
               qDebug() << " Else";
        }
    }
    
    void MainWindow::createConnections()
    {
        QObject::connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
                            this, SLOT(highlightChecked(QListWidgetItem*)));
    }
    

    The program is not crashing anymore, but this not working.

            ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable;
    

    I can still check/uncheck any items.


  • Lifetime Qt Champion

    @naax said in Check state QListWidget:

    ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable;

    Because that statement will not set any flags on the item.

    You are just applying an and operation on the temporary value returned by the call to flags().



  • @naax said in Check state QListWidget:

    ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable;

    I typed exactly what you want:

    Task->setFlags(Task->flags() & ~Qt::ItemIsUserCheckable);
    

    Apply that to your ui->listWidget->item(0) if that is what you want to do (I doubt that is right, why would you want to apply to specifically/only item(0)?).



  • @JonB

      if(item->checkState() == Qt::Checked)
        {
            qDebug() << "Checked";
            Euro+=100.5;
            UpdateData();
           //ui->listWidget->item(0)->setFlags(ui->listWidget->item(0)->flags() & ~Qt::ItemIsSelectable);
            ui->listWidget->blockSignals(true); //THIS LINE HELPED ME
           item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
           ui->listWidget->blockSignals(false);//THIS LINE HELPED ME
    


  • @naax
    Blocking signals is hiding whatever your issue is. You ought to sort out why your setFlags() is causing a problem in the first place, even if you then decide this is the simplest solution.

    If the fault is not elsewhere in your code. (You really ought check it out in a debugger.) I suppose it is possible that because you are doing this inside a slot, which is called because the the item is user-checkable and has been clicked, switching off ItemIsUserCheckable might cause a problem to Qt infrastructure code? If it were me I would try moving it out to a timer event or queued connection to establish where the problem is.

    Thought:

        QObject::connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)),
                            this, SLOT(highlightChecked(QListWidgetItem*)));
    

    The code for changing the checkable state is being executed inside your connected highlightChecked slot? If setting the flags raises itemChanged signal you would have recursion till crash? Again, debugger would tell you, or even qDebug() statements.


Log in to reply