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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Копирование ячеек из QTableWidget в Excel, через QPlainText. Вопросы процесса...  (Прочитано 12394 раз)
Anarion
Гость
« : Февраль 05, 2010, 09:10 »

Здравствуйте, уважаемые программисты.

Проблема в следующем: хотел реализовать перемещение данных из QTableWidget в Excel обычным методом копипаста, но возникла непонятка.
Со статьей http://hardclub.donntu.edu.ua/projects/qt/articles/qt-excel.html я ознакомился, но проблема как раз таки в том, что нужно перемещать большое количество данных.

Из практики знаю следующее: если, допустим, имеется текстовый файл следующего содержания (между цифрами в строке стоит табуляция):
Код:
1	2	3
4 5 6
7 8 9
то копирование из текстовика в EXcel пройдет нормально:


Поэтому я решил работать именно с текстом (диаграммы и т.д. не нужны - главная задача заключается именно в перемещении чисел, что там дальше с ними будут делать в Excel - воля пользователя).

Для своих целей я решил использовать объект QPlainTextEdit.
Собственно создал объект класса:
    QPlainTextEdit *pte = new QPlainTextEdit(this);
И записал в него в цикле текст (содержание ячеек таблицы) методами:
    pte->appendPlainText(S);
Получилось, например, следующее:

Цифры в строке по-прежнему разделены табуляцией.

Хочу сказать, что можно ввести текст и вручную в виджет QPlainTextEdit, дальнейший результат не изменится. Изображение виджета - для наглядности, в оригинале его вообще не нужно отображать.

Далее я вызываю 2 метода:
    pte->selectAll(); //выделение всего содержимого
    pte->copy(); //копирование в память
Теперь весь текст как бы в памяти, можно вставлять в Excel... И вот тут и возникла проблема: вставка происходит следующим образом:

что несколько озадачивает, поскольку в содержимом QPlainTextEdit явно стоят знаки табуляции, а не пробелы (при копировании в Word как раз таки можно увидеть, что цифры при вставке оказываются разделены пробелами, а не табуляцией).

Далее было проведено еще 2 опыта:
1) Создал виджет QLineEdit, скопировал в него содержимое QPlaintTextEdit, скопировал и вставил в Excel. Операция прошла успешно, цифры расставились по клеткам, как и надо.

Можно было остановиться и на этом варианте, однако максимальная длина строки QLineEdit, как я понял, типа int и составляет 32767 символов, что мне не очень подходит, т.к. копироваться могут тысячи ячеек, содержащих 9 символов.

2) Скопировал содержимое QPlaintTextEdit в обычный блокнот, ничего не изменяя скопировал содержимое и вставил в Excel.

Операция также прошла успешно.

Ну и на последок: для виджета QPlaintTextEdit уже реализована возможность использования Drag & Drop.
1) Если перетащить выделенный текст с табуляцией из него в Excel, то данные опять таки вставятся некорректно.
2) Если перетащить упорядоченные в ячейках данные из Excel в QPlaintTextEdit, потом их же скопировать и вставить обратно в Excel, то вставятся они уже опять некорректно.

Вопрос: можно ли каким-нибудь исправить работу QPlaintTextEdit, чтобы вставка после копирования происходила корректно? Просто не охото заморачиваться лишний раз со структурой файлов типа Excel, если, разумеется, есть альтернатива... Может быть можно даже обойтись без текстового преобразвания (как я понял, если копировать выделенные ячейки из QTableWidget, то при вставке в Excel вставится только та, которая находилась в фокусе. в теории нужно изменить опцию копирования, если таковая есть, но я не нашел). Не удивлюсь, если вопрос решится включением какой-нибудь одной галочки, но на форум я захожу только после часов/дней неудачных попыток решить проблему собственными силами Грустный.
Заранее благодарен.
« Последнее редактирование: Февраль 05, 2010, 09:52 от Anarion » Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #1 : Февраль 05, 2010, 11:28 »

Зачем так через задницу?
Просто заполняй QMimeData.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
Anarion
Гость
« Ответ #2 : Февраль 05, 2010, 12:24 »

Спасибо за совет.  Почитал описание QMimeData, но как понял из предложенных методов (setText(), setHtml(), setUrls(), setImageData(), and setColorData()) специального для таблиц нет? Простите безграмотность, если это не так...

