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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTableView + печать  (Прочитано 13329 раз)
KosToZyB
Гость
« : Декабрь 20, 2009, 12:41 »

Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

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


Просмотр профиля
« Ответ #1 : Декабрь 20, 2009, 14:17 »

Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать
http://www.crossplatform.ru/taxonomy/term/32
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
chu
Гость
« Ответ #2 : Ноябрь 29, 2010, 15:37 »

Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать
http://www.crossplatform.ru/taxonomy/term/32

мне, как новичку, сложно разбираться в этих программах...
прочел из Бланшета главу "Вывод на печатающее устройство",
но боюсь что не смогу адаптировать приведенные в ней примеры под QTableView.
Подкиньте, пожалуйста, примеры кода.
Записан
asvil
Гость
« Ответ #3 : Ноябрь 29, 2010, 16:46 »

Не могу сказать что код красив:
Код:
void TableViewPrintActionsManagerHelper::render(QPrinter* printer)
{
  if (tableView) {
    QAbstractItemModel* model = tableView->model();
    QHeaderView* hHeader = tableView->horizontalHeader();
    QHeaderView* vHeader = tableView->verticalHeader();

    if (model) {
      QPainter painter(printer);

      // Check that there is a valid device to print to.
      if (!painter.isActive())
        return;

      int pageLeft = 0;
      int pageTop = 0;
      int pageHeight = painter.device()->height();
      int pageWidth = painter.device()->width();
      int x = pageLeft;
      int y = pageTop;
      QList<QVector<QLine> > linePages;
      QVector<QLine> verticalLines;
      QList<QList<int> > sectionPages;
      QList<int> sections;
      QList<QList<int> > widthPages;
      QList<int> widths;
      QList<int> pageRights;
      QList<QStringList> pageLabels;
      QStringList labels;
      int logicalIndex;

      // Перечисляем столбцы
      for (int i = 0; i < hHeader->count(); ++i) {
        logicalIndex = hHeader->logicalIndex(i);

        // Если столбец не скрыт
        if (!hHeader->isSectionHidden(logicalIndex)) {
          // Если уже не помещаемся на страницу пошем новую страницу
          if (pageWidth <= x + hHeader->sectionSize(logicalIndex)) {
            verticalLines.append(QLine(x, pageTop, x, pageHeight));
            pageRights.append(x);
            x = pageLeft;
            sectionPages.append(sections);
            sections.clear();
            linePages.append(verticalLines);
            verticalLines.clear();
            widthPages.append(widths);
            widths.clear();
            pageLabels.append(labels);
            labels.clear();
          }

          // Добавляем, так как колонка видимая
          sections.append(logicalIndex);
          widths.append(hHeader->sectionSize(logicalIndex));
          labels.append(model->headerData(logicalIndex, Qt::Horizontal).toString());
          verticalLines.append(QLine(x, pageTop, x, pageHeight));
          // Смещаемся правее на ширину колонки
          x += hHeader->sectionSize(logicalIndex);
        }
      }

      if (!sections.isEmpty()) {
        verticalLines.append(QLine(x, pageTop, x, pageHeight));
        pageRights.append(x);
        x = pageLeft;
        sectionPages.append(sections);
        sections.clear();
        linePages.append(verticalLines);
        verticalLines.clear();
        widthPages.append(widths);
        widths.clear();
        pageLabels.append(labels);
        labels.clear();
      }

      int columnPageCount = sectionPages.count();
      int columnCount = sections.count();
      int rowCount = model->rowCount(tableView->rootIndex());
      int rowHeight;
      int columnWidth;
      QModelIndex currentIndex;
      int row = 0;
      int lastPageRow = 0;
      int columnPageIndex = 0;
      int rightColumn;

      while (true) {
        // Получаем колонки текущей страницы
        sections = sectionPages.at(columnPageIndex);
        widths = widthPages.at(columnPageIndex);
        verticalLines = linePages.at(columnPageIndex);
        // Количество колонок текущей страницы
        columnCount = sections.count();
        rightColumn = pageRights.at(columnPageIndex);
        labels = pageLabels.at(columnPageIndex);
        // Перемещаемся в левый верхний угол страницы
        x = pageLeft;
        y = pageTop;
        rowHeight = hHeader->height();

        // Рисуем колонки
        for (int i = 0; i < columnCount; ++i) {
          // Текущее значение
          columnWidth = widths.at(i);
          painter.drawText(x, y, columnWidth, rowHeight
                           , currentIndex.data(Qt::TextAlignmentRole).toInt()
                           | Qt::TextWordWrap
                           | Qt::AlignVCenter
                           | Qt::AlignHCenter
                           , labels.at(i)
                          );
          painter.drawLine(pageLeft, y, rightColumn, y);
          // Перемащаемся правее
          x += widths.at(i);
        }

        y += rowHeight;
        x = pageLeft;

        // Пока можем рисовать на текущей странице
        while (true) {
          // Высота текущей строки
          rowHeight = vHeader->sectionSize(row);

          if (y + rowHeight > pageHeight) {
            //--row;
            break;
          }

          // Рисуем колонки
          for (int i = 0; i < columnCount; ++i) {
            // Текущее значение
            currentIndex = model->index(row, sections.at(i), tableView->rootIndex());
            columnWidth = widths.at(i);

            if (!currentIndex.data().isNull())
              painter.drawText(x, y, columnWidth, rowHeight
                               , currentIndex.data(Qt::TextAlignmentRole).toInt()
                               | Qt::TextWordWrap
                               | Qt::AlignVCenter
                               | Qt::AlignHCenter
                               , currentIndex.data().toString()
                              );

            painter.drawLine(pageLeft, y, rightColumn, y);
            // Перемащаемся правее
            x += widths.at(i);
          }

          x = pageLeft;
          // Перемещаемся ниже
          y += rowHeight;
          // Берем следующую строку
          ++row;

          // Если строки кончились
          if (row >= rowCount)
            break;
        }

        // Рисуем завершающую горизонтальную линию
        painter.drawLine(pageLeft, y, rightColumn, y);
        // Рисуем вертикальные линии
        painter.drawLines(verticalLines);
        // Вытираем лишние концы
        // TODO: hard-coded background color for page
        painter.fillRect(pageLeft, y + 1, pageWidth, pageHeight - (y + 1), QBrush(Qt::white));

        // Если предыдущие колонки не поместились
        if (columnPageIndex < columnPageCount - 1) {
          ++columnPageIndex;
          row = lastPageRow;
        // Предыдущие колонки поместились
        } else {
          columnPageIndex = 0;
          lastPageRow = row;

          // Строки закончились
          if (row >= rowCount)
            break;
        }

        // Создаем новую страницу
        printer->newPage();
      }
    }
  }
}
Записан
chu
Гость
« Ответ #4 : Ноябрь 29, 2010, 20:44 »

