Документ для экспорта QWidget-ов
От: snam  
Дата: 28.09.18 06:28
Оценка:
Есть QVBoxLayout, который содержит большое количество QWidget.
Причем они выровнены по разным краям. Хотелось бы экспортировать
все виджеты в pdf или html в виде картинок компонентов.

Попробовал использовать QPdfWriter, но ручная отрисовка осложняется
выравниванием картинок и отслеживанием конца страницы.

Если ли какой более простой способ положить картинки виджетов в какой-нибудь
многостраничный документ?

Ну или создать какой документ с возможностью накидать в него картинки с выравниванием,
и потом его же экспортировать в pdf или html.
Re: Документ для экспорта QWidget-ов
От: SaZ  
Дата: 28.09.18 10:28
Оценка:
Здравствуйте, snam, Вы писали:

S>Есть QVBoxLayout, который содержит большое количество QWidget.

S>Причем они выровнены по разным краям. Хотелось бы экспортировать
S>все виджеты в pdf или html в виде картинок компонентов.
S>...

У вас вопрос, как создать pdf или как отрендерить виджет в картинку?
Re: Документ для экспорта QWidget-ов
От: Chorkov Россия  
Дата: 28.09.18 10:39
Оценка: +1
Здравствуйте, snam, Вы писали:

S>...

S>Попробовал использовать QPdfWriter, но ручная отрисовка осложняется
S>выравниванием картинок и отслеживанием конца страницы.

Выравнивание по сторонам, оставить на откуп дочерним layout-ам, а задача отслеживания конца страницы не кажется очень сложной.

  пример

void printWidget(QWidget & widget, QPrinter &printer)
{
    QPainter painter;
    painter.begin(&printer);
    painter.setPen(Qt::black);
    painter.setFont(QFont("Times", 10));

    auto page_size= printer.pageRect().size(); // paper.size - margings
    auto page_h = page_size.height();

    widget.setBaseSize(page_size);
    widget.setMinimumWidth(page_size.width());
    widget.setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );

    int h_pos =0;
    int left_h = page_h; // место оставшееся на странице

    auto newPage=[&](){
        if(h_pos!=0)
            printer.newPage(); // No empty pages!
        left_h = page_h;
        h_pos  = 0;
    };
    auto printRect=[&](QRect r)
    {
        int h=r.height();
        // assert( h <= left_h );
        widget.render(&painter, QPoint(0, h_pos), r, QWidget::DrawChildren);
        left_h -= h;
        h_pos  += h;
    };
    auto printMultipageRect=[&](QRect rect)
    {
        if( rect.height() > left_h )
        {
            newPage();
            while( rect.height() > left_h )
            {
                QRect hight=QRect( rect.left(), rect.top(), rect.width(), left_h);
                QRect low=QRect( rect.left(), rect.top()+left_h, rect.width(), rect.height()-left_h);
                printRect(hight);
                rect = low;
                newPage();
            }
        }
        printRect(rect);
    };

    auto layout = widget.layout();
    if(dynamic_cast<QVBoxLayout*>(layout)==nullptr)
    {
        // печатаем не глядя на layout
        printMultipageRect( widget.geometry() );
    }
    else
    {
        auto&v_box = dynamic_cast<QVBoxLayout&>(*layout);
        for( int i=0; i< v_box.count(); ++i )
        {
            QLayoutItem* item=v_box.itemAt(i);
            if( item!=nullptr && item->spacerItem()==nullptr )
                printMultipageRect(item->geometry());
        }
    }

    painter.end();
}

void printPreviewDialog(QWidget & widget, QString pdfFilePath)
{

    QPrinter printer;
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setPageSize(QPrinter::A4);
    printer.setOutputFileName(pdfFilePath);

    QPrintPreviewDialog preview_dlg(&printer);
    preview_dlg.connect(&preview_dlg, &QPrintPreviewDialog::paintRequested,
                        [&widget](QPrinter *p){ printWidget(widget, *p); } );
    preview_dlg.exec();
}


S>Если ли какой более простой способ положить картинки виджетов в какой-нибудь

S>многостраничный документ?

S>Ну или создать какой документ с возможностью накидать в него картинки с выравниванием,

S>и потом его же экспортировать в pdf или html.

