#!/usr/bin/env python import sys from qt import * from qtcanvas import * import random True = 1 False = 0 butterfly_fn = QString.null butterflyimg = [] logo_fn = QString.null logoimg = [] bouncy_logo = None views = [] class ImageItem(QCanvasRectangle): def __init__(self,img,canvas): QCanvasRectangle.__init__(self,canvas) self.imageRTTI=984376 self.image=img self.pixmap=QPixmap() self.setSize(self.image.width(), self.image.height()) self.pixmap.convertFromImage(self.image, Qt.OrderedAlphaDither); def rtti(self): return self.imageRTTI def hit(self,p): ix = p.x()-self.x() iy = p.y()-self.y() if not self.image.valid( ix , iy ): return False self.pixel = self.image.pixel( ix, iy ) return (qAlpha( self.pixel ) != 0) def drawShape(self,p): p.drawPixmap( self.x(), self.y(), self.pixmap ) class NodeItem(QCanvasEllipse): def __init__(self,canvas): QCanvasEllipse.__init__(self,6,6,canvas) self.__inList=[] self.__outList=[] self.setPen(QPen(Qt.black)) self.setBrush(QBrush(Qt.red)) self.setZ(128) def addInEdge(self,edge): self.__inList.append(edge) def addOutEdge(self,edge): self.__outList.append(edge) def moveBy(self,dx,dy): QCanvasEllipse.moveBy(self,dx,dy) for each_edge in self.__inList: each_edge.setToPoint( int(self.x()), int(self.y()) ) for each_edge in self.__outList: each_edge.setFromPoint( int(self.x()), int(self.y()) ) class EdgeItem(QCanvasLine): __c=0 def __init__(self,fromNode, toNode,canvas): QCanvasLine.__init__(self,canvas) self.__c=self.__c+1 self.setPen(QPen(Qt.black)) self.setBrush(QBrush(Qt.red)) fromNode.addOutEdge(self) toNode.addInEdge(self) self.setPoints(int(fromNode.x()),int(fromNode.y()), int(toNode.x()), int(toNode.y())) self.setZ(127) def setFromPoint(self,x,y): self.setPoints(x,y,self.endPoint().x(),self.endPoint().y()) def setToPoint(self,x,y): self.setPoints(self.startPoint().x(), self.startPoint().y(),x,y) def count(self): return self.__c def moveBy(self,dx,dy): pass class FigureEditor(QCanvasView): def __init__(self,c,parent,name,f): QCanvasView.__init__(self,c,parent,name,f) self.__moving=0 self.__moving_start= 0 def contentsMousePressEvent(self,e): # QMouseEvent e point = self.inverseWorldMatrix().map(e.pos()) ilist = self.canvas().collisions(point) #QCanvasItemList ilist for each_item in ilist: if each_item.rtti()==984376: if not each_item.hit(point): continue self.__moving=each_item self.__moving_start=point return self.__moving=0 def clear(self): ilist = self.canvas().allItems() for each_item in ilist: if each_item: each_item.setCanvas(None) del each_item self.canvas().update() def contentsMouseMoveEvent(self,e): if self.__moving : point = self.inverseWorldMatrix().map(e.pos()); self.__moving.moveBy(point.x() - self.__moving_start.x(),point.y() - self.__moving_start.y()) self.__moving_start = point self.canvas().update() class BouncyLogo(QCanvasSprite): def __init__(self,canvas): # Make sure the logo exists. global bouncy_logo if bouncy_logo is None: bouncy_logo=QCanvasPixmapArray("qt-trans.xpm") QCanvasSprite.__init__(self,None,canvas) self.setSequence(bouncy_logo) self.setAnimated(True) self.initPos() self.logo_rtti=1234 def rtti(self): return self.logo_rtti def initPos(self): self.initSpeed() trial=1000 self.move(random.random()%self.canvas().width(), random.random()%self.canvas().height()) self.advance(0) trial=trial-1 while (trial & (self.xVelocity()==0 )& (self.yVelocity()==0)): elf.move(random.random()%self.canvas().width(), random.random()%self.canvas().height()) self.advance(0) trial=trial-1 def initSpeed(self): speed=4.0 d=random.random()%1024/1024.0 self.setVelocity(d*speed*2-speed, (1-d)*speed*2-speed) def advance(self,stage): if stage==0: vx=self.xVelocity() vy=self.yVelocity() if (vx==0.0) & (vy==0.0): self.initSpeed() vx=self.xVelocity() vy=self.yVelocity() nx=self.x()+vx ny=self.y()+vy if (nx<0) | (nx >= self.canvas().width()): vx=-vx if (ny<0) | (ny >= self.canvas().height()): vy=-vy for bounce in [0,1,2,3]: l=self.collisions(False) for hit in l: if (hit.rtti()==1234) & (hit.collidesWith(self)): if bounce==0: vx=-vx elif bounce==1: vy=-vy vx=-vx elif bounce==2: vx=-vx elif bounce==3: vx=0 vy=0 self.setVelocity(vx,vy) break if (self.x()+vx < 0) | (self.x()+vx >= self.canvas().width()): vx=0 if (self.y()+vy < 0) | (self.y()+vy >= self.canvas().height()): vy=0 self.setVelocity(vx,vy) elif stage==1: QCanvasItem.advance(self,stage) class Main (QMainWindow): def __init__(self,c,parent,name,f=0): QMainWindow.__init__(self,parent,name,f) self.editor=FigureEditor(c,self,name,f) self.printer=QPrinter() self.dbf_id=0 self.canvas=c self.mainCount=0 file=QPopupMenu(self.menuBar()) file.insertItem("&Fill canvas", self.init, Qt.CTRL+Qt.Key_F) file.insertItem("&Erase canvas", self.clear, Qt.CTRL+Qt.Key_E) file.insertItem("&New view", self.newView, Qt.CTRL+Qt.Key_N) file.insertSeparator(); file.insertItem("&Print", self._print, Qt.CTRL+Qt.Key_P) file.insertSeparator() file.insertItem("E&xit", qApp, SLOT("quit()"), Qt.CTRL+Qt.Key_Q) self.menuBar().insertItem("&File", file) edit = QPopupMenu(self.menuBar() ) edit.insertItem("Add &Circle", self.addCircle, Qt.ALT+Qt.Key_C) edit.insertItem("Add &Hexagon", self.addHexagon, Qt.ALT+Qt.Key_H) edit.insertItem("Add &Polygon", self.addPolygon, Qt.ALT+Qt.Key_P) edit.insertItem("Add Spl&ine", self.addSpline, Qt.ALT+Qt.Key_I) edit.insertItem("Add &Text", self.addText, Qt.ALT+Qt.Key_T) edit.insertItem("Add &Line", self.addLine, Qt.ALT+Qt.Key_L) edit.insertItem("Add &Rectangle", self.addRectangle, Qt.ALT+Qt.Key_R) edit.insertItem("Add &Sprite", self.addSprite, Qt.ALT+Qt.Key_S) edit.insertItem("Create &Mesh", self.addMesh, Qt.ALT+Qt.Key_M ) edit.insertItem("Add &Alpha-blended image", self.addButterfly, Qt.ALT+Qt.Key_A) self.menuBar().insertItem("&Edit", edit) view = QPopupMenu(self.menuBar() ); view.insertItem("&Enlarge", self.enlarge, Qt.SHIFT+Qt.CTRL+Qt.Key_Plus); view.insertItem("Shr&ink", self.shrink, Qt.SHIFT+Qt.CTRL+Qt.Key_Minus); view.insertSeparator(); view.insertItem("&Rotate clockwise", self.rotateClockwise, Qt.CTRL+Qt.Key_PageDown); view.insertItem("Rotate &counterclockwise", self.rotateCounterClockwise, Qt.CTRL+Qt.Key_PageUp); view.insertItem("&Zoom in", self.zoomIn, Qt.CTRL+Qt.Key_Plus); view.insertItem("Zoom &out", self.zoomOut, Qt.CTRL+Qt.Key_Minus); view.insertItem("Translate left", self.moveL, Qt.CTRL+Qt.Key_Left); view.insertItem("Translate right", self.moveR, Qt.CTRL+Qt.Key_Right); view.insertItem("Translate up", self.moveU, Qt.CTRL+Qt.Key_Up); view.insertItem("Translate down", self.moveD, Qt.CTRL+Qt.Key_Down); view.insertItem("&Mirror", self.mirror, Qt.CTRL+Qt.Key_Home); self.menuBar().insertItem("&View", view) self.options = QPopupMenu( self.menuBar() ); self.dbf_id = self.options.insertItem("Double buffer", self.toggleDoubleBuffer) self.options.setItemChecked(self.dbf_id, True) self.menuBar().insertItem("&Options",self.options) self.menuBar().insertSeparator(); help = QPopupMenu( self.menuBar() ) help.insertItem("&About", self.help, Qt.Key_F1) help.insertItem("&About Qt", self.aboutQt, Qt.Key_F2) help.setItemChecked(self.dbf_id, True) self.menuBar().insertItem("&Help",help) self.statusBar() self.setCentralWidget(self.editor) self.printer = 0 self.tb=0 self.tp=0 self.init() def init(self): self.clear() r=24 r=r+1 random.seed(r) for i in range(self.canvas.width()/56): self.addButterfly() for j in range(self.canvas.width()/85): self.addHexagon() for k in range(self.canvas.width()/128): self.addLogo() def newView(self): m=Main(self.canvas,None,"new windiw",Qt.WDestructiveClose) qApp.setMainWidget(m) m.show() qApp.setMainWidget(None) views.append(m) def clear(self): self.editor.clear() def help(self): QMessageBox.information(None, "PyQt Canvas Example", "

