Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QPrinter in QThread produce QPixmap error

QPrinter in QThread produce QPixmap error

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 3.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RazrFalcon
    wrote on last edited by
    #1

    Simple code example:
    @void MainWindow::on_btnPrint_clicked()
    {
    QThread *thread = new QThread(this);
    ThreadedPrint *print = new ThreadedPrint();
    print->moveToThread(thread);
    thread->start();
    QMetaObject::invokeMethod(print, "print", Qt::QueuedConnection);
    }

    ThreadedPrint::ThreadedPrint(QObject *parent) :
    QObject(parent)
    {
    m_printer = new QPrinter(QPrinter::PrinterResolution);
    m_printer->setPageSize(QPrinter::A4);
    }

    void ThreadedPrint::print()
    {
    QPainter painter(m_printer);
    QRect pageRect = m_printer->pageRect();
    QImage image(pageRect.width(), pageRect.height(), QImage::Format_RGB32);
    image.fill(Qt::black);
    painter.drawImage(0, 0, image);
    }
    @
    And i got:
    QPixmap: It is not safe to use pixmaps outside the GUI thread
    and I got empty page from my printer.
    But when I use printing into PDF all works fine, so bug only appears when I try to print on real printer.

    The documentation states:
    Painting in Threads
    QPainter can be used in a thread to paint onto QImage, QPrinter, and QPicture paint devices.

    So my question is: can i print in non-gui thread?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      The QPrinter instance allocated on the heap in your ThreadedPrint constructor will be in the main thread (and stay there).

      So either:

      • Make the QPrinter instance a member variable
      • Put the heap allocation in a slot, called init() for example, and have that slot connected to the started() signal of the QThread wrapper object.

      Here is an example Qt 4 program that works without issue here:
      @
      #include <QtGui>
      #include <QDebug>

      class ThreadedPrint: public QObject {
      Q_OBJECT
      QPrinter *m_printer;
      public:
      ThreadedPrint(QObject *p = 0): QObject(p) {
      m_printer = 0;
      }
      ~ThreadedPrint() {
      delete m_printer;
      }

      signals:
      void finished();

      public slots:
      void init() {
      qDebug() << Q_FUNC_INFO;
      m_printer = new QPrinter;
      }
      void doPrint() {
      qDebug() << Q_FUNC_INFO;
      Q_ASSERT(m_printer);
      QPainter painter(m_printer);
      QRect pageRect = m_printer->pageRect();
      QImage image(pageRect.width(), pageRect.height(), QImage::Format_RGB32);
      image.fill(Qt::black);
      painter.drawImage(0, 0, image);

          // wait a while then finish the thread
          QTimer::singleShot(3000, this, SIGNAL(finished()));
      }
      

      };

      int main(int argc, char **argv)
      {
      QApplication app(argc, argv);

      QThread *thread= new QThread(qApp);
      ThreadedPrint *worker = new ThreadedPrint;
      worker->moveToThread(thread);
      QObject::connect(thread, SIGNAL(started()), worker, SLOT(init()));
      QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
      QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
      QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
      thread->start();
      
      QTimer::singleShot(10000, qApp, SLOT(quit()));
      QTimer::singleShot(1000, worker, SLOT(doPrint()));
      return app.exec();
      

      }
      #include "main.moc"
      @

      1 Reply Last reply
      0
      • R Offline
        R Offline
        RazrFalcon
        wrote on last edited by
        #3

        Thanks for explanation, but I still have the same error...

        Even when I create QPrinter object in doPrint slot.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          ChrisW67
          wrote on last edited by
          #4

          The example code I posted works fine here. Does it fail for you?

          1 Reply Last reply
          0
          • R Offline
            R Offline
            RazrFalcon
            wrote on last edited by
            #5

            Yes. I compile it without changes and get QPixmap error.
            Qt 4.8.4, Windows 7 x32.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved