diff options
Diffstat (limited to 'python/pyqt/examples3/canvas/canvas.py')
-rwxr-xr-x | python/pyqt/examples3/canvas/canvas.py | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/python/pyqt/examples3/canvas/canvas.py b/python/pyqt/examples3/canvas/canvas.py new file mode 100755 index 00000000..178a6e66 --- /dev/null +++ b/python/pyqt/examples3/canvas/canvas.py @@ -0,0 +1,619 @@ +#!/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", + "<h3>The PyQt QCanvas classes example</h3><hr>" + "<p>This is the PyQt implementation of " + "Qt canvas example.</p> by Sadi Kose " + "<i>(kose@nuvox.net)</i><hr>" + "<ul>" + "<li> Press ALT-S for some sprites." + "<li> Press ALT-C for some circles." + "<li> Press ALT-L for some lines." + "<li> Drag the objects around." + "<li> Read the code!" + "</ul>","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 |