The PyQt QCanvas classes example


" "

This is the PyQt implementation of " "Qt canvas example.

by Sadi Kose " "(kose@nuvox.net)
" "","Dismiss") def aboutQt(self): QMessageBox.aboutQt(self,"PyQt Canvas Example") def toggleDoubleBuffer(self): s = not self.options.isItemChecked(self.dbf_id) self.options.setItemChecked(self.dbf_id,s) self.canvas.setDoubleBuffering(s) def enlarge(self): self.canvas.resize(self.canvas.width()*4/3, self.canvas.height()*4/3) def shrink(self): self.canvas.resize(self.canvas.width()*3/4, self.canvas.height()*3/4) def rotateClockwise(self): m = self.editor.worldMatrix() m.rotate( 22.5 ) self.editor.setWorldMatrix( m ) def rotateCounterClockwise(self): m = self.editor.worldMatrix() m.rotate( -22.5 ) self.editor.setWorldMatrix( m ) def zoomIn(self): m = self.editor.worldMatrix() m.scale( 2.0, 2.0 ) self.editor.setWorldMatrix( m ) def zoomOut(self): m = self.editor.worldMatrix() m.scale( 0.5, 0.5 ) self.editor.setWorldMatrix( m ) def mirror(self): m = self.editor.worldMatrix() m.scale( -1, 1 ) self.editor.setWorldMatrix( m ) def moveL(self): m = self.editor.worldMatrix() m.translate( -16, 0 ) self.editor.setWorldMatrix( m ) def moveR(self): m = self.editor.worldMatrix() m.translate( +16, 0 ) self.editor.setWorldMatrix( m ) def moveU(self): m = self.editor.worldMatrix() m.translate( 0, -16 ) self.editor.setWorldMatrix( m ) def moveD(self): m = self.editor.worldMatrix(); m.translate( 0, +16 ); self.editor.setWorldMatrix( m ) def _print(self): if not self.printer: self.printer = QPrinter() if self.printer.setup(self) : pp=QPainter(self.printer) self.canvas.drawArea(QRect(0,0,self.canvas.width(),self.canvas.height()),pp,False) def addSprite(self): i = BouncyLogo(self.canvas) i.setZ(256*random.random()%256); i.show(); def addButterfly(self): if butterfly_fn.isEmpty(): return if not butterflyimg: butterflyimg.append(QImage()) butterflyimg[0].load(butterfly_fn) butterflyimg.append(QImage()) butterflyimg[1] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.75), int(butterflyimg[0].height()*0.75) ) butterflyimg.append(QImage()) butterflyimg[2] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.5), int(butterflyimg[0].height()*0.5) ) butterflyimg.append(QImage()) butterflyimg[3] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.25), int(butterflyimg[0].height()*0.25) ) i = ImageItem(butterflyimg[int(4*random.random()%4)],self.canvas) i.move((self.canvas.width()-butterflyimg[0].width())*random.random()%(self.canvas.width()-butterflyimg[0].width()), (self.canvas.height()-butterflyimg[0].height())*random.random()%(self.canvas.height()-butterflyimg[0].height())) i.setZ(256*random.random()%256+250); i.show() def addLogo(self): if logo_fn.isEmpty(): return; if not logoimg: logoimg.append(QImage()) logoimg[0].load( logo_fn ) logoimg.append(QImage()) logoimg[1] = logoimg[0].smoothScale( int(logoimg[0].width()*0.75), int(logoimg[0].height()*0.75) ) logoimg.append(QImage()) logoimg[2] = logoimg[0].smoothScale( int(logoimg[0].width()*0.5), int(logoimg[0].height()*0.5) ) logoimg.append(QImage()) logoimg[3] = logoimg[0].smoothScale( int(logoimg[0].width()*0.25), int(logoimg[0].height()*0.25) ); i = ImageItem(logoimg[int(4*random.random()%4)],self.canvas) i.move((self.canvas.width()-logoimg[0].width())*random.random()%(self.canvas.width()-logoimg[0].width()), (self.canvas.height()-logoimg[0].width())*random.random()%(self.canvas.height()-logoimg[0].width())) i.setZ(256*random.random()%256+256) i.show() def addCircle(self): i = QCanvasEllipse(50,50,self.canvas) i.setBrush( QBrush(QColor(256*random.random()%32*8,256*random.random()%32*8,256*random.random()%32*8) )) i.move(self.canvas.width()*random.random()%self.canvas.width(),self.canvas.width()*random.random()%self.canvas.height()) i.setZ(256*random.random()%256) i.show() def addHexagon(self): i = QCanvasPolygon(self.canvas) size = canvas.width() / 25 pa=QPointArray(6) pa.setPoint(0,QPoint(2*size,0)) pa.setPoint(1,QPoint(size,-size*173/100)) pa.setPoint(2,QPoint(-size,-size*173/100)) pa.setPoint(3,QPoint(-2*size,0)) pa.setPoint(4,QPoint(-size,size*173/100)) pa.setPoint(5,QPoint(size,size*173/100)) i.setPoints(pa) i.setBrush( QBrush(QColor(256*random.random()%32*8,256*random.random()%32*8,256*random.random()%32*8) )) i.move(self.canvas.width()*random.random()%self.canvas.width(),self.canvas.width()*random.random()%self.canvas.height()) i.setZ(256*random.random()%256) i.show() def addPolygon(self): i = QCanvasPolygon(self.canvas) size = self.canvas.width()/2 pa=QPointArray(6) pa.setPoint(0, QPoint(0,0)) pa.setPoint(1, QPoint(size,size/5)) pa.setPoint(2, QPoint(size*4/5,size)) pa.setPoint(3, QPoint(size/6,size*5/4)) pa.setPoint(4, QPoint(size*3/4,size*3/4)) pa.setPoint(5, QPoint(size*3/4,size/4)) i.setPoints(pa) i.setBrush(QBrush( QColor(256*random.random()%32*8,256*random.random()%32*8,256*random.random()%32*8)) ) i.move(self.canvas.width()*random.random()%self.canvas.width(),self.canvas.width()*random.random()%self.canvas.height()) i.setZ(256*random.random()%256) i.show() def addSpline(self): i = QCanvasSpline(self.canvas) size = canvas.width()/6 pa=QPointArray(12) pa.setPoint(0,QPoint(0,0)) pa.setPoint(1,QPoint(size/2,0)) pa.setPoint(2,QPoint(size,size/2)) pa.setPoint(3,QPoint(size,size)) pa.setPoint(4,QPoint(size,size*3/2)) pa.setPoint(5,QPoint(size/2,size*2)) pa.setPoint(6,QPoint(0,size*2)) pa.setPoint(7,QPoint(-size/2,size*2)) pa.setPoint(8,QPoint(size/4,size*3/2)) pa.setPoint(9,QPoint(0,size)) pa.setPoint(10,QPoint(-size/4,size/2)) pa.setPoint(11,QPoint(-size/2,0)) i.setControlPoints(pa) i.setBrush( QBrush(QColor(256*random.random()%32*8,256*random.random()%32*8,256*random.random()%32*8) )) i.move(self.canvas.width()*random.random()%self.canvas.width(),self.canvas.width()*random.random()%self.canvas.height()) i.setZ(256*random.random()%256) i.show() def addText(self): i = QCanvasText(self.canvas) i.setText("QCanvasText") i.move(self.canvas.width()*random.random()%self.canvas.width(),self.canvas.width()*random.random()%self.canvas.height()) i.setZ(256*random.random()%256) i.show() def addLine(self): i = QCanvasLine(self.canvas); i.setPoints( self.canvas.width()*random.random()%self.canvas.width(), self.canvas.width()*random.random()%self.canvas.height(), self.canvas.width()*random.random()%self.canvas.width(), self.canvas.width()*random.random()%self.canvas.height() ) i.setPen( QPen(QColor(256*random.random()%32*8,256*random.random()%32*8,256*random.random()%32*8), 6) ) i.setZ(256*random.random()%256) i.show() def ternary(self,exp,x,y): if exp: return x else: return y def addMesh(self): x0 = 0; y0 = 0; if not self.tb: self.tb = QBrush( Qt.red ) if not self.tp: self.tp = QPen( Qt.black ) nodecount = 0; w = self.canvas.width() h = self.canvas.height() dist = 30 rows = h / dist cols = w / dist #ifndef QT_NO_PROGRESSDIALOG #progress=QProgressDialog( "Creating mesh...", "Abort", rows, # self, "progress", True ); #endif lastRow=[] for c in range(cols): lastRow.append(NodeItem(self.canvas)) for j in range(rows): n = self.ternary(j%2 , cols-1 , cols) prev = 0; for i in range(n): el = NodeItem( self.canvas ) nodecount=nodecount+1 r = 20*20*random.random() xrand = r %20 yrand = (r/20) %20 el.move( xrand + x0 + i*dist + self.ternary(j%2 , dist/2 , 0 ), yrand + y0 + j*dist ); if j > 0 : if i < cols-1 : EdgeItem( lastRow[i], el, self.canvas ).show() if j%2 : EdgeItem( lastRow[i+1], el, self.canvas ).show() elif i > 0 : EdgeItem( lastRow[i-1], el, self.canvas ).show() if prev: EdgeItem( prev, el, self.canvas ).show() if i > 0 : lastRow[i-1] = prev prev = el el.show() lastRow[n-1]=prev #ifndef QT_NO_PROGRESSDIALOG #progress.setProgress( j ) #if progress.wasCancelled() : # break #endif #ifndef QT_NO_PROGRESSDIALOG #progress.setProgress( rows ) #endif #// qDebug( "%d nodes, %d edges", nodecount, EdgeItem::count() ); def addRectangle(self): i = QCanvasRectangle( self.canvas.width()*random.random()%self.canvas.width(), self.canvas.width()*random.random()%self.canvas.height(), self.canvas.width()/5,self.canvas.width()/5,self.canvas) z = 256*random.random()%256 i.setBrush( QBrush(QColor(z,z,z) )) i.setPen( QPen(QColor(self.canvas.width()*random.random()%32*8, self.canvas.width()*random.random()%32*8, self.canvas.width()*random.random()%32*8), 6) ) i.setZ(z) i.show() if __name__=='__main__': app=QApplication(sys.argv) if len(sys.argv) > 1: butterfly_fn=QString(sys.argv[1]) else: butterfly_fn=QString("butterfly.png") if len(sys.argv) > 2: logo_fn = QString(sys.argv[2]) else: logo_fn=QString("qtlogo.png") canvas=QCanvas(800,600) canvas.setAdvancePeriod(30) m=Main(canvas,None,"pyqt canvas example") m.resize(m.sizeHint()) qApp.setMainWidget(m) m.setCaption("Qt Canvas Example ported to PyQt") if QApplication.desktop().width() > m.width() + 10 and QApplication.desktop().height() > m.height() + 30: m.show() else: m.showMaximized() m.show(); #// m.help(); qApp.setMainWidget(None); QObject.connect( qApp, SIGNAL("lastWindowClosed()"), qApp, SLOT("quit()") ) app.exec_loop() # We need to explicitly delete the canvas now (and, therefore, the main # window beforehand) to make sure that the sprite logo doesn't get garbage # collected first. views = [] del m del canvas