Russian Qt Forum

Qt => Печать => Тема начата: crocus от Январь 22, 2006, 06:40



Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 22, 2006, 06:40
Есть необходимость преобразовать текст.
Взял стандартный пример widgets/imageviewer внес изменения
Код:

QPixmap canvas(width(), height());
QPainter p;
p.begin(&canvas);
p.setPen(Qt::blue);
p.drawText(0, 0, QString(text));
p.end();
imageLabel->setPixmap(canvas);

и получаю черный экран.
Версия 4.1
Заработало так:
Код:

void ImageViewer::open()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                       tr("Open File"), QDir::currentPath());

    QFile file(fileName);
   if (!file.open( QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::information(this, tr("HTTP"),
                                 tr("Unable to open the file %1: %2.")
                                 .arg(fileName).arg(file.errorString()));

    }

    QByteArray data = file.readAll();
    QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
    QString str = codec->toUnicode(data);
    file.close();
    QString text = str;
    QPixmap canvas(800, 600);
    QPainter p(&canvas);
    QColor color(0xff, 0xff, 0xff);
    QFont serifFont("MS Shell Dlg", 10);
    p.begin(&canvas);
    p.setPen(color);
    p.fillRect(0, 0, 800, 600, color);
    p.setFont(serifFont);
    for (int i = 0; i < text.size(); ++i)
    {
        //color.setHsv(255, 255, 255);
        QColor color(0, 0, 0);
        p.setPen(color);
        p.drawText(10, 20, QString(text));
    }
    p.end();

    imageLabel->setPixmap(canvas);

............
но косяк текст идет спошняком без переноса по строчкам, хотя
QFile::Text присутствует.

[MODERATOR]
Уважаемые форумчане! НЕ бойтесь пользоватся тегом code. Он не кусается и читать удобнее.
[/MODERATOR]


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: BaltikS от Январь 22, 2006, 11:15
2crocus... Какая версия QT?


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 22, 2006, 18:08
Объясню зачем мне это нужно.
Выбираю данные из БД пользую модель, сортирую, ставлю фильтры
и создаю file.htm(обычная таблица), а далее её (таблицу) необходимо распечатать, предварительно просмотрев, зачем смотреть??? если можно и так отформатировав  распечатать, да наглядно это!!!
а если дорисовать колонтитулы заголовки и т.д. то получится вполне полноценный отчет.
Почему не использую openrpt, ncreport, recall, openRTK??
все эти системы написаны на Qt3  а портировать весь их функционал
нет ни времени, ни желания, ни знаний!!!
Так что если есть схожие с моими проблемы, добро пожаловать устроим brainstorm.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: Dendy от Январь 23, 2006, 10:22
Странно как-то рисовать один и тот же текст несколько раз на одном месте.
А проблема твоя в том, что немного не с той точки начинаешь рисовать.

Код:
p.drawText( x, y, text );


x, y - начинает рисовать с базовой линии шрифта и вверх. Так что начиная рисовать с точки (0,0) увидишь разве что загогулиньІ от букв вверху екрана. ЧтобьІ увидеть весь текст нужно хотя бьІ так:

Код:
p.drawText( 0, QFontMetrics( p.font() ).ascent(), text );


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 23, 2006, 12:41
Пардон за не слишком читаемый код, но критику принимаю конструктивную, здесь уже рисует построчно при наличии \n,
но хотелось бы чтоб рисовал форматированный HTML, предполагаю
что нужно использовать QRect связав с QTextDocument,  но не понятно как.

Код:

void ImageViewer::open()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                       tr("Open File"), QDir::currentPath());

    QFile file(fileName);
    QString text;
    QTextStream stream(&file);


    QPixmap canvas(width(), height());
    QPainter p(&canvas);
    QColor color(0xff, 0xff, 0xff);
    QFont serifFont("MS Shell Dlg", 8);
    p.begin(&canvas);
    p.setPen(color);
    p.fillRect(0, 0, width(), height(), color);
    p.setFont(serifFont);
    if (file.open( QFile::ReadOnly | QFile::Text))
    {
     QString line;
        int k = 1;
        while ( !stream.atEnd() ) {
            line = stream.readLine(); // line of text excluding '\n'
            qDebug() << k++ << line;
            //text += line;
            for (int i = 0; i < line.size(); ++i)
    {
        //color.setHsv(255, 255, 255);
        QColor color(0, 0, 0);
        p.setPen(color);
        p.drawText(10, (k-1)*20, QString(line));
    }
        }
    }
     else
    {
    QMessageBox::information(this, tr("HTTP"),
                                 tr("Unable to open the file %1: %2.")
                                 .arg(fileName).arg(file.errorString()));
    }
    QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
    file.close();

    p.end();

    imageLabel->setPixmap(canvas);