Посмотрел пример Макса Шлее про "Собственный тип перетаскивания":
Код:
MyDragClass::startDrag() 
{
Qlmage img ("mira. jpg");
QByteArray data;
QBuffer buf(&data);
QMimeData* pMimeData = new QMimeData;

buf.open(QIODevice::WriteOnly);
img.save(&buf, "JPG");
pMimeData->setData("image/jpg", data);

QDrag* pDrag = new QDrag(this);
pDrag->setMimeData(pMimeData);
pDrag->start(Qt::MoveAction);
}

Здесь, как я понял, запись в буфер происходит при вызове для изображения метода save. Предполагая, что имеются выделенные в таблице ячейки
QList<QTableWidgetItem *> selectedItems ()
QList<QTableWidgetSelectionRange> selectedRanges () ,
то как в таком случае поступить с ними, поместить в буфер? Или просто также текстом заполнять?
« Последнее редактирование: Февраль 05, 2010, 12:36 от Anarion » Записан
Zmeishe
Гость
« Ответ #3 : Февраль 05, 2010, 12:49 »

Через Clipboard делаю так:
Код:
      QString cbStr;
      QClipboard *cb = QApplication::clipboard();
      QModelIndexList list =  myTableView->selectionModel()->selectedIndexes();
      int i, j, firstRow, lastRow, rowCount;

     if( list.isEmpty() ) return;

         firstRow = list.first().row();  lastRow = list.last().row();
         rowCount = lastRow - firstRow + 1;

       for(i = 0; i < rowCount; ++i, cbStr += '\n')
        for(j = i; j < list.count(); j += rowCount, cbStr += '\t')
          cbStr += myTableView->model()->data(list[ j ], Qt::EditRole).toString();

       cb->setText(cbStr);
В OpenOffice.Calc вставляется на раз. Excel не проверял - нет его в Линуксе.
« Последнее редактирование: Февраль 05, 2010, 12:52 от Zmeishe » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Февраль 05, 2010, 13:28 »

Zmeishe, я почти также делаю, только без указания роли, хотя может указание EditRole и правильнее
Записан

Юра.
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #5 : Февраль 05, 2010, 13:32 »

Через Clipboard делаю так:
Нормально, точно так-же желаю, только если у меня в ячейке есть '\t' or '\n' я их заменяю на пробелы.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
Anarion
Гость
« Ответ #6 : Февраль 05, 2010, 13:41 »

Сейчас сделал похожим образом тоже через Clipboard. Работает отлично. Текст для копирования я также формировал используя цикл по ячейкам и '\t' '\n'. Единственная проблема была в объеме. Хоть в одном был прав изначально: первоначальная запись в строку (QTextPlainEdit->text) Улыбающийся. Проблему можно считать решенной.
Спасибо большое всем за помощь.

Вопрос на последок. В справке сказано:
Код:
The QString class provides a Unicode character string.
QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character. (Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars.)
Т.е., как я понял, строка типа QString вмещает 65535 символов, возможно русских еще в 2 раза меньше. Дальше сказано что еще используется технолигия  implicit sharing (copy-on-write), чтобы увеличить вместимость для копирования. В моем случае копируются только цифры и "." в качестве разделителя дробной части. В методе копирования через Clipboard данные сначала записываются в QString, а уже потом из нее в Clipboard. Провел эксперимент и оказалось, что успешно копируются выделенные ячейки, в которых содержится суммарно более 180 000 знаков (в ворде посчитал), это почти в 3 раза больше чем вместимость QString. Вопрос связан с желанием узнать максимальную вместимость QString.
Почему копирование происходит успешно, если по идее QString не может вместить столько данных?
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #7 : Февраль 05, 2010, 15:08 »

>>Т.е., как я понял, строка типа QString вмещает 65535 символов
Нет не правильно понял, написано "Unicode characters with code values above 65535..." переводится так:
"Символы Unicode со значением кода выше 65535 ..."
Записан

Юра.
Anarion
Гость
« Ответ #8 : Февраль 05, 2010, 15:37 »

Спасибо за объяснение.
Записан
crossly
Гость
« Ответ #9 : Февраль 07, 2010, 21:41 »

>>implicit sharing (copy-on-write), чтобы увеличить вместимость для копирования.
тоже не верно... к примеру.... мы создаем строку.... создаем еще одну и присваиваем ей значение первой.... так вот... это означает что память для второй строки не будет выделена до того, пока она не изменится....
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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