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

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

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

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

Сообщений: 865

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


Просмотр профиля
« Ответ #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.022 секунд. Запросов: 20.