Большое спасибо BaltikS использовался также и твой код.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: BaltikS от Январь 23, 2006, 13:21
Цитировать
Большое спасибо BaltikS использовался также и твой код.
...
Конечно незачто  :lol: .... Только я кода не писал!


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 23, 2006, 13:28
Не скромничай
http://prog.org.ru/forum/htopic_2051_%D4%C5%CB%D3%D4%CF%D7%CF%C7%CF+%C6%C1%CA%CC%C1.html
И кстати мой текст для теста состоит из 39 сторок,  на Р4-2.8 рисуется
около 15 с.- долго неправдали.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: Racheengel от Январь 23, 2006, 14:54
В 3-й было что-то типа QRichTextPainter, вроде бы (название точно не помню), который как раз это и делал...


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 23, 2006, 15:07
Да и у Бланшет есть примеры,
но из четверки этот класс убрали в Q3Support, ближайший по смыслу
QTextDocument,  вот я спрашиваю как его связать с QRect.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 23, 2006, 15:42
2 crocus
Если у тебя формируется простейший HTML, то чем тебе QTextEdit для просмотра HTML не подходит ?


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 23, 2006, 16:16
Для просмотра он вполне подходит, да только это не превью, что называется попробуй распечатай -у меня таблица в страницу не влазит, в идеале хотелось бы как предварительный просмотр в Mozille Firefox.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 23, 2006, 16:43
Цитата: "crocus"
Для просмотра он вполне подходит, да только это не превью, что называется попробуй распечатай -у меня таблица в страницу не влазит, в идеале хотелось бы как предварительный просмотр в Mozille Firefox.

Если хочешь чтоб выглядело так, как будет напечатано, то советую посмотреть исходники метода QTextDocument::print(...). Можно сделать похожим образом, но вместо принтера выводить на экран или в память (pixmap).


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 25, 2006, 08:36
Хотел удалить топик


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 25, 2006, 09:13
Q_D(QTextDocument) это макрос, который объявляет локальную переменную d как указатель на внутренние данные документа:
Код:
Q_D(QTextDocument) --> QTextDocumentPrivate* const d = d_func();


Не совсем понятно что и с чём ты пытаешься связать, и зачем тебе содержимое конструкора QTextDocument.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 26, 2006, 08:27
А при печати в PDF можно ли представлять альбомом, а не портретом
Код:

QPrinter printer(QPrinter::HighResolution);
    printer.setOrientation(QPrinter::Landscape);
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName(fileName);
    QPainter painter(&printer);
        QRect rect = painter.viewport();
        QSize size = imageLabel->pixmap()->size();
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
        painter.setWindow(imageLabel->pixmap()->rect());
        painter.drawPixmap(0, 0, *imageLabel->pixmap());

