Need service of an experienced Qt coder



  • How to print a dialog in Qt seems to be beyond my comprehension.
    Would you like to teach me this one skill.
    If so, lets talk!


  • Lifetime Qt Champion

    Hi,

    Something like

    QPrinter printer;
    printer.setOutputFileName("/Path/to/my/pdf/out.pdf");
    dialog->render(&printer);
    

    ?



  • Does your example print the dialog window to a pdf file?



  • @collycrk
    I want to print to a printer not to a file. How is that done.



  • Below there is one of the ways to do it.
    I modified my code slightly to avoid long explanation.
    But you should get an idea.

    QWidget* w =  ... your widget
    
        QPrinter* m_printer  = NULL;
    
    if( !m_printer )
    {
    	QPrinterInfo info =	QPrinterInfo::defaultPrinter ();
    	m_printer =  new QPrinter ( QPrinter::HighResolution );
    	//		m_printer->setOrientation( QPrinter::Landscape );
    }
    
    QPrintDialog *dialog = new QPrintDialog( this);
    dialog->setWindowTitle(tr("Print Document"));
    
    dialog->setOption( QAbstractPrintDialog::PrintToFile, false );
    dialog->setOption( QAbstractPrintDialog::PrintPageRange, false );
    dialog->setOption( QAbstractPrintDialog::PrintSelection, false );
    
    if ( dialog->exec() == QDialog::Accepted)
    {
    	QPainter painter( m_printer );
    	int resolution = m_printer->resolution ();
    
    	painter.begin(m_printer);
    
    	double xscale = m_printer->pageRect().width()/double(w->width());
    	double yscale = m_printer->pageRect().height()/double(w->height());
    	double scale = qMin(xscale, yscale);
    	painter.translate(  m_printer->paperRect().x() + m_printer->pageRect().width()/2,
    		m_printer->paperRect().y() + m_printer->pageRect().height()/2);
    	painter.scale(scale, scale);
    	painter.translate(-w->width()/2, -w->height()/2);
    
    	w->render(&painter);
    
    }
    
    delete dialog;


  • // header
    class QWidget;
    void print( QWidget* w );

    // cpp
    #include <QWidget>
    #include <QPrinterInfo>
    #include <QPrintDialog>
    #include <QPainter>

    void print( QWidget* w )
    {
    Q_CHECK_PTR( w );

    QPrinterInfo info =	QPrinterInfo::defaultPrinter ();
    QPrinter* printer=  new QPrinter ( QPrinter::HighResolution );
    printer->setOrientation( QPrinter::Landscape );
    
    QPrintDialog *dialog = new QPrintDialog( w );
    dialog->setWindowTitle(QObject::tr("Print Document"));
    
    dialog->setOption( QAbstractPrintDialog::PrintToFile, false );
    dialog->setOption( QAbstractPrintDialog::PrintPageRange, false );
    dialog->setOption( QAbstractPrintDialog::PrintSelection, false );
    
    if ( dialog->exec() == QDialog::Accepted)
    {
    	QPainter painter( printer );
    	int resolution = printer->resolution ();
    
    	painter.begin(printer);
    
    	double xscale = printer->pageRect().width()/double(w->width());
    	double yscale = printer->pageRect().height()/double(w->height());
    	double scale = qMin(xscale, yscale);
    	painter.translate(  printer->paperRect().x() + printer->pageRect().width()/2,
    		printer->paperRect().y() + printer->pageRect().height()/2);
    	painter.scale(scale, scale);
    	painter.translate(-w->width()/2, -w->height()/2);
    
    	w->render(&painter);
    
    }
    
    delete printer;
    delete dialog;
    

    }

    // usage :

    • include header header first
    • call print with a pointer to your widget you want to print

  • Lifetime Qt Champion

    @collycrk Yes, that's what my example does. You asked for help on how to print a widget, you didn't specify whether it needed to be on paper.

    @alex_malyu One optimization that can be done: since they live only during the print function, use a QPrinter and QPrintDialog on the stack. That simplify the the memory management.



  • @SGaist said:

    @alex_malyu One optimization that can be done: since they live only during the print function, use a QPrinter and QPrintDialog on the stack. That simplify the the memory management.

    Example was a quick and only partial adoption of the code I already had and supposed to be treated as an example. You can adopt it for your specific needs, use RAII etc.



  • SGaist thanks so much for your help with coding a dialog to print to paper.

    At this point I have created a print button on the dialog and placed the print code into its slot.
    I placed the class and the void print( QWidget* w ); into the header file.

    I'm getting an error that 'w was not declared in this scope'.
    What do I replace the 'w' with, and should the replacement be a pointer?


  • Lifetime Qt Champion

    Are you trying to print the widget from within himself ?



  • Yes SGaist I am printing from within the widget. (I think) By widget if you mean the form.

    I have code now that work and will post it here. The only catch is that it does not respond to the full page command. It will not use the full 8x11 page.
    Anything I can try would be appreciated.......
    Code:
    ui->pbtPrint->hide();
    ui->pbtExit->hide();
    ui->pbtSave->hide();
    ui->label_rcStatus->hide();

    // this printed the dialog to paper.  Have problem with it filling the 8x12 paper
    QPrinter printer;
    printer.setPaperSize(QPrinter::A4);
    printer.setFullPage(true);
    printer.setNumCopies(2);
    
    QPrintDialog printer_dialog(&printer);
    if (printer_dialog.exec() == QDialog::Accepted) {
    
        QPainter painter(&printer);
        ReceiptsCreate::render(&painter);
    }
    //show print button
    ui->pbtPrint->show();
    ui->pbtExit->show();
    ui->pbtSave->show();
    ui->label_rcStatus->show();

  • Lifetime Qt Champion

    Why are you calling ReceiptsCreate::render and not just render ?

    By the way, why are you doing it from within the widget ? That sounds a bit counter intuitive.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.