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
Forum Updated to NodeBB v4.3 + New Features

QPrinter in QThread produce QPixmap error

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 3.4k 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