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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перетаскивание из QTableWidget в QTreeView  (Прочитано 5984 раз)
virtual_root
Гость
« : Август 15, 2012, 18:20 »

Добрый вечер ребята) Подскажите пожалуйста как мне реализовать перетаскивание из ячеки таблицы в ветку дерева. Приложение следующее:
Есть список групп и подгрупп. Я их отображаю в QTreeView. В каждой группе или подгруппе имеются фамилии участников. Они отображаются в отдельной таблице в зависимости от выбранной группы. Нужно сделать следующее: Выбирается фамилия участника из таблицы, состоящего в группе №1 и тащится в дерево групп в группу №2. При перетаскивании нужно чтобы рисовался луч от участника до группы в которую его тащат.
Ребята, помогите, подскажите идеи для реализации перетаскивания с таким эффектом))
Записан
Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #1 : Август 16, 2012, 10:17 »

В модели таблицы переопределяете методы:
Код:
QMimeData* Model::mimeData (const QModelIndexList& indexes) const {
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;

QDataStream stream(&encodedData, QIODevice::WriteOnly);

QListIterator<QModelIndex> iterator(indexes);
while (iterator.hasNext()) {
QModelIndex index = iterator.next();
if (index.isValid()) {
// тут пишете в stream информацию о перетаскиваемых элементах, например идентификаторы
stream.write(...);
}
}

mimeData->setData("MyMimeType", encodedData);
return mimeData;
}

QStringList Model::mimeTypes () const {
QStringList types;
types << "MyMimeType";
return types;
}

В модели treeView переопределяете
Код:
bool HierarchyModel::dropMimeData (const QMimeData* data, Qt::DropAction action,
   int row, int column, const QModelIndex& parent) {
}
, из data извлекаете ваши данные и вставляете в модель.
Естественно для представлений нужно разрешить drag'n'drop.

Как луч рисовать: при начале перетаскивания запоминаете начальную позицию мыши, вычисляете конечную. Создаете QImage с прозрачным фоном, рисуете туда линию и рендерите его поверх основного окна. Как-то так.
Записан
virtual_root
Гость
« Ответ #2 : Август 16, 2012, 22:41 »

Спасибо большое, буду пробовать!
Записан
virtual_root
Гость
« Ответ #3 : Сентябрь 13, 2012, 21:54 »

всё хорошо, но у меня в таблице нет модели.. и я отнаследовалась от QTableWidget и переопределила у него метод mimeData(). Но к сожалению, я заметила что именно переопределение этого метода всё портит... Если я его не трогаю то вижу что попадаю в функцию
Код:
bool PQModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
    qDebug()<<data->text()<<data->data("text/plain")<<__FUNCTION__;
}
эта функция модели дерева в которое я пытаюсь сделать перетаскивание.
Если я переопределяю у своего QTableWidget метод
Код:
QMimeData* PQTableWidget::mimeData(const QList<QTableWidgetItem *> items)const
то не попадаю уже в неё и собственно само перетаскивание перестаёт работать...
Уже два дня вожусь, ну что-то не пойму что я не так пишу.. Ребята, подскажите пожалуйстаЙ
Вот код моей модели дерева:
Код
C++ (Qt)
#include <QStandardItemModel>
 
class PQModel : public QStandardItemModel
{
   Q_OBJECT
public:
   explicit PQModel(QObject *parent = 0);
 
protected:
   bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
 
signals:
 
public slots:
 
};

Код
C++ (Qt)
#include <QDebug>
#include <QMimeData>
#include "pqmodel.h"
 
PQModel::PQModel(QObject *parent) :
   QStandardItemModel (parent)
{
}
 
bool PQModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
   qDebug()<<data->text()<<data->data("text/plain")<<__FUNCTION__;
}
здесь собственно всё очень просто и работает как надо.
вот код моей таблицы:
Код
C++ (Qt)
#include <QTableWidget>
 
class PQTableWidget : public QTableWidget
{
   Q_OBJECT
public:
   explicit PQTableWidget(QWidget *parent = 0);
 
protected:
   QMimeData* mimeData(const QList<QTableWidgetItem *> items) const;
   QStringList mimeTypes();
 
signals:
 
public slots:
 
};

Код
C++ (Qt)
#include <QMimeData>
#include <QDataStream>
#include <QDebug>
#include <QDrag>
#include "pqtablewidget.h"
 
PQTableWidget::PQTableWidget(QWidget *parent) :
   QTableWidget(parent)
{
}
 
QMimeData* PQTableWidget::mimeData(const QList<QTableWidgetItem *> items)const{
 
   QMimeData *mimeData = new QMimeData();
   QByteArray encodedData;
 
   QDataStream stream(&encodedData, QIODevice::WriteOnly);
 
   QTableWidgetItem *item = items.at(0);
   QTableWidgetItem *newItem = this->item(item->row(),0);
   qDebug()<<newItem->text();
   stream<<newItem->text();
 
   mimeData->setData("text/plain", encodedData);
   QTableWidget::mimeData(items);
   return mimeData;
}
 
QStringList PQTableWidget::mimeTypes(){
   QStringList types;
   types << "text/plain";
   return types;
}
Как правильно переопределить метод QMimeData* PQTableWidget::mimeData(const QList<QTableWidgetItem *> items)const, чтобы всё правильно заработало?Непонимающий
Записан
virtual_root
Гость
« Ответ #4 : Сентябрь 13, 2012, 22:24 »

нашла ошибку, нужно было тип другой указать:
Код
C++ (Qt)
QMimeData* PQTableWidget::mimeData(const QList<QTableWidgetItem *> items)const{
 
   QMimeData *mimeData = new QMimeData();
   QByteArray encodedData;
 
   QDataStream stream(&encodedData, QIODevice::WriteOnly);
 
   QTableWidgetItem *item = items.at(0);
   QTableWidgetItem *newItem = this->item(item->row(),0);
   qDebug()<<newItem->text();
   stream<<newItem->text();
 
   mimeData->setData("application/x-qabstractitemmodeldatalist", encodedData);
   QTableWidget::mimeData(items);
   return mimeData;
}

теперь вижу,что при перетаскивании из таблицы в QTreeView у модели QTreeView срабатывает функция
Код:
bool PQModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
    qDebug()<<data->text()<<__FUNCTION__<<data->formats()<<data->data("application/x-qabstractitemmodeldatalist").at(0);
}
но мне никак не удаётся достать данные... хотя они точно туда пишутся! Подскажите, пожалуйста как быть? Что нужно сделать чтобы получить перетаскиваемые данные?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #5 : Сентябрь 13, 2012, 23:09 »

QTableWidget::mimeData(items); — этот вызов «портит» всё, что ты записываешь руками
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
virtual_root
Гость
« Ответ #6 : Сентябрь 14, 2012, 11:55 »

всё равно не могу достать данные... я в QMimeData записываю int и пытаюсь его потом достать:
Код:
int id = (int) data;
но там что-то не то...
Записан
virtual_root
Гость
« Ответ #7 : Сентябрь 14, 2012, 11:58 »

я достала данные) внимательно ещё раз изучила документацию и нашла там)
Код:
    QByteArray encodedData = data->data("application/vnd.text.list");
    QDataStream stream(&encodedData, QIODevice::ReadOnly);
    QString text;
             stream >> text;
             qDebug()<<text;
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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