#!/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)
"
""
"- Press ALT-S for some sprites."
"
- Press ALT-C for some circles."
"
- Press ALT-L for some lines."
"
- Drag the objects around."
"
- Read the code!"
"
","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