在以前的一篇文章中,實現了QT場景視圖的打印功能,主要經過render函數來實現,很是簡單和方便。html
在實際的項目需求中,除了打印整個場景外,還須要對單個圖形進行打印操做,基於item的圖形能夠在paint函數中打在QPrinter做爲繪圖設備實現打印,基於Widget的圖形則提供了更方便的render函數,均可以很好地實現。可是,若是圖形存在父子嵌套關係,則須要在打印該圖形時,連同其子圖形以及孫子圖形也要一塊兒打印出來,爲此,本文對此進行了研究,方便參考。dom
目的:實現QT場景視圖中父子關係打印ide
具體要求: 打印某圖形時,打印其爲根的一顆圖形樹; 打印左上角不留空白區域函數
主要代碼,僅供參考:測試
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#ifndef
MYITEM_H #define MYITEM_H #include <QGraphicsItem> class QPainter; class MyItem : public QGraphicsItem { public : explicit MyItem(QGraphicsItem *parent = nullptr); MyItem( const QString &name, QGraphicsItem *parent = nullptr); // custom item type enum {Type = UserType + 1 }; // overriding bounding rect QRectF boundingRect() const override; // overriding type() int type() const override; // overrriding paint() void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; // recursive print items void printAll(QPainter *painter, // painter int xOffset = 0 , // x偏移 int yOffset = 0 , // y偏移 bool root = true ); // 是不是最頂層item protected : // overriding mouse events virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); private : // actual drawing void draw(QPainter *painter, // painter int xOffset = 0 , // x偏移 int yOffset = 0 // y偏移 ); // find item from full parent/child tree void findInherit(MyItem *itemFind, bool &find); private : QString m_name; QColor m_color; QPointF m_scenePos; }; #endif // MYITEM_H |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
#include
"MyItem.h"
#include <QPainter> #include <QGraphicsScene> #include <QRandomGenerator> #include <QPrinter> #include <QPrintDialog> MyItem::MyItem(QGraphicsItem *parent) : QGraphicsItem (parent) , m_name( "" ) { // radom color m_color.setRed(QRandomGenerator::global()->bounded( 255 )); m_color.setGreen(QRandomGenerator::global()->bounded( 255 )); m_color.setBlue(QRandomGenerator::global()->bounded( 255 )); // item options setFlag(ItemIsMovable); setFlag(ItemIsSelectable); } MyItem::MyItem( const QString &name, QGraphicsItem *parent) : QGraphicsItem (parent) , m_name(name) { // radom color m_color.setRed(QRandomGenerator::global()->bounded( 255 )); m_color.setGreen(QRandomGenerator::global()->bounded( 255 )); m_color.setBlue(QRandomGenerator::global()->bounded( 255 )); // item options setFlag(ItemIsMovable); setFlag(ItemIsSelectable); } QRectF MyItem::boundingRect() const { // outer most edges return QRectF( 0 , 0 , 100 , 100 ); } int MyItem::type() const { // Enable the use of qgraphicsitem_cast with this item. return Type; } void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); draw(painter); } void MyItem::printAll(QPainter *painter, int xOffset, int yOffset, bool root) { if (root) { bool bFindH = false ; bool bFindV = false ; unsigned int xPos = scenePos().x(); unsigned int yPos = scenePos().y(); // 若是其child item不在其座標的左上區域,則移除打印的左上角空白區域 QRectF rectBlankH = QRectF( 0 . 0 , 0 . 0 , scene()->width(), scenePos().y()); QRectF rectBlankV = QRectF( 0 . 0 , 0 . 0 , scenePos().x(), scene()->height()); // 水平區域 QList<QGraphicsItem *> itemListH = scene()->items(rectBlankH); foreach (QGraphicsItem *item, itemListH) { if (item->type() == MyItem::Type) { MyItem *itemTmp = qgraphicsitem_cast<MyItem *>(item); if (itemTmp != nullptr) { bool find = false ; findInherit(itemTmp, find); if (find) { bFindH = true ; if (itemTmp->m_scenePos.y() < yPos) { yPos = itemTmp->m_scenePos.y() < 0 ? 0 : itemTmp->m_scenePos.y(); } } } } } if (bFindH) { painter->translate(-QPointF( 0 . 0 , yPos)); } else { painter->translate(-QPointF( 0 . 0 , scenePos().y())); } // 垂直區域 QList<QGraphicsItem *> itemListV = scene()->items(rectBlankV); foreach (QGraphicsItem *item, itemListV) { if (item->type() == MyItem::Type) { MyItem *itemTmp = qgraphicsitem_cast<MyItem *>(item); if (itemTmp != nullptr) { bool find = false ; findInherit(itemTmp, find); if (find) { bFindV = true ; if (itemTmp->m_scenePos.x() < xPos) { xPos = itemTmp->m_scenePos.x() < 0 ? 0 : itemTmp->m_scenePos.x(); } } } } } if (bFindV) { painter->translate(-QPointF(xPos, 0 . 0 )); } else { painter->translate(-QPointF(scenePos().x(), 0 . 0 )); } } draw(painter, m_scenePos.x(), m_scenePos.y()); QList<QGraphicsItem *> childList = childItems(); foreach (QGraphicsItem *item, childList) { if (item->type() == MyItem::Type) { MyItem *myChilditem = qgraphicsitem_cast<MyItem *>(item); if (myChilditem != nullptr) { myChilditem->printAll(painter, m_scenePos.x(), m_scenePos.y(), false ); } } } } void MyItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { QPrinter printer; QPrintDialog printDlg(&printer); if (printDlg.exec()) { QPainter painter(&printer); QRectF rect = scene()->sceneRect(); painter.translate(-rect.x(), -rect.y()); printAll(&painter); } } void MyItem::draw(QPainter *painter, int xOffset, int yOffset) { QRectF rect = boundingRect(); qreal width = rect.width(); qreal height = rect.height(); rect.setX(xOffset); rect.setY(yOffset); rect.setWidth(width); rect.setHeight(height); painter->drawText(rect.x() + rect.width() / 2 , rect.y() + rect.height() / 2 , m_name); QPen pen(m_color, 2 ); painter->setPen(pen); painter->drawRect(rect); m_scenePos = scenePos(); } void MyItem::findInherit(MyItem *itemFind, bool &find) { QList<QGraphicsItem *> childList = childItems(); if (childList.size() > 0 ) { foreach (QGraphicsItem *item, childList) { if (item->type() == MyItem::type()) { MyItem *itemChild = qgraphicsitem_cast<MyItem *>(item); if (itemChild != nullptr) { if (itemChild == itemFind) { find = true ; } itemChild->findInherit(itemFind, find); } } } } } |
測試代碼:this
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
m_view =
new
QGraphicsView(
this
); m_scene = new QGraphicsScene(); m_scene->setSceneRect( 0 . 0 , 0 . 0 , 800 . 0 , 800 . 0 ); m_view->setScene(m_scene); // 繪製場景座標系 QPen pen(Qt::black, 1 , Qt::DashLine); m_scene->addLine(QLineF(- 400 . 0 , 0 . 0 , 400 , 0 . 0 ), pen); m_scene->addLine(QLineF( 0 . 0 , - 400 , 0 . 0 , 400 . 0 ), pen); // item-based MyItem *item = new MyItem( "parent" ); m_scene->addItem(item); MyItem *child1 = new MyItem( "child1" ); child1->setParentItem(item); child1->setPos(- 100 , - 100 ); m_scene->addItem(child1); MyItem *child2 = new MyItem( "child2" ); child2->setParentItem(item); child2->setPos( 100 , 100 ); m_scene->addItem(child2); MyItem *child21 = new MyItem( "child21" ); child21->setParentItem(child2); child21->setPos( 50 , 50 ); m_scene->addItem(child21); |