С этим все равно просматривается портретом, только вписывает правильно, а если убрать
Код:
printer.setOrientation(QPrinter::Landscape);
обрезает рисунок.
И еще- с помощью QTextDocument::print() и плясок с бубном удалось
правильно отображать(рисовать) HTML-код, только с количеством страниц и отображением со 2-й и далее пока непонятно.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 27, 2006, 14:20
Вышибает, если подряд открыть несколько документов и внимательно надо просмотреть QTextDocument::print, где-то что-то проглядел поэтому и рисует только 1 страницу, да и с границами(размерами) косяк.
Код:
void ImageViewer::preview()
{

    QString fileName = QFileDialog::getOpenFileName(this,
                       tr("Open File"), QDir::currentPath());
    QFile file(fileName);
    QString str;
    if (file.open(QFile::ReadOnly))
    {
        QByteArray data = file.readAll();
        QTextCodec *codec = Qt::codecForHtml(data);
        str = codec->toUnicode(data);
        if (Qt::mightBeRichText(str))
        {
            doc->setHtml(str);
        }
        else
        {
            str = QString::fromLocal8Bit(data);
            doc->setHtml(str);
        }
    }
    file.close();
    QColor color(0xff, 0xff, 0xff);
    QPixmap preview(width(), height());
    QPainter p(&preview);
    p.setPen(color);
    p.fillRect(0, 0, width(), height(), color);
    (void)doc->documentLayout(); // make sure that there is a layout
    // QRectF body = QRectF(QPointF(0, 0), size);
    QPointF pageNumberPos;
    extern int qt_defaultDpi();
    qreal sourceDpiX = qt_defaultDpi();
    qreal sourceDpiY = sourceDpiX;
    QPaintDevice *dev = doc->documentLayout()->paintDevice();
    if (dev)
    {
        sourceDpiX = dev->logicalDpiX();
        sourceDpiY = dev->logicalDpiY();
    }
    // scale to dpi
    // QSizeF scaledPageSize = doc->pageSize;
    //const QSizeF printerPageSize(preview.width(), preview.height());
    QAbstractTextDocumentLayout *layout = doc->documentLayout();
    layout->setPaintDevice(p.device());
    const int dpiy = p.device()->logicalDpiY();
    //const int margin = (int) ((2/2.54)*dpiy); // 2 cm margins
    const int margin = 0;
    QTextFrameFormat fmt = doc->rootFrame()->frameFormat();
    fmt.setMargin(margin);
    doc->rootFrame()->setFrameFormat(fmt);

    QRectF body = QRectF(0, 0, p.device()->width(), p.device()->height());
    pageNumberPos = QPointF(body.width() - margin,
                            body.height() - margin
                            + QFontMetrics(doc->defaultFont(), p.device()).ascent()
                            + 5 * p.device()->logicalDpiY() / 72);

    QFont font(doc->defaultFont());
    font.setPointSize(8); // we define 10pt to be a nice base size for printing
    doc->setDefaultFont(font);
    doc->setPageSize(body.size());
    QRectF view(0, 0, body.width(), body.height());
    QAbstractTextDocumentLayout::PaintContext ctx;
    p.setClipRect(view);
    ctx.clip = view;
    layout->draw(&p,ctx);
    imageLabel->setPixmap(preview);
    scaleFactor = 1.0;
    printAct->setEnabled(true);
    fitToWindowAct->setEnabled(true);
    updateActions();

    if (!fitToWindowAct->isChecked())
        imageLabel->adjustSize();
    delete doc;


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 30, 2006, 13:33
Не идет вывод всех страниц :evil:
(http://source.foliant.net.ru/screenshot.gif)
И PDF весь pixmap загоняет в одну страницу :?


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 30, 2006, 15:18
Что значит "Не идет вывод всех страниц" ?
Ты пытаешься все страницы документа в один QPixmap вывести ?


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 30, 2006, 15:49
Нет вывести каждую страницу в свой pixmap наверное не трудно,
не пойму как потом pixmap,ы засунуть в один label?
Связка то идет pixmap-> label -> scrollarea, а у QScrollArea есть только QScrollArea::setWidget, но нет addWidget.
Или я уже куда-то не туда пошел????


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 30, 2006, 16:12
Объединить label'ы можно, запихнув в ScrollArea например QFrame, а в него уже label'ы через QVBoxLayout.
Но хранить preview в картинках это не лучшее решение, очень много памяти будет на это расходоваться. Лучше рисовать не в pixmap, а каждый раз в окно preview, при его перерисовке (paintEvent).

Я сам на днях пытался реализовать print preview, в конце концов мне это удалось,  но не получилось до конца решить проблему масштабирования готового preview.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 30, 2006, 17:01
Я пробывал запихнуть QFrame в QScrollArea не фига не вышло,
а это вообще реально???, просто QFrame без scrola без проблем, а вносишь его (frame) в scroll нечего неотображается.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Январь 30, 2006, 17:18
Цитата: "crocus"
Я пробывал запихнуть QFrame в QScrollArea не фига не вышло,
а это вообще реально???, просто QFrame без scrola без проблем, а вносишь его (frame) в scroll нечего неотображается.

Попробуй изменить размер QFramе после добавления в QScrollArea :
frame->resize(300, 300);


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Январь 31, 2006, 16:45
Сделал так
Код:
frame ->resize(width() * 3, height() * 2);

что пожалуй тоже не совсем верно.
И еще, что значит-

Лучше рисовать не в pixmap, а каждый раз в окно preview, при его перерисовке (paintEvent).


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Февраль 01, 2006, 00:27
Цитата: "crocus"
Добавил
Код:
scrollArea->setWidgetResizable(true);
и resize не требуется.
Но новый косяк исчезли ScrolBar,ы

Скроллбары какраз из за setWidgetResizable изчезли, т.к. ScrollArea теперь автоматически подгоняет размеры починённого фрейма под свои. Сделай вместо этого resize.

Цитата: "crocus"
И еще, что значит-
Лучше рисовать не в pixmap, а каждый раз в окно preview, при его перерисовке (paintEvent).

Имеется ввиду обойтись без всяких QPixmap и QLabel. В место этого в качестве preview будет один QWidget (помещённый в QScrollArea) с переопределённым методом paintEvent(). В paintEvent происходит отрисовка страниц (preview page) или части страниц, которые попадают в область перерисовки.

Я сегодня вечером или завтра постараюсь выложить свой вариант PrintPreview, там именно так реализовано.

добавлено спустя 6 часов 49 минут:

 
Вот моя реализация Print preview QTextDocument'a.
Вариант ещё не до конца закончен, но думаю будет интересен.
(ссылки ниже)

(http://alexbirk.narod.ru/source/printpreview/screen1.png)

Исходники [10KB] http://alexbirk.narod.ru/source/printpreview/printpreview.zip
Исполняемый файл [17KB] (требуется Qt4.1.0) http://alexbirk.narod.ru/source/printpreview/printpreview.exe.zip


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Февраль 07, 2006, 09:25
Цитировать
to nEoN

Собрал на MinGW, сначала поругалось на "friend", что-то сделал - скомпилировалось. Все прикольно, в принципе что и требовалось, только не понял??? При отправке на печать ничего не выводится (те печать не происходит) и кого вообще отправляем на печать,
Код:

{
m_printer->setFullPage(true);
QPrintDialog dlg(m_printer, this);
if (dlg.exec() != QDialog::Accepted)
return;
}
m_printer->setFromTo(1, 1);

m_preview->setDocument(ui.textEdit->document());
m_preview->updatePreview();
updateScaleEdit();

Это баг или чтоб жизнь медом не казалась, :lol:
Типа додумывайте сами!!!


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Февраль 07, 2006, 09:41
Печати там нет, только preview :-)
При нажатии на кнопку "Preview" вылезает окно настройки печати. Это сделано для того, чтобы можно было наблюдать, как Preview реагирует на различные настройки печати/принтера.
А саму печать приделать пара пустяков ;-)


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: Steven_Orko от Февраль 07, 2006, 19:57
Скачал указанный выше пример с "Исходники [10KB] http://alexbirk.narod.ru/source/printpreview/printpreview.zip".
Сходу распаковал в папку, соответствующую названию PRO-файла и открыл в MS VS2005.
Выбрал Build->Batch Build->Select All->Rebuild. Создалось два файла: как вы догадываетесь, Release и Debug.
Запускаю оба файла - работают без проблем. Компиляция тоже прошла без проблем.

ОГРОМНОЕ СПАСИБО nEoN!!!!
Мне это тоже пригодилось при созданиии моего рабочего проекта.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: crocus от Февраль 13, 2006, 17:56
Цитата: "nEoN"

А саму печать приделать пара пустяков ;-)

