Здравствуйте!
Не могу осилить тему передачи собственного типа данных через буфер обмена. Сделал себе тестовый примерчик, но пока заставить работать не могу.
В чем у меня непонятки?
Начнем с постановки задачи - надо заставить передаваться через буфер обмена какой-нибудь объект определенного типа. В данный момент пытаюсь разобраться с типом QMap<QString,QString>. Если хотябы такой объект смогу передать, дальше уже будет прощще. В перспективе, конечно, буду не QMap<QString,QString> передавать, а что-то более сложное, но пока хотябы это сделать.
Сразу скажу, что конвертить данный хеш в текст и форматировать с использованием символов Tab и Enter - это не вариант. Должны передаваться любые данные, не только текст.
Теперь выдержки из книжек:
"...может понадобиться перетаскивать и принимать свои собственные типы данных, например звуковые данные. Как поступать в подобных ситуациях? Для этих случаев, в классе
QMimeData определен метод
setData(), в который первым параметром нужно передать строку, характеризующую тип данных, а вторым сами данные в объекте класса
QByteArray. Но можно поступить и иначе - унаследовать класс
QMimeData и перезаписать методы
formats() и
retrieveData() ..."
"...если мы хотим перетаскивать пользовательские данные, необходимо сделать выбор между следующими альтернативами:
1. Мы можем обеспечить произвольные данные в виде массива
QByteArray, используя функцию
QMimeDada::setData(), и извлекать их пожже, используя функцию
QMimeDada::data().
2. Мы можем создать подкласс
QMimeData и переопределить функции
formats() и
retrieveData() для обработки наших пользовательских типов данных.
3. Для выполнения операций drag and ndrop в рамках одного приложения мы можем создать подкласс
QMimeData и хранить данные в любых структурах данных. ..."
(Чем отличается пункт 2 от пункта 3 не совсем ясно, ну да ладно)
Для помещения данных в clipboard в любом случае надо пользоваться методом setMimeData() объекта QClipboard. А этот метод принимает данные типа QMimeData. Производный класс от QMimeData мы можем скормить в setMimeData(). Вот пример (clipbrecords - это производный от QMimeData класс)
// Создается объект, который будет помещен в буфер обмена
clipbrecords *rcd=new clipbrecords();
rcd->set_field("name","Article about scintific");
rcd->set_field("author","Aristotel");
rcd->set_field("text","Scintific is paradox area of mind");
rcd->print();
// Создается буфер обмена
QClipboard *cbuf=QApplication::clipboard();
// Объект с данными помещается в буфер обмена
cbuf->setMimeData(rcd);
Проблемы возникают, когда мы пытаемся извлечь данные.
// Создается объект для приема данных
clipbrecords *rcd2=new clipbrecords();
// Данные из буфера вставляются в принимающий объект
rcd2=cbuf->mimeData(); // <- Ошибка здесь
rcd2->print();
Этот код не можем скомпилировать, потому что
cbuf->mimeData() возвращает объект типа
QMimeData, который не может быть преобразован в
clipbrecords.
ошибка: некорректное преобразование из 'const QMimeData*' в 'clipbrecords*'
А если попробуем сделать приведение типов, как это сделано в примере в книге
rcd2=qobject_cast<clipbrecords *>(cbuf->mimeData());
то получим уже другие ошибки
/usr/local/Trolltech/Qt-4.4.1/include/QtCore/qobject.h: In function 'T qobject_cast(const QObject*) [with T = clipbrecords*]':
src/main.cpp:156: instantiated from here
/usr/local/Trolltech/Qt-4.4.1/include/QtCore/qobject.h:451: ошибка: reinterpret_cast from type 'const QObject*' to type 'clipbrecords*' casts away constness
src/main.cpp:156: instantiated from here
/usr/local/Trolltech/Qt-4.4.1/include/QtCore/qobject.h:453: ошибка: static_cast from type 'const QObject*' to type 'clipbrecords*' casts away constness
Что свидетельствует от том, что вроде как нужно иметь объект, в который возвращается начение с модификатором const. Но тогда мы не сможем этому объекту ничего присвоить. Поэтому пробую конструкцию присвоения в момент инициализаии
const clipbrecords *rcd2=qobject_cast<const clipbrecords *>(cbuf->mimeData());
Но в этом случае имею такую ошибку
ошибка: passing 'const clipbrecords' as 'this' argument of 'void clipbrecords::print()' discards qualifiers
то есть по каким-то причинам, вызов метода print() у принимаемого объекта становится невозможным...
В общем, чую что я вообще не понял как работать с буфером обмена. Тем более, что если закомментировать выдов метода print() для принимаемого объекта, то далее будет ошибка компиляции в объекте clipbrecords перегружаемого для QMimeData метода retrieveData(). Как его писать вообще не понял. Он должен возвращать тип QVariant. А мои данные представлены в виде QMap<QString,QString>, и QVariant такой тип не может передать без плясок с бубном. Но даже если я и соображу как передавать производный тип данных через QVariant, остается непонятным, почему невозможно вызов метода print() у объекта rcd2 скомпилировать. И как тогда дальше преобразовывать полученные данные методами объекта clipbrecords? Их тоже не вызовешь.
В рунете толковых объяснялок нет. Надеюсь, гуру скажут что делаю не так?