Results 1 to 20 of 25

Thread: QTableView printing

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default QTableView printing

    Greetings!

    I'm trying to print the contents of a QTableView to the printer (this is my first QT program sending anything to the printer). I didn't know if there was a way as easy as QTextEdit->document()->print(&printer). The closeest I could find was implementing something similar to what I saw in Qt's Pixelator example, but all this seems to do for me is spit out an empty sheet of paper:

    Note: 'model' is previously defined as QAbstractItemModel *model

    Qt Code:
    1. QPrinter printer(QPrinter::HighResolution);
    2.  
    3. QPrintDialog *dlg = new QPrintDialog(&printer, this);
    4. dlg->setWindowTitle(tr("Print Table"));
    5.  
    6. if (dlg->exec() != QDialog::Accepted)
    7. return;
    8.  
    9. QPainter painter;
    10. painter.begin(&printer);
    11.  
    12. int rows = model->rowCount(QModelIndex());
    13. int columns = model->columnCount(QModelIndex());
    14.  
    15. double xscale = printer.pageRect().width();
    16. double yscale = printer.pageRect().height();
    17. double scale = qMin(xscale, yscale);
    18.  
    19. painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
    20. printer.paperRect().y() + printer.pageRect().height()/2);
    21. painter.scale(scale, scale);
    22. painter.save();
    23.  
    24. const int ItemSize = 256;
    25. float x = ItemSize /2;
    26. for (int printRow = 0; printRow < rows; ++printRow) {
    27. float y = ItemSize /2;
    28. for (int column = 0; column < columns; ++column) {
    29. option.rect = QRect(int(x), int(y), ItemSize, ItemSize);
    30. myTableView->itemDelegate()->paint(&painter, option, model->index(printRow, column, parent));
    31. x = x + 256;
    32. }
    33. y = y + 256;
    34. }
    35. painter.restore();
    36. painter.end();
    To copy to clipboard, switch view to plain text mode 

    Any ideas would be greatly appreciated. The only thing I can think of is creating a QTextDocument() and feeding it the QTableView in HTML format and then printing that.

    Thanks,
    --D
    Last edited by wysota; 26th September 2006 at 19:25. Reason: missing [code] tags

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView printing

    At least you'll need a proper QStyleOptionViewItem for the delegate to function properly.
    Try taking advantage of QAbstractItemView::viewOptions().

    PS. use [ code ] -tags to make code blocks more readable.
    J-P Nurmi

  3. #3
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QTableView printing

    Thanks for the reply and the tip!! I guess I'm a little confused, though. When I try to do QStyleOptionViewItem option = QAbstractItemView::viewOptions(), compiler tells me I need to state an object. So when I do QStyleOptionViewItem option = myTableView->viewOptions, compiler states I can't b/c viewOptions is protected. What am I missing??

    Thanks,
    --D

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView printing

    Yes, it's a non-static and a protected method. So for this kind of approach to work you would have to move some parts of the printing code to a QTableView subclass.
    J-P Nurmi

  5. #5
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QTableView printing

    Do you have any examples to go on? I guess I'm unclear of how to get my existing QTableView's contents into a separate QTableView subclass - or are you saying I should subclass my QTableView alltogether?

    Thanks!

  6. #6
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QTableView printing

    Ok, I finally opened my eyes and saw how to get the TableView contents from the view to my subclass (again, model predefined as QAbstractItemModel *model, and mainTableView->setModel(model) happens during MainWindow construction) but I'm back to square 1 - All that prints is a blank page. I know setting the PrintTableView's model to 'model' passes the contents of the mainTableView to tempTableView b/c I can display the contents of the indexes through qDebug() in PrintTableView:rintTable(). Is there something more I need to do to viewOptions()? or is there something else I'm missing?

    Thanks!!

    Qt Code:
    1. void MainWindow::Print()
    2. {
    3. QPrinter printer(QPrinter::HighResolution);
    4. QPrintDialog *dlg = new QPrintDialog(&printer, this);
    5. dlg->setWindowTitle(tr("Print ACLs"));
    6.  
    7. if (dlg->exec() != QDialog::Accepted)
    8. return;
    9.  
    10. PrintTableView *tempTableView = new PrintTableView();
    11. tempTableView->setModel(model);
    12. tempTableView->printTable(printer);
    13. }
    14.  
    15. PrintTableView::PrintTableView(QWidget *parent) : QTableView (parent)
    16. {
    17.  
    18. }
    19.  
    20. void PrintTableView::printTable(QPrinter &printer)
    21. {
    22. QString str;
    23. QPainter painter;
    24. painter.begin(&printer);
    25. const int ItemSize = 256;
    26. int rows = model()->rowCount(QModelIndex());
    27. int columns = model()->columnCount(QModelIndex());
    28. int sourceWidth = (columns+1) * ItemSize;
    29. int sourceHeight = (rows+1) * ItemSize;
    30. painter.save();
    31.  
    32. double xscale = printer.pageRect().width();
    33. double yscale = printer.pageRect().height();
    34. double scale = qMin(xscale, yscale);
    35.  
    36. painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
    37. printer.paperRect().y() + printer.pageRect().height()/2);
    38. painter.scale(scale, scale);
    39. painter.translate(-sourceWidth/2, -sourceHeight/2);
    40.  
    41. QStyleOptionViewItem option = viewOptions();
    42.  
    43. float x = ItemSize /2;
    44. for (int printRow = 0; printRow < rows; ++printRow) {
    45. float y = ItemSize /2;
    46. for (int column = 0; column < columns; ++column) {
    47. option.rect = QRect(int(x), int(y), ItemSize, ItemSize);
    48. itemDelegate()->paint(&painter, option, model()->index(printRow, column, QModelIndex()));
    49. x = x + 256;
    50. }
    51. y = y + 256;
    52. }
    53. painter.restore();
    54. painter.end();
    55. }
    56.  
    57. QStyleOptionViewItem PrintTableView::viewOptions() const
    58. {
    59. QStyleOptionViewItem option = QAbstractItemView->viewOptions();
    60. return option;
    61. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView printing

    The painter's scale factors don't look proper. They should be pretty close to 1.0..

    Qt Code:
    1. double xscale = printer.pageRect().width();
    2. double yscale = printer.pageRect().height();
    3. double scale = qMin(xscale, yscale);
    4. ...
    5. painter.scale(scale, scale); // causes painter to scale it's result width/height times bigger
    To copy to clipboard, switch view to plain text mode 

    I guess it should be something more like:
    Qt Code:
    1. double xscale = printer.pageRect().width() / width();
    2. double yscale = printer.pageRect().height() / height();
    3. ...
    4. painter.scale(xscale, yscale);
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  8. #8
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QTableView printing

    J-P,

    Thanks for the reply. I implemented your suggestion, and I'm still getting a blank page.

  9. #9
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView printing

    Qt Code:
    1. void TableView::print(QPainter* painter, const QRect& area)
    2. {
    3. const int rows = model()->rowCount();
    4. const int cols = model()->columnCount();
    5.  
    6. // calculate the total width/height table would need without scaling
    7. double totalWidth = 0.0;
    8. for (int c = 0; c < cols; ++c)
    9. {
    10. totalWidth += columnWidth(c);
    11. }
    12. double totalHeight = 0.0;
    13. for (int r = 0; r < rows; ++r)
    14. {
    15. totalHeight += rowHeight(r);
    16. }
    17.  
    18. // calculate proper scale factors
    19. const double scaleX = area.width() / totalWidth;
    20. const double scaleY = area.height() / totalHeight;
    21. painter->scale(scaleX, scaleY);
    22.  
    23. // paint cells
    24. for (int r = 0; r < rows; ++r)
    25. {
    26. for (int c = 0; c < cols; ++c)
    27. {
    28. QModelIndex idx = model()->index(r, c);
    29. QStyleOptionViewItem option = viewOptions();
    30. option.rect = visualRect(idx);
    31. itemDelegate()->paint(painter, option, idx);
    32. }
    33. }
    34. }
    35.  
    36. // printer usage
    37. QPainter painter(&printer);
    38. tableView->print(&painter, printer.pageRect());
    39.  
    40. // test on pixmap
    41. QPixmap pixmap(320, 240);
    42. QPainter painter(&pixmap);
    43. tableView->print(&painter, pixmap.rect());
    44. pixmap.save("table.png", "PNG");
    To copy to clipboard, switch view to plain text mode 

    Edit: I forgot to add painter translating but that should be trivial to add once you get the idea..
    Last edited by jpn; 29th September 2006 at 21:24.
    J-P Nurmi

  10. #10
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTableView printing

    Yet another (maybe even better?) option is to use QPainter's powerful redirecting mechanism. This approach doesn't even require subclassing of QTableView.

    Qt Code:
    1. QPrinter printer(QPrinter::HighResolution);
    2. QPrintDialog dlg(&printer, this);
    3. if (dlg.exec() == QDialog::Accepted)
    4. {
    5. // calculate the total width/height table would need without scaling
    6. const int rows = table->model()->rowCount();
    7. const int cols = table->model()->columnCount();
    8. double totalWidth = 0.0;
    9. for (int c = 0; c < cols; ++c)
    10. {
    11. totalWidth += table->columnWidth(c);
    12. }
    13. double totalHeight = 0.0;
    14. for (int r = 0; r < rows; ++r)
    15. {
    16. totalHeight += table->rowHeight(r);
    17. }
    18.  
    19. // redirect table's painting on a pixmap
    20. QPixmap pixmap(totalWidth, totalHeight);
    21. QPainter::setRedirected(table->viewport(), &pixmap);
    22. QPaintEvent event(QRect(0, 0, totalWidth, totalHeight));
    23. QApplication::sendEvent(table->viewport(), &event);
    24. QPainter::restoreRedirected(table->viewport());
    25.  
    26. // print scaled pixmap
    27. QPainter painter(&printer);
    28. painter.drawPixmap(printer.pageRect(), pixmap, pixmap.rect());
    29. }
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  11. #11
    Join Date
    Sep 2006
    Posts
    38
    Thanks
    5
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: QTableView printing

    J-P,

    This is AWESOME!!! Thank you so much! both of these work well. The first suggestion works nicely and scales the text well. The 2nd option prints only to the printer (i.e., won't print to Adobe PDF's printer - for instance, i get a "Critical: QPixmap::toWinHBITMAP(), failed to create dibsection(Not enough stoarge is available to process this command.) but that's a hurdle to tackle another time) but prints the grid lines, which is REALLY nice. One issue I have with both suggestions, however, is that for large tables (more than 1 page), it scales the text to fit onto one page. I had thought to emit a signal to call QPrinter::newPage(), but, I can't seem to do this with the QPainter you've set up.

    I've also tried :

    Qt Code:
    1. double totalHeight = 0.0;
    2. for (int r = 0; r < 45; ++r){
    3. totalHeight += table->rowHeight(r);
    4. }
    To copy to clipboard, switch view to plain text mode 

    for your examples, but this only prints 1 page as well. Do you know how I can tell QPainter to send a new page request to the Printer?

    Again...Thank you very much for your help!!!

    --D

  12. #12
    Join Date
    Mar 2012
    Posts
    3
    Qt products

    Question Re: QTableView printing

    hi friend . how i do translate this part code from c++ to python?


    for (int c = 0; c < cols; ++c)
    {
    QModelIndex idx = model()->index(r, c);
    QStyleOptionViewItem option = viewOptions();
    option.rect = visualRect(idx);
    itemDelegate()->paint(painter, option, idx);
    }


  13. #13
    Join Date
    Mar 2012
    Posts
    3
    Qt products

    Default Re: QTableView printing


  14. #14
    Join Date
    Jan 2007
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QTableView-Printing with grid lines

    {Two posts merged}

    Hi All,

    Iam Jagannath Mandapally

    Hi All,

    My Requirement is Print table , Means Generating .ps file and giving to APS Print but I have some issues.

    1) Preview is not visible on APS Print

    2) Printing table but ignoring some rows

    3) Grid lines are not Printing

    my code is :
    Qt Code:
    1. void TableEditor::printt()
    2. {
    3.  
    4. QPrinter printer(QPrinter::HighResolution);
    5. //printer.setFullPage(true);
    6. //printer.setPageSize(QPrinter::A4);
    7. /*int rightMargin = printer.paperRect().right() - printer.pageRect().right();
    8.  int bottomMargin = printer.paperRect().bottom() - printer.pageRect().bottom();
    9. int leftMargin = printer.paperRect().left() - printer.pageRect().left();
    10. int topMargin = printer.paperRect().top() - printer.pageRect().top();*/ //This is commented
    11. //printer.margins(&topMargin,&leftMargin,&bottomMargin, &rightMargin);
    12.  
    13. printer.setOutputFileName("rtest.ps");
    14. QPrintDialog dlg(&printer, this);
    15. double totalWidth = 0.0;
    16. double totalHeight = 0.0;
    17. double totalPageHeight=0.0;
    18. //QRect area;
    19. if (dlg.exec() == QDialog::Accepted){
    20. const int rows=view->model()->rowCount();
    21. const int cols = view->model()->columnCount();
    22. printf("no of rows\n %d",rows);
    23. printf("\n no of columns %d",cols);
    24. for (int c = 0; c < cols; ++c) {
    25. totalWidth += view->columnWidth(c); }
    26. for(int p=0; p<45; p++) //45
    27. {
    28. totalPageHeight+= view->rowHeight(p);
    29.  
    30.  
    31. }
    32. for (int r = 0; r < rows; ++r)
    33. { totalHeight += view->rowHeight(r); }
    34.  
    35.  
    36. } //if loop ending here
    37.  
    38. QPainter painter(&printer);
    39. //QPainter::setRedirected(view->viewport(), &painter);
    40. //QPaintEvent event(QRect(0, 0, totalWidth, totalHeight));
    41. //view->paintEvent(&event);
    42. //painter.drawLines(0,0,rows,cols);
    43. //QApplication::sendEvent(view->viewport(), &event);
    44. //QPainter::restoreRedirected(view->viewport()); //This is commented for testing row nums
    45. //QPainter painter(&printer);
    46. painter.begin(&printer);
    47. const int rows=view->model()->rowCount();
    48. const int columns=view->model()->columnCount();
    49. printf("The num of rows are %d",rows);
    50. QRect area = printer.paperRect(); // here should be pageRect
    51. const double xscale = area.width() / totalWidth;
    52. const double yscale = area.height() / totalHeight;
    53. const double pscale = area.height() / totalPageHeight;
    54. painter.scale(xscale+9, yscale+9); // With the scaling 3 It is Printing all
    55. //painter.translate(area.x() + xscale, area.y() + pscale); //This is original
    56. painter.translate(area.x() + xscale, area.y() + yscale);
    57. //painter.save(); //commented
    58. int x=0;
    59. //int y=0 ;// This is introduced for the columns
    60. //view->paintEvent(&event);
    61. QPainter paint(this);
    62. paint.setPen(Qt::red);
    63. paint.drawRect(0, 0, 0, 0);
    64.  
    65.  
    66. for (int r=0; r<rows; r++)
    67. {
    68. ++x;
    69.  
    70. for(int c=0; c<columns; c++)
    71. {
    72. //++y;
    73.  
    74.  
    75. /*double xscale = printer.pageRect().width() / width();
    76.   double yscale = printer.pageRect().height() / height();
    77.   double scale = qMin(xscale, yscale);
    78.   QRect rect = painter.viewport( ); */
    79. //QSize size = pixmap.size( );
    80. //size.scale( rect.size( ), Qt::KeepAspectRatio );
    81. //painter.drawLines(0,0,rows,columns);
    82.  
    83.  
    84. QModelIndex idx = view->model()->index(r,c);
    85. option = view->viewOptions();
    86. option.rect =view->visualRect(idx);
    87. view->itemDelegate()->paint(&painter, option, idx);
    88. // painter.drawPixmap(printer.pageRect(), pixmap, pixmap.rect());
    89.  
    90. // painter.drawPixmap((r,c), pixmap, pixmap.rect());
    91.  
    92. // if(page!=printer.numCopies())
    93. } //columns are closed here
    94. if (x==39)
    95. {
    96. printf("This is inside if loop %d:",x);
    97. printer.newPage();
    98. x=0;
    99. //y=0;
    100. painter.translate(0, -1150);
    101. //painter.translate(0,-1000);
    102. //painter.translate(0,-850);
    103. x=0;
    104.  
    105. // page++
    106. //painter.drawPixmap(printer.pageRect(), pixmap, pixmap.rect());
    107.  
    108. //x=0;
    109. painter.save();
    110. painter.restore();
    111.  
    112. // break;
    113. }
    114.  
    115. printf("%d",rows);
    116.  
    117.  
    118. // }
    119. }
    120. painter.end();
    121. system("apsprint rtest.ps");
    122.  
    123.  
    124.  
    125.  
    126. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 6th February 2007 at 17:26. Reason: missing [code] tags

  15. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView-Printing with grid lines

    Next time, please, use [code] tags, format your code properly and remove unnecessary lines.

  16. #16
    Join Date
    Jan 2007
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView printing

    Hi Jacek,

    Thank U very much , I need solution desparately

    BR
    Jagannath

  17. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTableView printing

    First try cleaning your code, because it's unreadable.

    Maybe you should consider creating a report in HTML using QTextDocument?

  18. #18
    Join Date
    Aug 2007
    Posts
    275
    Thanks
    28
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTableView-Printing with grid lines

    This was very helpful to my Problem with Printing from QTableModel but I have encountered some hick ups

    when i print a cell i use this
    Qt Code:
    1. //i have initialized my painter like this
    2. QPainter painter (printer);
    3. painter.scale(idealXScale, idealYScale);
    4. painter.setClipping(true);
    5. qDebug() << "hasClippings = "<< painter.hasClipping(); // this will always give me false
    To copy to clipboard, switch view to plain text mode 

    then i pass painter on to print a page

    Qt Code:
    1. for (int r = info.startRow; r <= info.endRow; ++r)
    2. {
    3. for (int c = info.startCol; c <= info.endCol; ++c)
    4. {
    5. QModelIndex idx = model()->index(r,c);
    6. QStyleOptionViewItem option = viewOptions();
    7. option.rect = visualRect(idx);
    8. if (r % 2 == 0)
    9. {
    10. QBrush brush(QColor(220, 220, 220), Qt::SolidPattern);
    11. painter.fillRect(option.rect, brush);
    12. }
    13.  
    14. itemDelegate()->paint(&painter, option, idx);
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

    now when the cell's content is clipped ( content not fully shown in the rect or maybe elided) then somehow the text will be printed but text is too big.

    picture speaks a thousand words
    Attached Images Attached Images

Similar Threads

  1. Set height of QTableView to fit exact number of rows.
    By Ben.Hines in forum Qt Programming
    Replies: 3
    Last Post: 17th January 2019, 01:49
  2. QTableView sorting
    By gabriels in forum Qt Programming
    Replies: 11
    Last Post: 6th October 2010, 17:13
  3. QTableView paints too much
    By Jimmy2775 in forum Qt Programming
    Replies: 2
    Last Post: 26th July 2006, 18:42
  4. Replies: 0
    Last Post: 28th June 2006, 20:49
  5. Multi-line messages in QTableView
    By Conel in forum Qt Programming
    Replies: 6
    Last Post: 13th April 2006, 13:49

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.