1) Отпечатать дочерние виджеты в SVG и положить их в HTML, работая с HTML, как с обычным текстовым файлом. HTML-тэги в соответствии с выравниванием виджетов (ИМХО) обработать сложнее.
2) Отпечатать дочерние виджеты в картинки (QImage) и вставлять их в QTextDocument см. https://www.qtcentre.org/threads/58566-Insert-QPixmap-in-QTextDocument Потом экспортировать документ в HTML.
Re[2]: Документ для экспорта QWidget-ов
От: snam  
Дата: 04.10.18 13:52
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>Здравствуйте, snam, Вы писали:


S>>...

S>>Попробовал использовать QPdfWriter, но ручная отрисовка осложняется
S>>выравниванием картинок и отслеживанием конца страницы.

C>Выравнивание по сторонам, оставить на откуп дочерним layout-ам, а задача отслеживания конца страницы не кажется очень сложной.


C>
  пример
C>

C>void printWidget(QWidget & widget, QPrinter &printer)
C>{
C>    QPainter painter;
C>    painter.begin(&printer);
C>    painter.setPen(Qt::black);
C>    painter.setFont(QFont("Times", 10));

C>    auto page_size= printer.pageRect().size(); // paper.size - margings
C>    auto page_h = page_size.height();

C>    widget.setBaseSize(page_size);
C>    widget.setMinimumWidth(page_size.width());
C>    widget.setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );

C>    int h_pos =0;
C>    int left_h = page_h; // место оставшееся на странице

C>    auto newPage=[&](){
C>        if(h_pos!=0)
C>            printer.newPage(); // No empty pages!
C>        left_h = page_h;
C>        h_pos  = 0;
C>    };
C>    auto printRect=[&](QRect r)
C>    {
C>        int h=r.height();
C>        // assert( h <= left_h );
C>        widget.render(&painter, QPoint(0, h_pos), r, QWidget::DrawChildren);
C>        left_h -= h;
C>        h_pos  += h;
C>    };
C>    auto printMultipageRect=[&](QRect rect)
C>    {
C>        if( rect.height() > left_h )
C>        {
C>            newPage();
C>            while( rect.height() > left_h )
C>            {
C>                QRect hight=QRect( rect.left(), rect.top(), rect.width(), left_h);
C>                QRect low=QRect( rect.left(), rect.top()+left_h, rect.width(), rect.height()-left_h);
C>                printRect(hight);
C>                rect = low;
C>                newPage();
C>            }
C>        }
C>        printRect(rect);
C>    };

C>    auto layout = widget.layout();
C>    if(dynamic_cast<QVBoxLayout*>(layout)==nullptr)
C>    {
C>        // печатаем не глядя на layout
C>        printMultipageRect( widget.geometry() );
C>    }
C>    else
C>    {
C>        auto&v_box = dynamic_cast<QVBoxLayout&>(*layout);
C>        for( int i=0; i< v_box.count(); ++i )
C>        {
C>            QLayoutItem* item=v_box.itemAt(i);
C>            if( item!=nullptr && item->spacerItem()==nullptr )
C>                printMultipageRect(item->geometry());
C>        }
C>    }

C>    painter.end();
C>}

C>void printPreviewDialog(QWidget & widget, QString pdfFilePath)
C>{

C>    QPrinter printer;
C>    printer.setOutputFormat(QPrinter::PdfFormat);
C>    printer.setPageSize(QPrinter::A4);
C>    printer.setOutputFileName(pdfFilePath);

C>    QPrintPreviewDialog preview_dlg(&printer);
C>    preview_dlg.connect(&preview_dlg, &QPrintPreviewDialog::paintRequested,
C>                        [&widget](QPrinter *p){ printWidget(widget, *p); } );
C>    preview_dlg.exec();
C>}

C>



S>>Если ли какой более простой способ положить картинки виджетов в какой-нибудь

S>>многостраничный документ?

S>>Ну или создать какой документ с возможностью накидать в него картинки с выравниванием,

S>>и потом его же экспортировать в pdf или html.

C>1) Отпечатать дочерние виджеты в SVG и положить их в HTML, работая с HTML, как с обычным текстовым файлом. HTML-тэги в соответствии с выравниванием виджетов (ИМХО) обработать сложнее.

C>2) Отпечатать дочерние виджеты в картинки (QImage) и вставлять их в QTextDocument см. https://www.qtcentre.org/threads/58566-Insert-QPixmap-in-QTextDocument Потом экспортировать документ в HTML.

Спасибо. Понял.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.