- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания QT 4 программирование GUI на С++ Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
Мы начнем с создания и заполнения модели QStringListModel. Затем создадим представление QListView и свяжем его с только что созданной моделью. Установим также некоторые переключатели редактирования, чтобы позволить пользователю редактировать строку, просто вводя символ или делая двойной щелчок. По умолчанию все переключатели редактирования сброшены для QListView, фактически делая это представление пригодным только для чтения.
01 void TeamLeadersDialog::insert()
02 {
03 int row = listView->currentIndex().row();
04 model->insertRows(row, 1);
05 QModelIndex index = model->index(row);
07 listView->setCurrentIndex(index);
08 listView->edit(index);
09 }
Когда пользователь нажимает на кнопку Insert (вставка), вызывается слот insert(). Этот слот начинает с получения номера строки текущего элемента в списке. Каждый элемент данных модели имеет соответствующий «индекс модели», представленный объектом QModelIndex. Мы подробно рассмотрим индексы модели в следующем разделе, а в данный момент нам достаточно знать, что индекс имеет три основных компонента: строку, столбец и указатель на модель, к которой он принадлежит. В модели одномерного списка столбец всегда равен 0.
Имея номер строки, мы вставляем одну новую строку в данную позицию. Вставка выполняется в модели, и модель автоматически обновляет списковое представление. Затем мы устанавливаем текущий индекс спискового представления на пустую строку, которую мы только что вставили. Наконец, мы устанавливаем в списковом представлении режим редактирования для новой строки, как будто пользователь нажал какую-нибудь клавишу клавиатуры или дважды щелкнул, чтобы начать редактирование.
01 void TeamLeadersDialog::del()
02 {
03 model->removeRows(listView->currentIndex().row(), 1);
04 }
В конструкторе сигнал clicked() кнопки Delete (удалить) связывается со слотом del(). Поскольку мы только что удалили текущую строку, мы можем вызвать removeRows() для текущей позиции индекса и для значения 1 счетчика строк. Как и при выполнении вставки, мы полагаемся на то, что модель должным образом обновит представление.
01 QStringList TeamLeadersDialog::leaders() const
02 {
03 return model->stringList();
04 }
Наконец, функция leaders() позволяет считывать отредактированные строки, когда диалоговое окно закрыто.
Создать TeamLeadersDialog можно было бы на основе универсального диалогового окна редактирования списка строк, просто параметризируя заголовок этого окна. Другое часто используемое пользователями универсальное диалоговое окно отображает список файлов или каталогов. В следующем примере применяется класс QDirModel, который моделирует файловую систему компьютера и позволяет показывать (или скрывать) различные атрибуты файлов. Эта модель может применять фильтр для ограничения типов элементов файловой системы при их выводе на экран и упорядочивать элементы различными способами.
Рис. 10.7. Приложение Просмотр каталога.
Мы начнем с создания и настройки модели и представления в конструкторе диалогового окна Просмотр каталога (Directory Viewer).
01 DirectoryViewer::DirectoryViewer(QWidget *parent)
02 : QDialog(parent)
03 {
04 model = new QDirModel;
05 model->setReadOnly(false);
06 model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
07 treeView = new QTreeView;
08 treeView->setModel(model);
09 treeView->header()->setStretchLastSection(true);
10 treeView->header()->setSortIndicator(0, Qt::AscendingOrder);
11 treeView->header()->setSortIndicatorShown(true);
12 treeView->header()->setClickable(true);
13 QModelIndex index = model->index(QDir::currentPath());
14 treeView->expand(index);
15 treeView->scrollTo(index);
16 treeView->resizeColumnToContents(0);
17 …
18 }
После создания модели мы обеспечиваем возможность ее редактирования и устанавливаем различные начальные атрибуты упорядочивания. Затем мы создаем объект QTreeView для отображения на экране данных модели. Заголовок QTreeView может использоваться пользователем для управления сортировкой. Делая заголовок восприимчивым к щелчкам мышки, пользователь может сортирбвать данные по выбранному им в заголовке столбцу, причем повторные щелчки переключают направление сортировки, т.е сортировку по возрастанию на сортировку по убыванию и наоборот. После настройки заголовков представления данных в виде дерева мы получаем индекс модели текущего каталога и обеспечиваем просмотр содержимого этого каталога, раскрывая при необходимости его подкаталоги, используя expand(), и устанавливая изображение на его начало, используя scrollTo(). Затем мы обеспечиваем ширину первого столбца, достаточную для размещения всех элементов без вывода многоточия (…).
Во фрагменте конструктора, который здесь не показан, мы связываем кнопки Create Directory (создать каталог) и Remove (удалить) со слотами, выполняющими соответствующие действия. Нам не нужно иметь кнопку Rename (переименовать), поскольку пользователи могут переименовывать элементы каталога по месту, нажимая клавишу F2 и осуществляя ввод символов с клавиатуры.
01 voidDirectoryViewer::createDirectory()
02 {
03 QModelIndex index;
04 if (!index.isValid())
05 return;
06 QString dirName = QInputDialog::getText(this,
07 tr("Create Directory"), tr("Directory name"));
08 if (!dirName.isEmpty()) {
09 if (!model->mkdir(index,dirName).isValid())
10 QMessageBox::information(this,
11 tr("Create Directory"),
12 tr("Failed to create the directory"));
13 }
14 }
Если пользователь вводит имя каталога в диалоговом окне ввода, мы пытаемся создать в текущем каталоге подкаталог с этим именем. Функция QDirModel::mkdir() принимает индекс родительского каталога и имя нового каталога; она возвращает индекс модели созданного каталога. Если операция завершается неудачей, возвращается недействительный индекс модели.
Последний пример в этом разделе показывает, как следует применять модель QSortFilterProxyModel. В отличие от других заранее определенных моделей, эта модель использует какую-нибудь существующую модель и управляет данными, которые проходят между базовой моделью и представлением. В нашем примере базовой является модель QStringListModel, которая проинициализирована списком названий цветов, распознаваемых Qt (полученных функцией QColor::colorNames()). Пользователь может ввести строку фильтра в строке редактирования QLineEdit и указать ее тип (регулярное выражение, шаблон или фиксированная строка), используя поле с выпадающим списком.
Рис. 10.8. Приложение Названия цветов (ColorNames).
Ниже приводится фрагмент конструктора ColorNamesDialog:
01 ColorNamesDialog::ColorNamesDialog(QWidget *parent)
02 : QDialog(parent)
03 {
04 sourceModel = new QStringListModel(this);
05 sourceModel->setStringList(QColor::colorNames());
06 proxyModel = new QSortFilterProxyModel(this);
07 proxyModel->setSourceModel(sourceModel);
08 proxyModel->setFilterKeyColumn(0);
09 listView = new QListView;
10 listView->setModel(proxyModel);
11 syntaxComboBox = new QComboBox;
12 syntaxComboBox->addItem(tr("Regular expression"), QRegExp::RegExp);
13 syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);
14 syntaxComboBox->addItem(tr("Fixed string"), QRegExp::FixedString);
15 …
16 }
Модель QStringListModel создается и пополняется обычным образом. После этого создается модель QSortFilterProxyModel. Мы передаем базовую модель, используя функцию setSourceModel(), и указываем прокси на необходимость фильтрации по столбцу 0 базовой модеди. Функция QComboBox::addItem() принимает необязательный аргумент дополнительных данных типа QVariant; мы используем его для хранения значения QRegExp::PatternSyntax c текстом, определяющим тип фильтра данного элемента.
01 void ColorNamesDialog::reapplyFilter()
02 {
03 QRegExp::PatternSyntax syntax =
04 QRegExp::PatternSyntax(syntaxComboBox->itemData(
05 syntaxComboBox->currentIndex()).toInt());
06 QRegExp regExp(filterLineEdit->text(), Qt::CaseInsensitive, syntax);
07 proxyModel->setFilterRegExp(regExp);
08 }
Слот reapplyFilter() вызывается при всяком изменении пользователем строки фильтра или типа шаблона фильтрации в поле с выпадающим списком. Мы создаем объект QRegExp, используя текст в строке редактирования. Затем устанавливаем тип шаблона фильтрации на тот, который имеется в данных текущего элемента и отображается в соответствующем поле с выпадающим списком. Когда мы вызываем setFilterRegExp(), новый фильтр становится активным и автоматически обновляется представление данных.