Russian Qt Forum
Ноябрь 18, 2024, 09:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Буфер обмена и самодельные типы данных  (Прочитано 27198 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Ноябрь 12, 2008, 22:25 »

Здравствуйте!


Не могу осилить тему передачи собственного типа данных через буфер обмена. Сделал себе тестовый примерчик, но пока заставить работать не могу.

В чем у меня непонятки?

Начнем с постановки задачи - надо заставить передаваться через буфер обмена какой-нибудь объект определенного типа. В данный момент пытаюсь разобраться с типом 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? Их тоже не вызовешь.

В рунете толковых объяснялок нет. Надеюсь, гуру скажут что делаю не так?
« Последнее редактирование: Ноябрь 18, 2008, 14:11 от xintrea » Записан

Собираю информацию по крупицам
http://webhamster.ru
spirit
Гость
« Ответ #1 : Ноябрь 12, 2008, 22:36 »

в QVariant можно запихнуть любой тип, как это сделать см. в описалове Q_DECLARE_METATYPE.
Записан
BRE
Гость
« Ответ #2 : Ноябрь 12, 2008, 22:38 »

Объяви функцию print так
void print() const;
Записан
ритт
Гость
« Ответ #3 : Ноябрь 12, 2008, 23:41 »

Цитировать
const QMimeData * QClipboard::mimeData ( Mode mode = Clipboard ) const
Returns a reference to a QMimeData representation of the current clipboard data.

а посему:

Код:
// Создается объект для приема данных
// Данные из буфера вставляются в принимающий объект
const clipbrecords *rcd2 = cbuf->mimeData();
rcd2->print(); // <- Ошибка здесь: немодифицирующий метод должен быть статическим или иметь правый const
Записан
vaprele07
Гость
« Ответ #4 : Ноябрь 13, 2008, 05:50 »

ну или избавится от конст, да... ты не за был про макрос Q_OBJECT в производном классе?

Код:
//передача мапа
typedef QMap<QString, QString> Fields;
Fields fields;

f1["name"]="Article about scintific";
//...
QMimeData md;
QBuffer b1(&QByteArray());
b1.open(QIODevice::ReadWrite);
QDataStream s1(&b1);
s1 << f1;
b1.seek(0);

md.setData("Fields", b1.data());

QApplication::clipboard()->setMimeData(&md);

//прием мапа
QBuffer b2(&QApplication::clipboard()->mimeData()->data("Fields"));
b2.open(QIODevice::ReadOnly);
QDataStream s2(&b2);
Fields f2;
in >> f2;

qDebug() << f2;

Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #5 : Ноябрь 13, 2008, 13:51 »

Все, парни, получилось. Спасибо всем кто помогал.

Подводных камней было конечно много, но в конце концов заработало.

Подумываю сделать урок (текст объяснялки + пример проекта), ибо про передачу самодельных данных через буфер обмена инфы в рунете практически нет. А так лишний вопрос будет иметь готовое решение.

Кстати, что думают модераторы про создание ветки "Уроки", в которых можно будет создавать только темы с первым постом в виде урока. На flasher.ru так раньше было, очень помогало и начинающим, и тем кто разбирался с какой-нить новой темой во flash.

Вот примерно какие уроки планирую сделать

- Работа с буфером обмена. Передача нестандартных данных.
- Работа с ini файлами (борьба с затыками месторазмещения ini файлов)
- Работа с QDir (особенности логики работы QDir c с абсолютными и относительными путями)
- Как сделать самодельный виджет (рабочая заготовка)
- Преобразование QIndexModel в порядковый номер и обратно
- Как понять, от какого объекта пришел сигнал
- Отладочный вывод XML данных
- Отладочный вывод дерева объектов, если неработают функции dumpObjectInfo() и dumpObjectTree()
« Последнее редактирование: Ноябрь 13, 2008, 14:10 от xintrea » Записан

Собираю информацию по крупицам
http://webhamster.ru
spirit
Гость
« Ответ #6 : Ноябрь 13, 2008, 14:20 »

Цитировать
Преобразование QIndexModel в порядковый номер и обратно
QModelIndex  Подмигивающий
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #7 : Ноябрь 13, 2008, 14:43 »

Цитировать
Преобразование QIndexModel в порядковый номер и обратно
QModelIndex  Подмигивающий

Ну это я по памяти писал.
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #8 : Ноябрь 13, 2008, 14:48 »

для того завели вику. если готов потратить какое-то время на написание статьи/статей, свяжись с пантером.
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #9 : Ноябрь 13, 2008, 15:18 »

для того завели вику. если готов потратить какое-то время на написание статьи/статей, свяжись с пантером.

Парни, толку от вашей вики никакого, потому что о ней мало кто знает. Основная страница данного ресурса - FORUM (http://www.prog.org.ru/index.php?action=forum), а не НАЧАЛО (http://www.prog.org.ru/index.php). Поймите, у вас нету "сайта по QT", у вас есть форум по QT. И его главная страница - http://www.prog.org.ru/index.php?action=forum.

Чтобы вики начали читать, и люди вообще знали о том что она есть в природе, нужно в заголовке форума прописать что-то в стиле "Так же загляните в нашу базу знаний Qt - уроки, готовые решения". И эта надпись должна мозолить глаза на каждой станице.

Я вот например зарегистрировался здесь полгода назад, а про вики только сегодня узнал. И то не сам узнал, а когда сказали. А на flasher.ru раздел Уроки читал в первый же день. Почуствуйте разницу. Не хотим делать уроки на форуме - хорошо, но давайте тогда четко и явно укажем где у нас копятся "неизменяемые" данные.

Но и этого мало. По-хорошему, надо всунуть поиск по вики в результаты поиска по форуму. Вот тогда вики начнут пользоваться и читать. Конечно, никто такого делать не будет, а это на самом деле очень важно. Поэтому раздел Уроки очень форуму нужен. Ведь решения будут как минимум видны в поиске.
Записан

Собираю информацию по крупицам
http://webhamster.ru
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #10 : Ноябрь 13, 2008, 15:24 »

Щас посмотрел - да, ребята, эта вики http://prog.org.ru/qt_wiki/ - унылое Г. И из этого Г надо долго и упорно выбираться. Не стоит тратить на такую вики время, сделайте раздел на форуме, будьте человечнее, и люди к вам потянутся.
Записан

Собираю информацию по крупицам
http://webhamster.ru
Karl-Philipp
Гость
« Ответ #11 : Ноябрь 13, 2008, 17:56 »

xintrea, ну и что же в Вики не так? Что-то я не наблюдал там "унылого Г" Улыбающийся
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #12 : Ноябрь 13, 2008, 18:04 »

Щас посмотрел - да, ребята, эта вики http://prog.org.ru/qt_wiki/ - унылое Г. И из этого Г надо долго и упорно выбираться. Не стоит тратить на такую вики время, сделайте раздел на форуме, будьте человечнее, и люди к вам потянутся.

Ну если каждый будет тока обсырать и ничего не делать, то она такой и останеться. Вики только подняли. Взял бы да и написал пару статеек.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Rcus
Гость
« Ответ #13 : Ноябрь 13, 2008, 18:12 »

Ну если каждый будет тока обсырать и ничего не делать, то она такой и останеться. Вики только подняли. Взял бы да и написал пару статеек.

Идея и сила вики в свободе редактирования. Надо хотя бы сквозную регистрацию/вход с форумом.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #14 : Ноябрь 13, 2008, 18:16 »

Надо хотя бы сквозную регистрацию/вход с форумом.

Это уже предложено Admin'у. Ждем ответа
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.057 секунд. Запросов: 23.