Russian Qt Forum

Qt => Вопросы новичков => Тема начата: koldun90 от Март 17, 2015, 10:44



Название: qlistwidget
Отправлено: koldun90 от Март 17, 2015, 10:44
Всем привет формирую список айтемов следующим образом
Код
C++ (Qt)
QListWidgetItem *item=new QListWidgetItem(QIcon(ikonka),hh,ui->listWidget,QListWidgetItem::UserType);
           item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
           item->setCheckState(Qt::Unchecked);
           ui->listWidget->addItem(item);
 

в результате получается вот такая картина
(http://s019.radikal.ru/i619/1503/82/ce9e9772aec9.png) (http://www.radikal.ru)
вопрос заключается в следующем как мне отследить момент когда я
ставлю крест  в  чекбоксе
? При чем сам айтем я могу и не выделять



Название: Re: qlistwidget
Отправлено: __Heaven__ от Март 17, 2015, 10:54
Сигнал
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item)
пробовали?


Название: Re: qlistwidget
Отправлено: Fregloin от Март 17, 2015, 11:01
Учим модели...  ;)


Название: Re: qlistwidget
Отправлено: koldun90 от Март 17, 2015, 11:08
Сигнал
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item)
пробовали?
попробывал вроде бы подходит (срабатывает только тогда когда я ставлю крестик)
но мне нужно сделать так чтобы я в своем списке мог активировать только один чекбокс. Те чтоб крестик ставился только на один айтем


Название: Re: qlistwidget
Отправлено: __Heaven__ от Март 17, 2015, 11:26
Ну вы же знаете, путь ко всем итемам...
Тот, который был изменен - ставим тру, всем остальным фолс


Название: Re: qlistwidget
Отправлено: koldun90 от Март 17, 2015, 11:46
Ну вы же знаете, путь ко всем итемам...
Тот, который был изменен - ставим тру, всем остальным фолс
я вас не совсем понял...
мне нужно чтобы когда я ставил крестик на текущем айтеме, чтобы затем крестик на предыдущем айтеме как бы очистился как мне сделать это?

или это нужно каждый айтем в цикле перебирать и если он checked делать ему unchecked?




Название: Re: qlistwidget
Отправлено: gil9red от Март 17, 2015, 12:00
Ну вы же знаете, путь ко всем итемам...
Тот, который был изменен - ставим тру, всем остальным фолс
я вас не совсем понял...
мне нужно чтобы когда я ставил крестик на текущем айтеме, чтобы затем крестик на предыдущем айтеме как бы очистился как мне сделать это?

или это нужно каждый айтем в цикле перебирать и если он checked делать ему unchecked?




Поясняю:
В цикле всем элементам убираете крестик, а текущему ставите

Ну, или ведите учет:
  Заведите QListWidgetItem * lastCheckedItem
  В конструкторе инициализируете нулем
  Когда отлавливаете сигнал itemChanged(QListWidgetItem * item):
    Смотрите на item->checked(), если он стал true, проверяете, что lastCheckedItem не равен нулю и убираете у lastCheckedItem крестик (setChecked(dalse)) и запоминаете текущий элемент lastCheckedItem = item

Ну что-то вроде такого :)


Название: Re: qlistwidget
Отправлено: Zerkin от Март 17, 2015, 12:04
gil9red собственно все разжевал, добавлю лишь, что если элементов не очень много, возможно, заводить отдельный указатель смысла и нет, в цикле все айтемы просто проверять, если же много, то да - логично завести.


Название: Re: qlistwidget
Отправлено: __Heaven__ от Март 17, 2015, 12:07
Судя по скрину выше - не много.


Название: Re: qlistwidget
Отправлено: Zerkin от Март 17, 2015, 12:07
Для любителей экстравагантных решений - можно было бы еще привязаться к selectionMode если он QAbstractItemView::SingleSelection и добавить поведение с чекбоксами =)


Название: Re: qlistwidget
Отправлено: koldun90 от Март 17, 2015, 12:31
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item)
{
int rez=ui->listWidget->count();   // вычисляем количество вес строк в листвиджете
   for (int i=1;i<rez;i++)  // перебираем все айтемы кроме самого верхнего
   {
       QListWidgetItem *item2=ui->listWidget->item(i);  // берем айтем на каждой строке
       if (item2!=item) // если айтем на который я кликнул не текущий айтем
                                              //перебираемый в  цикле
       {
           item2->setCheckState(Qt::Unchecked);  // сбрасываем крестик
       }
   }
}
 
