學(xué)習(xí)筆記圖形視圖框架_第1頁
學(xué)習(xí)筆記圖形視圖框架_第2頁
學(xué)習(xí)筆記圖形視圖框架_第3頁
學(xué)習(xí)筆記圖形視圖框架_第4頁
學(xué)習(xí)筆記圖形視圖框架_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Qt學(xué)習(xí)筆記-圖形視圖框架(一)2010-07-11 07:40優(yōu)點:處理多個圖元,單擊,拖動,選擇圖元架構(gòu):一個場景,多個圖元位于其中,通過視圖顯示主要應(yīng)用: 繪圖軟件,顯示地圖軟件當(dāng)使用沒有變換的視圖觀察場景時,場景中的一個單元對應(yīng)屏幕上的一個像素圖元坐標(biāo)通常以圖元中心為原點,X軸正方向為向右,Y軸正方向為向下場景坐標(biāo)的原點在場景中心,X軸正方向為向右,Y軸正方向為向下視圖坐標(biāo)以左上角為原點,X軸正方向為向右,Y軸正方向為向下所有的鼠標(biāo)事件最開始都是使用視圖坐標(biāo)場景:圖元的容器1.提供管理很多圖元的接口2.傳播事件到圖元中3.管理圖元狀態(tài),例如選擇和焦點處理4.提供非轉(zhuǎn)換的繪制功能,主要用

2、于打印QGraphicsScene scene;QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100); / 添加圖元QGraphicsItem *item = scene.itemAt(50, 50); / 查詢圖元/ item = rect;通過QGraphicsScene:setSelectionArea()可以選擇場景的任一個圖元,QGraphicsScene:setSelectedItems()返回被選擇的圖元設(shè)置焦點圖元QGraphicsScene:setFocusItem(), setFocus(),QGrap

3、hicsScene:focusItem(), 返回焦點圖元視圖:一個可視的子部件,可視化場景的內(nèi)容多個視圖可以顯示同一個場景坐標(biāo)轉(zhuǎn)換:QGraphicsView:mapToScene(), QGraphicsView:mapFromScene()圖元:支持鼠標(biāo)事件,滾輪事件,上下文菜單事件支持鍵盤輸入焦點,按鍵事件支持拖放支持分組沖突探測提供坐標(biāo)轉(zhuǎn)換,圖元與場景,圖元與圖元之間利用QGraphicsItem:shape()和QGraphicsItem:collidesWith()實現(xiàn)沖突探測,這2個函數(shù)都是虛函數(shù)相關(guān)類:QGraphicsScene, QGraphicsItem, QGraph

4、icsViewQGraphicsItem子類:QGraphicsEllipseItem provides an ellipse itemQGraphicsLineItem provides a line itemQGraphicsPathItem provides an arbitrary path itemQGraphicsPixmapItem provides a pixmap itemQGraphicsPolygonItem provides a polygon itemQGraphicsRectItem provides a rectangular itemQGraphicsSimpl

5、eTextItem provides a simple text label itemQGraphicsTextItem provides an advanced text browser itemQGraphicsSvgItem provides a SVG file itemQGraphicsScene:擁有多個圖元,包含三層:背景層,圖元層,前景層背景層和前景層可以使用QBrush繪制,也可以使用drawBackground(),drawForeground()實現(xiàn)如果使用圖片作為背景,可以用texture QBrush(pixmap)實現(xiàn)前景層brush可以使用半透明的白色實現(xiàn)褪色效果

6、,或者使用交叉模式實現(xiàn)網(wǎng)格重疊場景可以告訴我們,哪些圖元發(fā)生沖突,哪些圖元被選擇,哪些圖元位于一個特定的點或者區(qū)域每個圖元可以是:1.頂級圖元,場景是它的父親;2.孩子,它的父親是另一個圖元,任何作用于父圖元的轉(zhuǎn)換都將自動應(yīng)用于它的孩子2種分組方式:1.一個圖元成為另一個圖元的孩子; 2.使用QGraphicsItemGroup。使用分組,可以使位于同一個組的所有圖元的操作都相同QGraphicsView:是一個Widget,用于顯示一個場景,提供滾動條功能和轉(zhuǎn)換功能,可以縮放和旋轉(zhuǎn)場景。默認(rèn)使用內(nèi)建的2D畫圖引擎,可以使用OpenGL:在構(gòu)造后,調(diào)用setViewport()坐標(biāo)系統(tǒng):使用3

