Russian Qt Forum

Qt => Печать => Тема начата: KosToZyB от Декабрь 20, 2009, 12:41



Название: QTableView + печать
Отправлено: KosToZyB от Декабрь 20, 2009, 12:41
Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать


Название: Re: QTableView + печать
Отправлено: panAlexey от Декабрь 20, 2009, 14:17
Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать
http://www.crossplatform.ru/taxonomy/term/32


Название: Re: QTableView + печать
Отправлено: chu от Ноябрь 29, 2010, 15:37
Кто сталкивался с проблемой печати из QTableView? Не пойму как организовать
http://www.crossplatform.ru/taxonomy/term/32

мне, как новичку, сложно разбираться в этих программах...
прочел из Бланшета главу "Вывод на печатающее устройство",
но боюсь что не смогу адаптировать приведенные в ней примеры под QTableView.
Подкиньте, пожалуйста, примеры кода.


Название: Re: QTableView + печать
Отправлено: asvil от Ноябрь 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();
      }
    }
  }
}


Название: Re: QTableView + печать
Отправлено: chu от Ноябрь 29, 2010, 20:44
Спасибо за код!
А каким сигналом можно вызвать эту функцию?


Название: Re: QTableView + печать
Отправлено: asvil от Ноябрь 29, 2010, 22:38
Функция выдернута из контекста. Одним простым сигналом Вы ее не вызовете. Реформируйте ее для себя)


Название: Re: QTableView + печать
Отправлено: chu от Ноябрь 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 вызвать это окно?


Название: Re: QTableView + печать
Отправлено: asvil от Ноябрь 30, 2010, 15:31
В Qt есть класс QPrintPreviewDialog. Он сигналит void   paintRequested ( QPrinter * printer ). Вы должны в соответсвующем слоте вызвать вышеприведенную функцию. Однако в windows, как-то он не очень корректно у меня перерисовывает картинку. Возможно я что-то сделал не так.


Название: Re: QTableView + печать
Отправлено: chu от Декабрь 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
С чем это может быть связано?