Ну не догоняю :(
Код:
m_preview->paintTo(m_printer);

Печатает,  но не то что отображает, и перерисовка дважды происходит.
Раз отправил, перерисовала-распечатала, второй -тоже самое, ну и далее без перерисовки печатает.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: Alikus от Апрель 03, 2006, 01:58
У меня такой нескромный вопросик к знающим людям.
Скажите, а можно ли реализовать подобное что сделал nEoN используя библиотеку Qt-3.3.3?

Дело в том что у нас на работе ПС "Конструктор" (я думаю слышали об этом уродце) основан именно на этой версии Qt. И как бы все прекрасные весчи Qt4 отпадают :(

Мне тоже нужно организовать предварительный просмотр текста. Пишу нечто вроде текстового редактора. Я в общем пытался как-то выводить  содержимое художника на QFrame. Но у меня видимо что-то не то было с метриками фрейма или что еще. Кароче с маштабом проблема выходила. Ребят! Подскажите пожалуйста или направьте в нужное русло. Проскальзывал здесь вариант вывода на экран или в пиксмап, но я не совсем понял как именно это реализовать.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Апрель 03, 2006, 09:00
В Qt3 думаю реально сделать подобное.
Советую посмотреть исходники процесса печати Qt Assistant, а именно метод MainWindow::print()
(файл: Qt\3.3.4\tools\assistant\mainwindow.ui.h).

Для предварительного просмотра нужно сделать похожим образом, только рисовать не на принтере, а на виджете. А для изменения масштаба надо менять метрики этого виджета (как именно в Qt3, я не разбирался).


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: Alikus от Апрель 04, 2006, 02:14
Цитата: "nEoN"
В Qt3 думаю реально сделать подобное.
Советую посмотреть исходники процесса печати Qt Assistant, а именно метод MainWindow::print()
(файл: Qt\3.3.4\tools\assistant\mainwindow.ui.h)


Спасибо большое :) Пойду разбираться :) О результатах (плохих или хороших) сообщу позже :)

