Теперь мы переделаем этот пример, но на этот раз мы создадим подкласс QMimeData, чтобы отложить или избежать (потенциально затратных) преобразований между элементами QTableWidgetltem и массивом QByteArray. Ниже приводится определение нашего подкласса:
01 class TableMimeData : public QMimeData
02 {
03 Q_OBJECT
04 public:
05 TableMimeData(const QTableWidget *tableWidget,
06 const QTableWidgetSelectionRange &range);
07 const QTableWidget *tableWidget const
08 { return myTableWidget; }
09 QTableWidgetSelectionRange range const { return myRange; }
реальных данных мы храним объект QTableWidgetSelectionRange, который определяет область переносимых ячеек и сохраняет указатель на QTableWidget. Функции formats и retrieveData класса QMimeData переопределяются.
В конструкторе мы инициализируем закрытые переменные.
01 QStringList TableMimeData::formats const
02 {
03 return myFormats;
04 }
Функция formats возвращает список MIME—типов, находящихся в объекте MIME—данных. Последовательность форматов обычно несущественна, однако на практике желательно первыми указывать «лучшие» форматы. Приложения, поддерживающие несколько форматов, иногда будут использовать первый подходящий.
возвращает данные для заданного MIME—типа в виде объекта QVariant. Параметр format обычно содержит одну из строк, возвращенных функцией formats, однако нам не следует на это рассчитывать, поскольку не все приложения проверяют MIME—тип на соответствие форматам функции formats. Предусмотренные в классе QMimeData функции получения данных text, html, urls, imageData, colorData и data реализуются с помощью функции retrieveData.
Параметр preferredType определяет тип, который следует поместить в объект QVariant. Здесь мы его игнорируем и рассчитываем на то, что QMimeData преобразует при необходимости возвращенное значение в требуемый тип.
15 } else if (event->mimeData->hasFormat("text/plain")) {
16 QString plainText = event->mimeData->text;
17 …
18 event->acceptProposedAction;
19 }
20 QTableWidget::mouseMoveEvent(event);
21 }
Функция dropEvent аналогична функции с тем же названием, которую мы рассматривали ранее в данном разделе, но на этот раз мы ее оптимизируем, делая вначале проверку возможности приведения типа QMimeData в тип TableMimeData. Если qobject_cast<T> срабатывает, это значит, что перенос был инициирован виджетом MyTableWidget, расположенным в том же самом приложении, и мы можем получить непосредственный доступ к данным таблицы вместо того, чтобы пробираться сквозь программный интерфейс класса QMimeData. Если приведение типов оказывается неудачным, мы извлекаем данные стандартным способом.