7、種坐標(biāo)系統(tǒng):viewport, scene, itemviewport: 位于QGraphicsView內(nèi)部scene: 邏輯坐標(biāo)用于定位頂級圖元item: 與圖元相關(guān),以圖元的(0,0)為中心,移動圖元時,它的坐標(biāo)不會改變實踐中,主要關(guān)注場景坐標(biāo)(定位頂級圖元)和圖元坐標(biāo)(定位子圖元和繪制圖元)在圖元自己的坐標(biāo)系統(tǒng)里面繪圖意味著我們不用擔(dān)心它在場景中的位置和應(yīng)用于它的坐標(biāo)轉(zhuǎn)換Demo:/ 主要特點:/ 上下文菜單, 右鍵菜單/ copy->paste方法/TEMPLATE = appHEADERS = diagramwindow.h link.h node.h p

8、ropertiesdialog.hSOURCES = diagramwindow.cpp link.cpp main.cpp node.cpp propertiesdialog.cppFORMS = propertiesdialog.uiRESOURCES = resources.qrc/link.h#ifndef LINK_H#define LINK_H#include <QGraphicsLineItem>class Node;class Link : public QGraphicsLineItem / 如果使用信號和槽,采用多繼承public QObjectpublic:L

9、ink(Node *fromNode, Node *toNode);Link();Node *fromNode() const;Node *toNode() const;void setColor(const QColor &color);QColor color() const;void trackNodes(); / 節(jié)點移動時,跟蹤節(jié)點private:Node *myFromNode; / 連線的2個節(jié)點Node *myToNode;#endif/link.cpp#include <QtGui>#include "link.h"#include &

10、quot;node.h"Link:Link(Node *fromNode, Node *toNode)myFromNode = fromNode;myToNode = toNode;myFromNode->addLink(this); / 節(jié)點增加連線,每個節(jié)點有任意多個連線myToNode->addLink(this);setFlags(QGraphicsItem:ItemIsSelectable); / 連線可以被選擇,然后刪除setZValue(-1); / 在場景中顯示的前后層次,因為連線是兩個節(jié)點的中心,-1表示位于最后面,/ 節(jié)點覆蓋了部分連線setColor

