как распечатать QGraphicsScene с текстом и графикой

У меня есть QGraphicsScene, на котором есть графика и текст. Когда я пытаюсь распечатать, графика в порядке, но текст использует размер шрифта, определенный в пунктах, поэтому scene->render(), когда я передаю его QPainter, инициализированному QPrinter, имеет ОЧЕНЬ большой текст.

Как я должен напечатать QGraphicsScene, на котором есть текст?

редактировать:

Вот мой текущий код печати, где scene_ — мой собственный подкласс QGraphicsScene:

  QPrinter printer(QPrinter::HighResolution);
  QPrintDialog dialog(&printer, this);
  dialog.exec();
  std::cout << printer.resolution() << std::endl;
  QPainter painter(&printer);
  scene_->render(&painter);

Строка std:cout не имеет никакого значения. Принтер по-прежнему считает текст огромным, поэтому для каждого элемента текста печатается только крошечная часть первой буквы.


person David Burson    schedule 09.09.2010    source источник


Ответы (2)


Из QPrinter docs следует, что вам нужно указать размеры шрифта в пикселей, чтобы текст и графика совпадали. Обратите внимание, что QFont имеет метод setPixelSize.

person Troubadour    schedule 09.09.2010
comment
Это делает шрифт зависимым от устройства. У моих пользователей может быть несколько мониторов, и я не хочу рассчитывать шрифт в пикселях для одного монитора, а потом перетаскивают его на другой монитор, и он выглядит плохо. - person David Burson; 10.09.2010
comment
Или мне нужно использовать обычный размер в точках, но когда пользователь печатает, повторять весь мой текст и повторно вычислять шрифты в пикселях? Надеюсь, есть лучший способ? - person David Burson; 10.09.2010
comment
@David Burson: Работа на мониторе и на принтере обязательно будет зависеть от устройства. Установка размера в пунктах и ​​независимость от устройства означает, что текст размером 72 пункта всегда будет иметь высоту один дюйм, независимо от того, находится ли он на печатном листе бумаги или на мониторах с различным разрешением. Итак, да, я думаю, что вы должны относиться к принтеру как к частному случаю и работать с размером пикселя. - person Troubadour; 10.09.2010
comment
это имеет смысл, но есть ли лучший способ справиться с печатью, чем перебирать каждый текстовый объект, сбрасывать его шрифт до рассчитанного размера в пикселях, отображать сцену на принтер, затем перебирать все текстовые объекты и сбрасывать их шрифты обратно? до нужного размера точки? - person David Burson; 10.09.2010
comment
@David Burson: Вы можете поместить код в свою повторную реализацию paint для ваших текстовых объектов. Запросите device() художника, и если он динамически приводит к QPrinter, используйте размеры в пикселях. В качестве альтернативы, если ваша графика и текст очень сильно зависят от размеров друг друга, вам может быть лучше везде использовать размеры в пикселях. - person Troubadour; 15.09.2010
comment
размеры в пикселях везде кажутся лучшим выбором, и теперь он работает на нас. - person David Burson; 20.09.2010

Настройка QPrinter:

По умолчанию объект QPrinter инициализируется разрешением экрана (обычно 96 точек на дюйм), если вы не укажете QPrinter::HighResolution в конструкторе, который затем будет использовать разрешение используемого принтера.

Если вы настраиваете объект QPrinter с помощью QPrintDialog, тогда код должен выглядеть примерно так:

QPrinter printer(QPrinter::HighResolution);
QPrintDialog dialog(&printer, this);
dialog.exec();
std::cout << printer.resolution() << std::endl;

После этого программа должна вывести DPI выбранного принтера. В моем случае он печатает 600.

Если вы не используете QPrintDialog, вы должны использовать конструктор QPrinter, как показано выше, а затем вызвать setResolution(DPI) с известным DPI вашего принтера.

Это должно привести к правильному отображению шрифтов.

Обновление:

Теперь, когда наступили выходные, у меня наконец-то появилось время, чтобы как следует рассмотреть этот вопрос :) Хотя приведенное выше решение технически правильно для настройки QPrinter, оно нецелесообразно для графических сцен, содержащих текст, указанный в пунктах. Поскольку все графические элементы задаются в пиксельных координатах, имеет смысл указывать размеры шрифта только в пикселях, чтобы шрифты выглядели точно так, как ожидается, при смешивании с другими графическими примитивами.

Не нужно беспокоиться о размере текста на разных мониторах, поскольку сами графические элементы не зависят от разрешения. Представление может задавать переводы масштаба для работы с мониторами с разным разрешением и DPI.

При печати по умолчанию QPrinter масштабируется так, чтобы вся сцена помещалась на странице. Это имеет смысл, поскольку квадрат 100 x 100 на принтере с разрешением 600 точек на дюйм будет иметь ширину 1/6 дюйма на вашей бумаге :)

person Arnold Spence    schedule 10.09.2010
comment
Я хотел бы использовать QPrintDialog. Я попробовал ваше решение, но оно не дало результата - я новичок в C++ и Qt и, вероятно, что-то пропустил. Я также добавил #include ‹iostream›, чтобы заставить std::cout компилироваться. Мой полный код печати теперь добавлен к моему первоначальному вопросу - есть мысли? - person David Burson; 10.09.2010
comment
Cout просто есть, чтобы вы могли видеть, выбрал ли QPrinter правильную настройку DPI из QPrintDialog. Что он распечатывает для вас после того, как вы нажмете «печатать» в диалоговом окне? (вы должны запускать свою программу из консоли, чтобы вы могли видеть вывод, если ваша среда IDE не показывает его вам.) - person Arnold Spence; 10.09.2010
comment
600 - это то, что он печатает для разрешения принтера. - person David Burson; 10.09.2010
comment
Тогда это звучит правильно. Я проведу несколько экспериментов сегодня вечером и посмотрю, какие результаты я получу. Я поделюсь любой информацией, которую я соберу, хотя это может быть не так скоро, как вам нужно двигаться дальше :) - person Arnold Spence; 10.09.2010
comment
спасибо - мне очень приятно! Кстати, если это имеет значение, мои текстовые объекты на сцене являются пользовательским подклассом QGraphicsObject, в котором (среди прочего) переопределена краска, позволяющая рисовать текст вдоль кривой. Думаю, я бы упомянул об этом на тот случай, если то, как текст попадет на сцену, имеет значение. - person David Burson; 10.09.2010