Спасибо за код!
А каким сигналом можно вызвать эту функцию?
Записан
asvil
Гость
« Ответ #5 : Ноябрь 29, 2010, 22:38 »

Функция выдернута из контекста. Одним простым сигналом Вы ее не вызовете. Реформируйте ее для себя)
Записан
chu
Гость
« Ответ #6 : Ноябрь 30, 2010, 15:10 »

Адаптировал под себя. Добавил QPrintDialog. Печатает!
Код:
void MainForm::print()
{
    QPrinter *printer = new QPrinter;
    if ( productTableView ) {
        QAbstractItemModel* model = productTableView->model();
        QHeaderView* hHeader = productTableView->horizontalHeader();
        QHeaderView* vHeader = productTableView->verticalHeader();

        if (model) {
            QPrintDialog printDialog(printer, this);
            if (printDialog.exec()) {
                QPainter painter(printer);
Но есть ещё вопрос.
У меня есть 2 принтера.
На одном после настройки печати появляется окно предварительного просмотра (очень умный плоттер), а на другом - нет.
Как с помощью Qt вызвать это окно?
Записан
asvil
Гость
« Ответ #7 : Ноябрь 30, 2010, 15:31 »

В Qt есть класс QPrintPreviewDialog. Он сигналит void   paintRequested ( QPrinter * printer ). Вы должны в соответсвующем слоте вызвать вышеприведенную функцию. Однако в windows, как-то он не очень корректно у меня перерисовывает картинку. Возможно я что-то сделал не так.
Записан
chu
Гость
« Ответ #8 : Декабрь 01, 2010, 16:28 »

заметил что при исполнении функции в консоли приложения выскакивают 11 предупреждений:
Код:
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
UpdateNow not set
С чем это может быть связано?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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