11、(Qt:darkRed); / 設(shè)置線的顏色trackNodes();Link:Link()myFromNode->removeLink(this); / 刪除連線時,將刪除它在節(jié)點中的記錄myToNode->removeLink(this);Node *Link:fromNode() constreturn myFromNode;Node *Link:toNode() constreturn myToNode;void Link:setColor(const QColor &color)setPen(QPen(color, 1.0);QColor Link:color()

12、 constreturn pen().color();void Link:trackNodes()/ pos()返回節(jié)點在場景中或者父圖元中的位置setLine(QLineF(myFromNode->pos(), myToNode->pos();/node.h#ifndef NODE_H#define NODE_H#include <QApplication>#include <QColor>#include <QGraphicsItem>#include <QSet>class Link;class Node : public QG

13、raphicsItemQ_DECLARE_TR_FUNCTIONS(Node) / 在此類中增加tr()功能,直接使用,而不需要QObject:tr()了public:Node();Node();void setText(const QString &text);QString text() const;void setTextColor(const QColor &color);QColor textColor() const;void setOutlineColor(const QColor &color);QColor outlineColor() const;v

14、oid setBackgroundColor(const QColor &color);QColor backgroundColor() const;void addLink(Link *link);void removeLink(Link *link);QRectF boundingRect() const; / 重新實現(xiàn),決定一個圖元是否需要繪制,必須的QPainterPath shape() const; / 重新實現(xiàn),返回圖元的精確形狀,/ 決定一個點是否在圖元內(nèi),或者2個圖元是否發(fā)生沖突void paint(QPainter *painter, / 重新實現(xiàn),畫圖, 必須的c

15、onst QStyleOptionGraphicsItem *option, QWidget *widget);protected:void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); / 雙擊事件,修改節(jié)點的文本QVariant itemChange(GraphicsItemChange change, / 重新實現(xiàn),圖元變化時,相關(guān)的連線發(fā)生變化const QVariant &value); / 沒有使用mouseMoveEvent(), / 是因為程序可以改變節(jié)點位置private:QRectF outlineR

16、ect() const;int roundness(double size) const;QSet<Link *> myLinks;QString myText;QColor myTextColor;QColor myBackgroundColor;QColor myOutlineColor;#endif/link.cpp#include <QtGui>#include "link.h"#include "node.h"Node:Node()myTextColor = Qt:darkGreen;myOutlineColor = Q

17、t:darkBlue;myBackgroundColor = Qt:white;setFlags(ItemIsMovable | ItemIsSelectable); / 節(jié)點可以移動,被選擇Node:Node()foreach (Link *link, myLinks) / 刪除所有的連線,防止邊界效應(yīng),不使用aDeleteAll()delete link;void Node:setText(const QString &text)prepareGeometryChange(); / 改變節(jié)點內(nèi)的文本時,矩形可能會發(fā)生變化myText = text;update();QString

18、Node:text() constreturn myText;void Node:setTextColor(const QColor &color)myTextColor = color;update();QColor Node:textColor() constreturn myTextColor;void Node:setOutlineColor(const QColor &color)myOutlineColor = color;update();QColor Node:outlineColor() constreturn myOutlineColor;void Node

19、:setBackgroundColor(const QColor &color)myBackgroundColor = color;update();QColor Node:backgroundColor() constreturn myBackgroundColor;void Node:addLink(Link *link)myLinks.insert(link); / 增加連線時,記錄連線void Node:removeLink(Link *link)myLinks.remove(link);QRectF Node:boundingRect() const / View決定是否繪制

20、矩形const int Margin = 1;return outlineRect().adjusted(-Margin, -Margin, +Margin, +Margin);QPainterPath Node:shape() const / View用于沖突探測QRectF rect = outlineRect();QPainterPath path;path.addRoundRect(rect, roundness(rect.width(),roundness(rect.height();return path;/ 繪制圖元void Node:paint(QPainter *painte

21、r,const QStyleOptionGraphicsItem *option,QWidget * /* widget */)QPen pen(myOutlineColor);if (option->state & QStyle:State_Selected) / 圖元被選擇pen.setStyle(Qt:DotLine);pen.setWidth(2);painter->setPen(pen);painter->setBrush(myBackgroundColor);QRectF rect = outlineRect();painter->drawRound

22、Rect(rect, roundness(rect.width(),roundness(rect.height();painter->setPen(myTextColor);painter->drawText(rect, Qt:AlignCenter, myText);/ 雙擊節(jié)點,彈出標(biāo)準(zhǔn)輸入對話框void Node:mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)QString text = QInputDialog:getText(event->widget(),tr("Edit Text"

23、), tr("Enter new text:"),QLineEdit:Normal, myText);if (!text.isEmpty()setText(text);/ 拖動節(jié)點時,調(diào)用此函數(shù)QVariant Node:itemChange(GraphicsItemChange change,const QVariant &value)if (change = ItemPositionHasChanged) foreach (Link *link, myLinks)link->trackNodes();return QGraphicsItem:itemCha

24、nge(change, value);QRectF Node:outlineRect() constconst int Padding = 8;QFontMetricsF metrics = qApp->font();QRectF rect = metrics.boundingRect(myText);rect.adjust(-Padding, -Padding, +Padding, +Padding);rect.translate(-rect.center();return rect;int Node:roundness(double size) constconst int Diam

25、eter = 12;return 100 * Diameter / int(size);/ diagramwindow.h#ifndef DIAGRAMWINDOW_H#define DIAGRAMWINDOW_H#include <QMainWindow>#include <QPair>class QAction;class QGraphicsItem;class QGraphicsScene;class QGraphicsView;class Link;class Node;class DiagramWindow : public QMainWindowQ_OBJE

26、CTpublic:DiagramWindow();private slots:void addNode();void addLink();void del();void cut();void copy();void paste();void bringToFront();void sendToBack();void properties(); / 彈出屬性設(shè)置對話框void updateActions(); / 更新菜單欄和工具欄的動作,哪些可用,哪些不可用private:typedef QPair<Node *, Node *> NodePair;void createActio

27、ns();void createMenus();void createToolBars();void setZValue(int z);void setupNode(Node *node);Node *selectedNode() const;Link *selectedLink() const;NodePair selectedNodePair() const;QMenu *fileMenu;QMenu *editMenu;QToolBar *editToolBar;QAction *exitAction;QAction *addNodeAction;QAction *addLinkActi

28、on;QAction *deleteAction;QAction *cutAction;QAction *copyAction;QAction *pasteAction;QAction *bringToFrontAction;QAction *sendToBackAction;QAction *propertiesAction;QGraphicsScene *scene;QGraphicsView *view;int minZ; / sendToBack(), bringToFront()使用int maxZ;int seqNumber; / 唯一標(biāo)示一個節(jié)點的文本;#endif/digram

29、window.cpp#include <QtGui>#include "diagramwindow.h"#include "link.h"#include "node.h"#include "propertiesdialog.h"DiagramWindow:DiagramWindow()scene = new QGraphicsScene(0, 0, 600, 500); / 創(chuàng)建場景,起始點為(0,0), 寬600,高500view = new QGraphicsView;view->setSc

30、ene(scene); / 顯示場景view->setDragMode(QGraphicsView:RubberBandDrag); / 選擇多個節(jié)點方式:1.按ctrl;2.設(shè)置橡皮筋方式view->setRenderHints(QPainter:Antialiasing| QPainter:TextAntialiasing);view->setContextMenuPolicy(Qt:ActionsContextMenu); / 右鍵菜單setCentralWidget(view);minZ = 0;maxZ = 0;seqNumber = 0;createActions

31、();createMenus();createToolBars();connect(scene, SIGNAL(selectionChanged(),this, SLOT(updateActions();setWindowTitle(tr("Diagram");updateActions();/ 增加一個節(jié)點void DiagramWindow:addNode()Node *node = new Node;node->setText(tr("Node %1").arg(seqNumber + 1);setupNode(node);void Diag

32、ramWindow:addLink()NodePair nodes = selectedNodePair();if (nodes = NodePair()return;Link *link = new Link(nodes.first, nodes.second);scene->addItem(link);/ 刪除選擇的圖元:首先刪除連線,然后刪除節(jié)點,以防止多次刪除同一個連線void DiagramWindow:del()QList<QGraphicsItem *> items = scene->selectedItems();QMutableListIterator

33、<QGraphicsItem *> it(items);while (it.hasNext() Link *link = dynamic_cast<Link *>(it.next();if (link) delete link;it.remove();qDeleteAll(items);/ 剪切操作:先復(fù)制,后刪除void DiagramWindow:cut()Node *node = selectedNode();if (!node)return;copy();delete node;/ 拷貝操作:值得研究!void DiagramWindow:copy()Node

34、*node = selectedNode();if (!node)return;QString str = QString("Node %1 %2 %3 %4").arg(node->textColor().name().arg(node->outlineColor().name().arg(node->backgroundColor().name().arg(node->text();QApplication:clipboard()->setText(str);void DiagramWindow:paste()QString str = Q

35、Application:clipboard()->text();QStringList parts = str.split(" ");if (parts.count() >= 5 && parts.first() = "Node") Node *node = new Node;node->setText(QStringList(parts.mid(4).join(" "); / 連接字符串列表node->setTextColor(QColor(parts1);node->setOutlin

36、eColor(QColor(parts2);node->setBackgroundColor(QColor(parts3);setupNode(node);void DiagramWindow:bringToFront()+maxZ;setZValue(maxZ); / 改變繪圖順序,首先繪制父圖元,然后是子圖元,根據(jù)子圖元Z值的大小,/ 值最小,最先繪制,值最大,最后繪制void DiagramWindow:sendToBack()-minZ;setZValue(minZ);void DiagramWindow:properties()Node *node = selectedNode

37、();Link *link = selectedLink();if (node) PropertiesDialog dialog(node, this);dialog.exec(); else if (link) QColor color = QColorDialog:getColor(link->color(), this);if (color.isValid()link->setColor(color);/ 更新動作使能void DiagramWindow:updateActions()bool hasSelection = !scene->selectedItems()

38、.isEmpty();bool isNode = (selectedNode() != 0);bool isNodePair = (selectedNodePair() != NodePair();cutAction->setEnabled(isNode);copyAction->setEnabled(isNode);addLinkAction->setEnabled(isNodePair);deleteAction->setEnabled(hasSelection);bringToFrontAction->setEnabled(isNode);sendToBac

39、kAction->setEnabled(isNode);propertiesAction->setEnabled(isNode);foreach (QAction *action, view->actions()view->removeAction(action); / 刪除右鍵菜單foreach (QAction *action, editMenu->actions() if (action->isEnabled()view->addAction(action); / 增加右鍵菜單void DiagramWindow:createActions()e

40、xitAction = new QAction(tr("E&xit"), this);exitAction->setShortcut(tr("Ctrl+Q");connect(exitAction, SIGNAL(triggered(), this, SLOT(close();addNodeAction = new QAction(tr("Add &Node"), this);addNodeAction->setIcon(QIcon(":/images/node.png");addNod

41、eAction->setShortcut(tr("Ctrl+N");connect(addNodeAction, SIGNAL(triggered(), this, SLOT(addNode();addLinkAction = new QAction(tr("Add &Link"), this);addLinkAction->setIcon(QIcon(":/images/link.png");addLinkAction->setShortcut(tr("Ctrl+L");connect(

42、addLinkAction, SIGNAL(triggered(), this, SLOT(addLink();deleteAction = new QAction(tr("&Delete"), this);deleteAction->setIcon(QIcon(":/images/delete.png");deleteAction->setShortcut(tr("Del");connect(deleteAction, SIGNAL(triggered(), this, SLOT(del();cutAction

43、= new QAction(tr("Cu&t"), this);cutAction->setIcon(QIcon(":/images/cut.png");cutAction->setShortcut(tr("Ctrl+X");connect(cutAction, SIGNAL(triggered(), this, SLOT(cut();copyAction = new QAction(tr("&Copy"), this);copyAction->setIcon(QIcon(&quo

44、t;:/images/copy.png");copyAction->setShortcut(tr("Ctrl+C");connect(copyAction, SIGNAL(triggered(), this, SLOT(copy();pasteAction = new QAction(tr("&Paste"), this);pasteAction->setIcon(QIcon(":/images/paste.png");pasteAction->setShortcut(tr("Ctrl+V

45、");connect(pasteAction, SIGNAL(triggered(), this, SLOT(paste();bringToFrontAction = new QAction(tr("Bring to &Front"), this);bringToFrontAction->setIcon(QIcon(":/images/bringtofront.png");connect(bringToFrontAction, SIGNAL(triggered(),this, SLOT(bringToFront();sendToB

46、ackAction = new QAction(tr("&Send to Back"), this);sendToBackAction->setIcon(QIcon(":/images/sendtoback.png");connect(sendToBackAction, SIGNAL(triggered(),this, SLOT(sendToBack();propertiesAction = new QAction(tr("P&roperties."), this);connect(propertiesActio

47、n, SIGNAL(triggered(),this, SLOT(properties();void DiagramWindow:createMenus()fileMenu = menuBar()->addMenu(tr("&File");fileMenu->addAction(exitAction);editMenu = menuBar()->addMenu(tr("&Edit");editMenu->addAction(addNodeAction);editMenu->addAction(addLinkA

48、ction);editMenu->addAction(deleteAction);editMenu->addSeparator();editMenu->addAction(cutAction);editMenu->addAction(copyAction);editMenu->addAction(pasteAction);editMenu->addSeparator();editMenu->addAction(bringToFrontAction);editMenu->addAction(sendToBackAction);editMenu-&g

49、t;addSeparator();editMenu->addAction(propertiesAction);void DiagramWindow:createToolBars()editToolBar = addToolBar(tr("Edit");editToolBar->addAction(addNodeAction);editToolBar->addAction(addLinkAction);editToolBar->addAction(deleteAction);editToolBar->addSeparator();editTool

50、Bar->addAction(cutAction);editToolBar->addAction(copyAction);editToolBar->addAction(pasteAction);editToolBar->addSeparator();editToolBar->addAction(bringToFrontAction);editToolBar->addAction(sendToBackAction);void DiagramWindow:setZValue(int z)Node *node = selectedNode();if (node)n

51、ode->setZValue(z);void DiagramWindow:setupNode(Node *node)node->setPos(QPoint(80 + (100 * (seqNumber % 5),80 + (50 * (seqNumber / 5) % 7);scene->addItem(node);+seqNumber;scene->clearSelection();node->setSelected(true);bringToFront();/ 返回一個選擇的節(jié)點Node *DiagramWindow:selectedNode() constQ

52、List<QGraphicsItem *> items = scene->selectedItems(); / 全部選擇的節(jié)點if (items.count() = 1) return dynamic_cast<Node *>(items.first(); else return 0;Link *DiagramWindow:selectedLink() constQList<QGraphicsItem *> items = scene->selectedItems();if (items.count() = 1) return dynamic_c

53、ast<Link *>(items.first(); else return 0;/ 返回選擇的節(jié)點對DiagramWindow:NodePair DiagramWindow:selectedNodePair() constQList<QGraphicsItem *> items = scene->selectedItems();if (items.count() = 2) Node *first = dynamic_cast<Node *>(items.first();Node *second = dynamic_cast<Node *>

54、(items.last();if (first && second)return NodePair(first, second);return NodePair();/ propertiesdialog.h#ifndef PROPERTIESDIALOG_H#define PROPERTIESDIALOG_H#include "ui_propertiesdialog.h"class Node;class PropertiesDialog : public QDialog, private Ui:PropertiesDialogQ_OBJECTpublic:PropertiesDialog(Node *node, QWidget *parent = 0);private slots:void on_buttonBox_accepted(); / 快速信號連接void on_textColorButton_clicked();void on_outlineColorButton_clicked()

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論