добавлено спустя 14 часов 36 минут:

 
Цитата: "nEoN"
Для предварительного просмотра нужно сделать похожим образом, только рисовать не на принтере, а на виджете. А для изменения масштаба надо менять метрики этого виджета (как именно в Qt3, я не разбирался).

Я что-то пока не понимаю. А на виджете рисовать используя чьи метрики? И в связи с чем будут размеры картинки QPixmap совпадать или быть подобными размерам страницы А4? Извиняюсь за туманность моих выражений...


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Апрель 04, 2006, 10:42
Никаких QPixmap не надо. QSimpleRichText сразу рисуется на виджет.
А виджет, на котором происходит рисование, должен возвращать разные метрики в зависимости от масштаба.
Например при масштабе 100% он должен возвращать Xdpi, при 50% - (X/2)dpi, при 200% (X*2)dpi.

Соответственно, когда QSimpleRichText будет рисовать на этом виджете линию (например) размером в один дюйм, в пикселях размер будет пропорционален масштабу.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: LestorN от Апрель 04, 2006, 11:08
Может не в тему. Но нашёл хороший способ для предпросмотра печати. Отчёт я формирую в QTextDocument (QT4.1.2) после чего если нужен предпросмотр, то формирую временный PDF файл и смотрю его при помощи библиотеки poppler (которая в CVS уже имеет QT4 обёртку). Единственная загвоздка в том, что я не разобрался можно ли poppler собрать под винду, но мне это пока не критично.

PS. И ещё добавочка poppler фигово документирован но в заголовке qt обёртки отличные комментарии.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: nEoN от Апрель 04, 2006, 11:48
Цитировать
Poppler is a PDF rendering library based on the xpdf-3.0 code base.

Xpdf runs under the X Window System on UNIX, VMS, and OS/2.  The non-X
components (pdftops, pdftotext, etc.) also run on Win32 systems and
should run on pretty much any system with a decent C++ compiler.


Теоретически и на Win32 может собраться, но не полностью, судя по описанию.
Всё равно, чересчур тяжеловат этот механизм получается, для обычного пред. просмотра.


Название: Отчеты!! Преобразование текста в рисунок
Отправлено: LestorN от Апрель 04, 2006, 11:57
Не особо тяжело... На Cel500+128RAM весь процесс на отчёте в 4 страницы занимает секунды две...