13 item->setIcon(iconForSymbol(i.value));
14 item->setData(Qt::UserRole, i.key);
15 …
16 }
17 }
Мы инициализируем id (идентификатор последнего выбранного элемента) значением —1. Затем мы конструируем QListWidget — удобный виджет отображения элементов. Мы проходим в цикле по всем элементам ассоциативного массива символов блок—схемы symbolMap и для каждого создаем объект QListWidgetItem. Конструктор QListWidgetItem принимает выводимую на экран строку QString и родительский виджет QListWidget.
Затем задаем пиктограмму элемента и вызываем setData для сохранения в QListWidgetItem идентификатора элемента. Закрытая функция iconForSymbol возвращает QIcon для заданного имени символа.
QListWidgetItem может выступать в разных ролях, каждой из которых соответствует определенный объект QVariant. Самыми распространенными ролями являются Qt::DisplayRole, Qt::EditRole и Qt::IconRole, и для них предусмотрены удобные функции по установке и получению их значений (setText, setIcon), но имеется также несколько других ролей. Кроме того, мы можем определить пользовательские роли, задавая числовое значение, равное или большее, чем Qt::UserRole. В нашем примере мы используем Qt::UserRole при сохранении идентификатора каждого элемента.
В непоказанной части конструктора создаются кнопки, выполняется компоновка виджетов и задается заголовок окна.
01 void FlowChartSymbolPicker::done(int result)
02 {
03 id = -1;
04 if (result == QDialog::Accepted) {
05 QListWidgetItem *item = listWidget->currentItem;
06 if (item)
07 id = item->data(Qt::UserRole).toInt;
08 }
09 QDialog::done(result);
10 }
Функция done класса QDialog переопределяется. Она вызывается при нажатии пользователем кнопок ОК или Cancel. Если пользователь нажимает кнопку OK, мы получаем доступ к соответствующему элементу и извлекаем идентификатор, используя функцию data. Если бы нас интересовал текст элемента, мы могли бы его получить с помощью вызова item->data(Qt::DisplayRole).toString или более простого вызова item->text.
По умолчанию QListWidget используется только для чтения. Если бы мы хотели разрешить пользователю редактировать элементы, мы могли бы соответствующим образом установить переключатели редактирования представления, используя QAbstractItemView::setEditTriggers, например QAbstractItemView::AnyKeyPressed означает, что пользователь может инициировать редактирование элемента, просто начав вводить символы с клавиатуры. Можно было бы поступить по-другому и предусмотреть кнопку редактирования Edit (и, возможно, кнопки добавления и удаления Add и Delete) и связать их со слотами, чтобы можно было программно управлять операциями редактирования.
Теперь, когда мы увидели, как можно использовать удобный класс отображения элементов для просмотра и выбора данных, мы рассмотрим пример, в котором можно редактировать данные. Мы снова используем диалоговое окно, представляющее на этот раз набор точек с координатами (x, у), которые может редактировать пользователь.
Рис. 10.4. Приложение Редактор координат.
Как и в предыдущем примере, мы основное внимание уделим программному коду, относящемуся к представлению элементов, и начнем с конструктора.
01 CoordinateSetter::CoordinateSetter(QList *coords,
02 QWidget *parent)
03 : QDialog(parent)
04 {
05 coordinates = coords;
06 tableWidget = new QTableWidget(0, 2);
07 tableWidget->setHorizontalHeaderLabels(
08 QStringList << tr("X") << tr("Y"));
09 for (int row = 0; row < coordinates->count; ++row) {
10 QPointF point = coordinates->at(row);
11 addRow;
12 tableWidget->item(row, 0)->setText(
13 QString::number(point.x));