Results 1 to 4 of 4

Thread: [QT4] QThread and printing a QList<QPixmap>

  1. #1
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default [QT4] QThread and printing a QList<QPixmap>

    Hello all...

    I've got a program where I'm trying to print a list of pixmaps in a separate thread, so the user can continue working while the app prints off a copy of the work.

    Structurally, I have this:

    1. main thread brings up print dialog to set up printer options, and stores them inside the print thread

    2. main thread takes snapshots of selected dialogs, stores them in a QList <QPixmap> structure contained in the print thread (before the print thread starts).

    3. main thread starts print thread and goes on with life

    4. print thread re-scales each image in the list to the paper size (using the smooth scaling option - time consuming)

    5. print thread prints each pixmap, one to a page

    6. print thread exits, emits a finished() signal. Main thread sees this and deletes the print thread. If another print request comes up before this time, main thread will block until print thread finishes and becomes deleted, then create a new one.

    Sounds pretty straight-forward to me... but apparently not.

    I'm getting weird X window errors and out-of-memory errors when I do this. I think I may have a solution for the out-of-memory errors (kind of) if I can get the setStackSize() to work (complains about an invalid argument ). It works fine if I call the run() function instead of the start() function of the thread (forcing it to work on a single thread), but I'm getting the following:
    Xlib: unexpected async reply (sequence 0x18d32)!
    Xlib: sequence lost (0x200e6 > 0x196d4) in reply type 0xe6!
    In file image/qpixmap_x11.cpp, line 709: Out of memory
    When I use setStackSize(100000000) (100M), I get the following instead:
    X Error: BadRequest (invalid request code or no such operation) 1
    Extension: 239 (Uknown extension)
    Minor opcode: 0 (Unknown request)
    Resource id: 0x20024be
    and it scrolls on - 1 for each item printed, I think.

    Also, when I use the setStackSize function intelligently:
    QThread::start: thread stack size error: Invalid argument
    I'm a little confused on how to best proceed.

    Below is the code from the thread (header):
    Qt Code:
    1. class threadPrint : public QThread
    2. {
    3. Q_OBJECT
    4. public:
    5. threadPrint(QObject * parent = 0);
    6. virtual ~threadPrint();
    7.  
    8. void run();
    9.  
    10. QList <QPixmap> pixlist;
    11. QPrinter printer;
    12. };
    To copy to clipboard, switch view to plain text mode 
    ... and the source for the thread (The constructor / destructor are empty):
    Qt Code:
    1. void threadPrint::run()
    2. {
    3. QPainter painter;
    4. painter.begin(&printer);
    5. for(QList<QPixmap>::iterator i = pixlist.begin(); i != pixlist.end(); ++i)
    6. {
    7. if(i != pixlist.begin())
    8. {
    9. printer.newPage();
    10. }
    11. (*i) = (*i).scaled(printer.pageRect().width(), printer.pageRect().height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    12. painter.drawPixmap(0, 0, (*i));
    13. }
    14. painter.end();
    15. }
    To copy to clipboard, switch view to plain text mode 
    Pretty simple stuff so far... and the print slot from the main thread:
    Qt Code:
    1. void formMainApp::menuFilePrint()
    2. {
    3. PrintThread = new threadPrint;
    4. PrintThread->printer.setColorMode(QPrinter::GrayScale);
    5. PrintThread->printer.setOrientation(QPrinter::Landscape);
    6. QPrintDialog qp(&PrintThread->printer, this);
    7. if(qp.exec() == QDialog::Accepted)
    8. {
    9. QModelIndexList MIL = ui.treeViewSQLList->selectionModel()->selectedIndexes();
    10. for(QList<QModelIndex>::const_iterator i = MIL.begin(); i != MIL.end(); ++i)
    11. {
    12. if(!(*i).column()) //Only care about the rows selected, not the columns (entire rows selected)
    13. {
    14. myForm * T = myTreeModel->findForm(*i); //myForm is the dialog to take a snapshot of, obtained from my model
    15. T->show(); //Qt has a deficiency where it cannot take a snapshot of a form that is not being displayed
    16. QPixmap pixmap = QPixmap::grabWidget(T, T->rect());
    17. T->close();
    18. PrintThread->pixlist.append(pixmap);
    19. }
    20. }
    21. PrintThread->setStackSize(sizeof(threadPrint) + sizeof(QPixmap) * (PrintThread->pixlist.count() + 1));
    22. PrintThread->start();
    23. }
    24. }
    To copy to clipboard, switch view to plain text mode 
    ... and theoretically, it should go on its merry way and print. But looking above, it does all sorts of funky stuff. Any ideas? Do I have some basic concept horribly disfigured?
    Life without passion is death in disguise

  2. #2
    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: [QT4] QThread and printing a QList<QPixmap>

    QPixmaps are stored on the X Server, so you can't use them in a non-GUI thread. Use QImages instead.

  3. The following user says thank you to jacek for this useful post:

    KShots (24th April 2006)

  4. #3
    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: [QT4] QThread and printing a QList<QPixmap>

    Without even reading the whole post of yours, I'd like to remind you about the fact that QPixmap is not thread-safe, QImage is.
    J-P Nurmi

  5. The following user says thank you to jpn for this useful post:

    KShots (24th April 2006)

  6. #4
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] QThread and printing a QList<QPixmap>

    Yeah, you're both right. Using QImage caused it to work right away. I didn't need to mess with the stack size either, so I took that line out. Thanks!
    Life without passion is death in disguise

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.