вот так вроде правильно да?


Название: Re: qlistwidget
Отправлено: Zerkin от Март 17, 2015, 12:52
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item)
{
int rez=ui->listWidget->count();   // вычисляем количество вес строк в листвиджете
   for (int i=1;i<rez;i++)  // перебираем все айтемы кроме самого верхнего
   {
       QListWidgetItem *item2=ui->listWidget->item(i);  // берем айтем на каждой строке
       if (item2!=item) // если айтем на который я кликнул не текущий айтем
                                              //перебираемый в  цикле
       {
           item2->setCheckState(Qt::Unchecked);  // сбрасываем крестик
       }
   }
}
 
вот так вроде правильно да?

Почему самый верхний (0й) не проверяете?


Название: Re: qlistwidget
Отправлено: koldun90 от Март 17, 2015, 13:22
да там заголовок....


Название: Re: qlistwidget
Отправлено: gil9red от Март 17, 2015, 13:45
Форматирование кода лучше соблюдать -- и вам проще, и другим людям, видящим ваш код :)

До:
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item)
{
int rez=ui->listWidget->count();   // вычисляем количество вес строк в листвиджете
   for (int i=1;i<rez;i++)  // перебираем все айтемы кроме самого верхнего
   {
       QListWidgetItem *item2=ui->listWidget->item(i);  // берем айтем на каждой строке
       if (item2!=item) // если айтем на который я кликнул не текущий айтем
                                              //перебираемый в  цикле
       {
           item2->setCheckState(Qt::Unchecked);  // сбрасываем крестик
       }
   }
}

После:
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item) {
   int count = ui->listWidget->count(); // вычисляем количество вес строк в листвиджете
 
   // перебираем все айтемы кроме самого верхнего
   for (int i = 1; i < count; i++) {
       QListWidgetItem * child = ui->listWidget->item(i); // берем айтем на каждой строке
 
       // если айтем на который я кликнул не текущий айтем перебираемый в  цикле
       if (child != item)
           child->setCheckState(Qt::Unchecked); // сбрасываем крестик
   }
}

Расположение фигурных скобок -- на выбор, кому то нравится на следующей строке, кому то на текущей


Название: Re: qlistwidget
Отправлено: __Heaven__ от Март 17, 2015, 16:34
Я бы даже сделал так:
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item) {
   int count = ui->listWidget->count(); // вычисляем количество вес строк в листвиджете
 
   // перебираем все айтемы кроме самого верхнего
   for (int i = 1; i < count; i++) {
       QListWidgetItem * child = ui->listWidget->item(i); // берем айтем на каждой строке
       child->setCheckState(Qt::Unchecked); // сбрасываем крестик
   }
   item->setCheckState(Qt::Checked)
}


Название: Re: qlistwidget
Отправлено: Kurles от Март 18, 2015, 09:37
Я бы даже сделал так:
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item) {
   int count = ui->listWidget->count(); // вычисляем количество вес строк в листвиджете
 
   // перебираем все айтемы кроме самого верхнего
   for (int i = 1; i < count; i++) {
       QListWidgetItem * child = ui->listWidget->item(i); // берем айтем на каждой строке
       child->setCheckState(Qt::Unchecked); // сбрасываем крестик
   }
   item->setCheckState(Qt::Checked)
}
А зацикливания не произойдёт? Состояния айтема меняем, соответственно снова же должен это слот вызваться? не надо это всё в
ui->listWidget->blockSignals(..) обернуть?


Название: Re: qlistwidget
Отправлено: __Heaven__ от Март 18, 2015, 15:52
Я бы даже сделал так:
Код
C++ (Qt)
void QListWidget::itemChanged(QListWidgetItem * item) {
   int count = ui->listWidget->count(); // вычисляем количество вес строк в листвиджете
 
   // перебираем все айтемы кроме самого верхнего
   for (int i = 1; i < count; i++) {
       QListWidgetItem * child = ui->listWidget->item(i); // берем айтем на каждой строке
       child->setCheckState(Qt::Unchecked); // сбрасываем крестик
   }
   item->setCheckState(Qt::Checked)
}
А зацикливания не произойдёт? Состояния айтема меняем, соответственно снова же должен это слот вызваться? не надо это всё в
ui->listWidget->blockSignals(..) обернуть?
согласен