📄 canvas.cpp
字号:
/******************************************************************************** Copyright (C) 2006-2006 Trolltech ASA. All rights reserved.**** This file is part of the example classes of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qdatetime.h>#include <qmainwindow.h>#include <qstatusbar.h>#include <qmessagebox.h>#include <qmenubar.h>#include <qapplication.h>#include <qpainter.h>#include <qprinter.h>#include <qlabel.h>#include <qimage.h>#include <q3progressdialog.h>#include <Q3PointArray>#include <Q3PtrList>#include <QPixmap>#include <Q3PopupMenu>#include <QMouseEvent>#include <Q3MemArray>#include "canvas.h"#include <QStyleOptionGraphicsItem>#include <qdebug.h>#include <stdlib.h>// We use a global variable to save memory - all the brushes and pens in// the mesh are shared.static QBrush *tb = 0;static QPen *tp = 0;class EdgeItem;class NodeItem;class EdgeItem: public QGraphicsLineItem{public: EdgeItem( NodeItem*, NodeItem* ); void setFromPoint( int x, int y ) ; void setToPoint( int x, int y ); static int count() { return c; }private: static int c;};static const int imageRTTI = 984376;class ImageItem: public QGraphicsRectItem{public: ImageItem( QImage img ); int rtti () const { return imageRTTI; }protected: void paint( QPainter *, const QStyleOptionGraphicsItem *option, QWidget *widget );private: QImage image; QPixmap pixmap;};ImageItem::ImageItem( QImage img ) : image(img){ setRect(0, 0, image.width(), image.height()); setFlag(ItemIsMovable);#if !defined(Q_WS_QWS) pixmap.convertFromImage(image, Qt::OrderedAlphaDither);#endif}void ImageItem::paint( QPainter *p, const QStyleOptionGraphicsItem *option, QWidget * ){// On Qt/Embedded, we can paint a QImage as fast as a QPixmap,// but on other platforms, we need to use a QPixmap.#if defined(Q_WS_QWS) p->drawImage( option->exposedRect, image, option->exposedRect, Qt::OrderedAlphaDither );#else p->drawPixmap( option->exposedRect, pixmap, option->exposedRect );#endif}class NodeItem: public QGraphicsEllipseItem{public: NodeItem(); ~NodeItem() {} void addInEdge( EdgeItem *edge ) { inList.append( edge ); } void addOutEdge( EdgeItem *edge ) { outList.append( edge ); }protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value); // QPoint center() { return boundingRect().center(); }private: Q3PtrList<EdgeItem> inList; Q3PtrList<EdgeItem> outList;};int EdgeItem::c = 0;EdgeItem::EdgeItem( NodeItem *from, NodeItem *to ) : QGraphicsLineItem( ){ c++; setPen( *tp ); from->addOutEdge( this ); to->addInEdge( this ); setLine( QLineF(int(from->x()), int(from->y()), int(to->x()), int(to->y()) )); setZValue( 127 );}void EdgeItem::setFromPoint( int x, int y ){ setLine(QLineF( x,y, line().p2().x(), line().p2().y() ));}void EdgeItem::setToPoint( int x, int y ){ setLine(QLineF( line().p1().x(), line().p1().y(), x, y ));}QVariant NodeItem::itemChange(GraphicsItemChange change, const QVariant &value){ if (change == ItemPositionChange) { Q3PtrListIterator<EdgeItem> it1( inList ); EdgeItem *edge; while (( edge = it1.current() )) { ++it1; edge->setToPoint( int(x()), int(y()) ); } Q3PtrListIterator<EdgeItem> it2( outList ); while (( edge = it2.current() )) { ++it2; edge->setFromPoint( int(x()), int(y()) ); } } return QGraphicsEllipseItem::itemChange(change, value);}NodeItem::NodeItem( ) : QGraphicsEllipseItem( QRectF(-3, -3, 6, 6) ){ setPen( *tp ); setBrush( *tb ); setZValue( 128 ); setFlag(ItemIsMovable);}FigureEditor::FigureEditor( QGraphicsScene& c, QWidget* parent, const char* name, Qt::WindowFlags f) : QGraphicsView(&c,parent){ setObjectName(name); setWindowFlags(f); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);}void FigureEditor::clear(){ QList<QGraphicsItem *> list = scene()->items(); QList<QGraphicsItem *>::Iterator it = list.begin(); for (; it != list.end(); ++it) { if ( *it ) delete *it; }}BouncyLogo::BouncyLogo() : xvel(0), yvel(0){ setPixmap(QPixmap(":/trolltech/examples/graphicsview/portedcanvas/qt-trans.xpm"));}const int logo_rtti = 1234;int BouncyLogo::type() const{ return logo_rtti;}QPainterPath BouncyLogo::shape() const{ QPainterPath path; path.addRect(boundingRect()); return path;}void BouncyLogo::initPos(){ initSpeed(); int trial=1000; do { setPos(qrand()%int(scene()->width()),qrand()%int(scene()->height())); advance(0); } while (trial-- && xvel==0.0 && yvel==0.0);}void BouncyLogo::initSpeed(){ const double speed = 4.0; double d = (double)(qrand()%1024) / 1024.0; xvel = d*speed*2-speed; yvel = (1-d)*speed*2-speed;}void BouncyLogo::advance(int stage){ switch ( stage ) { case 0: { double vx = xvel; double vy = yvel; if ( vx == 0.0 && vy == 0.0 ) { // stopped last turn initSpeed(); vx = xvel; vy = yvel; } double nx = x() + vx; double ny = y() + vy; if ( nx < 0 || nx >= scene()->width() ) vx = -vx; if ( ny < 0 || ny >= scene()->height() ) vy = -vy; for (int bounce=0; bounce<4; bounce++) { QList<QGraphicsItem *> l=scene()->collidingItems(this); for (QList<QGraphicsItem *>::Iterator it=l.begin(); it!=l.end(); ++it) { QGraphicsItem *hit = *it; QPainterPath advancedShape = QMatrix().translate(xvel, yvel).map(shape()); if ( hit->type()==logo_rtti && hit->collidesWithPath(mapToItem(hit, advancedShape)) ) { switch ( bounce ) { case 0: vx = -vx; break; case 1: vy = -vy; vx = -vx; break; case 2: vx = -vx; break; case 3: // Stop for this turn vx = 0; vy = 0; break; } xvel = vx; yvel = vy; break; } } } if ( x()+vx < 0 || x()+vx >= scene()->width() ) vx = 0; if ( y()+vy < 0 || y()+vy >= scene()->height() ) vy = 0; xvel = vx; yvel = vy; } break; case 1: moveBy(xvel, yvel); break; }}static uint mainCount = 0;static QImage *butterflyimg;static QImage *logoimg;Main::Main(QGraphicsScene& c, QWidget* parent, const char* name, Qt::WindowFlags f) : Q3MainWindow(parent,name,f), canvas(c){ editor = new FigureEditor(canvas,this); QMenuBar* menu = menuBar(); Q3PopupMenu* file = new Q3PopupMenu( menu ); file->insertItem("&Fill canvas", this, SLOT(init()), Qt::CTRL+Qt::Key_F); file->insertItem("&Erase canvas", this, SLOT(clear()), Qt::CTRL+Qt::Key_E); file->insertItem("&New view", this, SLOT(newView()), Qt::CTRL+Qt::Key_N); file->insertSeparator(); file->insertItem("&Print...", this, SLOT(print()), Qt::CTRL+Qt::Key_P); file->insertSeparator(); file->insertItem("E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q); menu->insertItem("&File", file); Q3PopupMenu* edit = new Q3PopupMenu( menu ); edit->insertItem("Add &Circle", this, SLOT(addCircle()), Qt::ALT+Qt::Key_C); edit->insertItem("Add &Hexagon", this, SLOT(addHexagon()), Qt::ALT+Qt::Key_H); edit->insertItem("Add &Polygon", this, SLOT(addPolygon()), Qt::ALT+Qt::Key_P); edit->insertItem("Add Spl&ine", this, SLOT(addSpline()), Qt::ALT+Qt::Key_I); edit->insertItem("Add &Text", this, SLOT(addText()), Qt::ALT+Qt::Key_T); edit->insertItem("Add &Line", this, SLOT(addLine()), Qt::ALT+Qt::Key_L); edit->insertItem("Add &Rectangle", this, SLOT(addRectangle()), Qt::ALT+Qt::Key_R); edit->insertItem("Add &Sprite", this, SLOT(addSprite()), Qt::ALT+Qt::Key_S); edit->insertItem("Create &Mesh", this, SLOT(addMesh()), Qt::ALT+Qt::Key_M ); edit->insertItem("Add &Alpha-blended image", this, SLOT(addButterfly()), Qt::ALT+Qt::Key_A); menu->insertItem("&Edit", edit); Q3PopupMenu* view = new Q3PopupMenu( menu ); view->insertItem("&Enlarge", this, SLOT(enlarge()), Qt::SHIFT+Qt::CTRL+Qt::Key_Plus); view->insertItem("Shr&ink", this, SLOT(shrink()), Qt::SHIFT+Qt::CTRL+Qt::Key_Minus); view->insertSeparator(); view->insertItem("&Rotate clockwise", this, SLOT(rotateClockwise()), Qt::CTRL+Qt::Key_PageDown); view->insertItem("Rotate &counterclockwise", this, SLOT(rotateCounterClockwise()), Qt::CTRL+Qt::Key_PageUp); view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Plus); view->insertItem("Zoom &out", this, SLOT(zoomOut()), Qt::CTRL+Qt::Key_Minus); view->insertItem("Translate left", this, SLOT(moveL()), Qt::CTRL+Qt::Key_Left); view->insertItem("Translate right", this, SLOT(moveR()), Qt::CTRL+Qt::Key_Right); view->insertItem("Translate up", this, SLOT(moveU()), Qt::CTRL+Qt::Key_Up); view->insertItem("Translate down", this, SLOT(moveD()), Qt::CTRL+Qt::Key_Down); view->insertItem("&Mirror", this, SLOT(mirror()), Qt::CTRL+Qt::Key_Home); menu->insertItem("&View", view); menu->insertSeparator(); Q3PopupMenu* help = new Q3PopupMenu( menu ); help->insertItem("&About", this, SLOT(help()), Qt::Key_F1); help->setItemChecked(dbf_id, TRUE); menu->insertItem("&Help",help); statusBar(); setCentralWidget(editor); printer = 0; init();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -