БлогNot. QT: используем List Widget и обрабатываем клик + нажатие клавиши

QT: используем List Widget и обрабатываем клик + нажатие клавиши

В стандартном комплекте QT реализованы основные средства для работы со списками и таблицами. В режиме редактирования формы легко увидеть, что им посвящены 2 группы элементов:

  • Item Widgets (Item-based) – виджеты, рассчитанные, в основном, на "классическую" поэлементную обработку контейнеров (хотя и здесь без MVC-подхода бывает не обойтись);
  • Item Views (Model-based) – виджеты для работы со списками и таблицами по концепции MVC.

В блоге уже есть примеры как на "поэлементный" подход (списки, дерево), так и на "модельный" MVC-подход (теория по MVC, простой пример приложения MVC).

Не хватает только примера на самую "базовую" компоненту List Widget, восполним этот пробел.

Создав проект на основе класса QWidget, разработаем простейшее приложение для работы со списком List Widget. Для этого удалим из проекта файлы widget.*, а в main.cpp запрограммируем создание объекта класса QListWidget. При этом сигналы от виджета будет обрабатывать отдельный класс-контроллер списка ListContoller:

#include <QApplication>
#include "listcontroller.h"

int main(int argc, char *argv[]) {
 QApplication a(argc, argv);
 QListWidget listWidget; //будущий список
 listWidget.addItems (listItems); 
  //будущие предустановленные элементы списка
 listWidget.resize (640,480); 
 listWidget.show(); //запуск и отображение виджета
 ListContoller listController(&listWidget);
 /* Здесь будет настройка сигналов виджета */
 return a.exec();
}

Добавим в проект новый класс C++ с названием ListContoller и предком QObject:

Создание класса, производного от QObject
Создание класса, производного от QObject

В файле listcontroller.cpp оставим только строку

#include "listcontoller.h"

а в listcontroller.h решим следующие задачи:

  • реализуем слоты для обработки двойного и одиночного клика по списку (класс QListWidget испускает соответствующие сигналы, наследуя их от QAbstractItemView с параметром типа const QModelIndex &, означающим индекс выбранного элемента в модели);
  • предусмотрим "предустановленные" элементы списка.

То есть, как в Visual C++, включим код прямо в файл .h, а что, законом не запрещено :)

#ifndef LISTCONTOLLER_H
#define LISTCONTOLLER_H
#include <QObject>
#include <QListWidget>

static const QStringList listItems =
 QStringList () << "Яша" << "Бяша" << "Няша";
 //Определили предустановленные элементы списка

class ListContoller : public QObject {
 Q_OBJECT
 QListWidget *listWidget; //Ссылка на родительский виджет
public:
 ListContoller (QListWidget *listWidget) {
  this->listWidget = listWidget;
 }
public slots:
 void onListDoubleClicked (const QModelIndex &i) {
  if (!i.isValid()) return; 
   //Нет индекса выбранного элемента -  ничего не делать
  QListWidget *w = dynamic_cast <QListWidget *>
   (sender());//Узнать, какой виджет послал сигнал          
  if (w) { //Если удалось это сделать,
   QListWidgetItem *item = w->takeItem(i.row());
    //то попытаться получить элемент
   if (item) { //Если и это удалось,
    delete item; //удалить, или Ваша обработка item
   }
  }
 }
 void onListClicked (void) {
  QString item("Hello"); listWidget->addItem(item); 
 }
};

#endif // LISTCONTOLLER_H

Видно, что обработчик двойного клика по элементу будет удалять его, используя информацию об индексе элемента, полученную из сигнала, а обработчик обычного клика будет добавлять в список новый элемент. Он не получает аргумента, поэтому вынужден воспользоваться ссылкой на родительский виджет listWidget, которую сохранил конструктор.

Так как сигналы об одиночном и двойном клике могут оказаться взаимосвязанными, слот для обработки одиночного клика привяжем не к соответствующему сигналу от QListWidget, а к нажатию клавиши, например, Insert. Показанный ниже код демонстрирует, как это сделать, его нужно поставить в main.cpp на место комментария

/* Здесь будет настройка сигналов виджета */

QObject::connect(&listWidget, SIGNAL(doubleClicked(QModelIndex)),
  &listController,SLOT(onListDoubleClicked(QModelIndex)));
  //Сигнал "двойной щелчок" списка связали со слотом 
QShortcut *shortcut = new
  QShortcut(QKeySequence(Qt::Key_Insert),&listWidget);
  //Создали хоткей для клавиши Insert
QObject::connect(shortcut, SIGNAL(activated()),
  &listController,SLOT(onListClicked()));
  //И заставили его вызвать второй слот контроллера

При этом в начале файла main.cpp добавлены директивы:

#include <QKeySequence>
#include <QShortcut>

Теперь двойным кликом по элементам списка мы можем удалять их, а нажатием клавиши Insert добавлять в список новые элементы. Правда, на них всех будет написано только "Hello", но ведь мы пока и не программировали большего.

 Скачать папку с этим проектом QT5 в архиве .zip (2 Кб)

14.04.2017, 15:08 [12176 просмотров]


теги: учебное список программирование c++ qt

К этой статье пока нет комментариев, Ваш будет первым