You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pytqt/examples/canvas/canvas.py

620 lines
22 KiB

#!/usr/bin/env python
import sys
from python_tqt.qt import *
from python_tqt.qtcanvas import *
import random
True = 1
False = 0
butterfly_fn = TQString.null
butterflyimg = []
logo_fn = TQString.null
logoimg = []
bouncy_logo = None
views = []
class ImageItem(TQCanvasRectangle):
def __init__(self,img,canvas):
TQCanvasRectangle.__init__(self,canvas)
self.imageRTTI=984376
self.image=img
self.pixmap=TQPixmap()
self.setSize(self.image.width(), self.image.height())
self.pixmap.convertFromImage(self.image, TQt.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 (tqAlpha( self.pixel ) != 0)
def drawShape(self,p):
p.drawPixmap( self.x(), self.y(), self.pixmap )
class NodeItem(TQCanvasEllipse):
def __init__(self,canvas):
TQCanvasEllipse.__init__(self,6,6,canvas)
self.__inList=[]
self.__outList=[]
self.setPen(TQPen(TQt.black))
self.setBrush(TQBrush(TQt.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):
TQCanvasEllipse.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(TQCanvasLine):
__c=0
def __init__(self,fromNode, toNode,canvas):
TQCanvasLine.__init__(self,canvas)
self.__c=self.__c+1
self.setPen(TQPen(TQt.black))
self.setBrush(TQBrush(TQt.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(TQCanvasView):
def __init__(self,c,parent,name,f):
TQCanvasView.__init__(self,c,parent,name,f)
self.__moving=0
self.__moving_start= 0
def contentsMousePressEvent(self,e): # TQMouseEvent e
point = self.inverseWorldMatrix().map(e.pos())
ilist = self.canvas().collisions(point) #TQCanvasItemList 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(TQCanvasSprite):
def __init__(self,canvas):
# Make sure the logo exists.
global bouncy_logo
if bouncy_logo is None:
bouncy_logo=TQCanvasPixmapArray("qt-trans.xpm")
TQCanvasSprite.__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:
TQCanvasItem.advance(self,stage)
class Main (TQMainWindow):
def __init__(self,c,parent,name,f=0):
TQMainWindow.__init__(self,parent,name,f)
self.editor=FigureEditor(c,self,name,f)
self.printer=TQPrinter()
self.dbf_id=0
self.canvas=c
self.mainCount=0
file=TQPopupMenu(self.menuBar())
file.insertItem("&Fill canvas", self.init, TQt.CTRL+TQt.Key_F)
file.insertItem("&Erase canvas", self.clear, TQt.CTRL+TQt.Key_E)
file.insertItem("&New view", self.newView, TQt.CTRL+TQt.Key_N)
file.insertSeparator();
file.insertItem("&Print", self._print, TQt.CTRL+TQt.Key_P)
file.insertSeparator()
file.insertItem("E&xit", tqApp, SLOT("quit()"), TQt.CTRL+TQt.Key_Q)
self.menuBar().insertItem("&File", file)
edit = TQPopupMenu(self.menuBar() )
edit.insertItem("Add &Circle", self.addCircle, TQt.ALT+TQt.Key_C)
edit.insertItem("Add &Hexagon", self.addHexagon, TQt.ALT+TQt.Key_H)
edit.insertItem("Add &Polygon", self.addPolygon, TQt.ALT+TQt.Key_P)
edit.insertItem("Add Spl&ine", self.addSpline, TQt.ALT+TQt.Key_I)
edit.insertItem("Add &Text", self.addText, TQt.ALT+TQt.Key_T)
edit.insertItem("Add &Line", self.addLine, TQt.ALT+TQt.Key_L)
edit.insertItem("Add &Rectangle", self.addRectangle, TQt.ALT+TQt.Key_R)
edit.insertItem("Add &Sprite", self.addSprite, TQt.ALT+TQt.Key_S)
edit.insertItem("Create &Mesh", self.addMesh, TQt.ALT+TQt.Key_M )
edit.insertItem("Add &Alpha-blended image", self.addButterfly, TQt.ALT+TQt.Key_A)
self.menuBar().insertItem("&Edit", edit)
view = TQPopupMenu(self.menuBar() );
view.insertItem("&Enlarge", self.enlarge, TQt.SHIFT+TQt.CTRL+TQt.Key_Plus);
view.insertItem("Shr&ink", self.shrink, TQt.SHIFT+TQt.CTRL+TQt.Key_Minus);
view.insertSeparator();
view.insertItem("&Rotate clockwise", self.rotateClockwise, TQt.CTRL+TQt.Key_PageDown);
view.insertItem("Rotate &counterclockwise", self.rotateCounterClockwise, TQt.CTRL+TQt.Key_PageUp);
view.insertItem("&Zoom in", self.zoomIn, TQt.CTRL+TQt.Key_Plus);
view.insertItem("Zoom &out", self.zoomOut, TQt.CTRL+TQt.Key_Minus);
view.insertItem("Translate left", self.moveL, TQt.CTRL+TQt.Key_Left);
view.insertItem("Translate right", self.moveR, TQt.CTRL+TQt.Key_Right);
view.insertItem("Translate up", self.moveU, TQt.CTRL+TQt.Key_Up);
view.insertItem("Translate down", self.moveD, TQt.CTRL+TQt.Key_Down);
view.insertItem("&Mirror", self.mirror, TQt.CTRL+TQt.Key_Home);
self.menuBar().insertItem("&View", view)
self.options = TQPopupMenu( 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 = TQPopupMenu( self.menuBar() )
help.insertItem("&About", self.help, TQt.Key_F1)
help.insertItem("&About TQt", self.aboutTQt, TQt.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",TQt.WDestructiveClose)
tqApp.setMainWidget(m)
m.show()
tqApp.setMainWidget(None)
views.append(m)
def clear(self):
self.editor.clear()
def help(self):
TQMessageBox.information(None, "PyTQt Canvas Example",
"<h3>The PyTQt TQCanvas classes example</h3><hr>"
"<p>This is the PyTQt implementation of "
"TQt 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 aboutTQt(self):
TQMessageBox.aboutTQt(self,"PyTQt 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 = TQPrinter()
if self.printer.setup(self) :
pp=TQPainter(self.printer)
self.canvas.drawArea(TQRect(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(TQImage())
butterflyimg[0].load(butterfly_fn)
butterflyimg.append(TQImage())
butterflyimg[1] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.75),
int(butterflyimg[0].height()*0.75) )
butterflyimg.append(TQImage())
butterflyimg[2] = butterflyimg[0].smoothScale( int(butterflyimg[0].width()*0.5),
int(butterflyimg[0].height()*0.5) )
butterflyimg.append(TQImage())
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(TQImage())
logoimg[0].load( logo_fn )
logoimg.append(TQImage())
logoimg[1] = logoimg[0].smoothScale( int(logoimg[0].width()*0.75),
int(logoimg[0].height()*0.75) )
logoimg.append(TQImage())
logoimg[2] = logoimg[0].smoothScale( int(logoimg[0].width()*0.5),
int(logoimg[0].height()*0.5) )
logoimg.append(TQImage())
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 = TQCanvasEllipse(50,50,self.canvas)
i.setBrush( TQBrush(TQColor(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 = TQCanvasPolygon(self.canvas)
size = canvas.width() / 25
pa=TQPointArray(6)
pa.setPoint(0,TQPoint(2*size,0))
pa.setPoint(1,TQPoint(size,-size*173/100))
pa.setPoint(2,TQPoint(-size,-size*173/100))
pa.setPoint(3,TQPoint(-2*size,0))
pa.setPoint(4,TQPoint(-size,size*173/100))
pa.setPoint(5,TQPoint(size,size*173/100))
i.setPoints(pa)
i.setBrush( TQBrush(TQColor(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 = TQCanvasPolygon(self.canvas)
size = self.canvas.width()/2
pa=TQPointArray(6)
pa.setPoint(0, TQPoint(0,0))
pa.setPoint(1, TQPoint(size,size/5))
pa.setPoint(2, TQPoint(size*4/5,size))
pa.setPoint(3, TQPoint(size/6,size*5/4))
pa.setPoint(4, TQPoint(size*3/4,size*3/4))
pa.setPoint(5, TQPoint(size*3/4,size/4))
i.setPoints(pa)
i.setBrush(TQBrush( TQColor(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 = TQCanvasSpline(self.canvas)
size = canvas.width()/6
pa=TQPointArray(12)
pa.setPoint(0,TQPoint(0,0))
pa.setPoint(1,TQPoint(size/2,0))
pa.setPoint(2,TQPoint(size,size/2))
pa.setPoint(3,TQPoint(size,size))
pa.setPoint(4,TQPoint(size,size*3/2))
pa.setPoint(5,TQPoint(size/2,size*2))
pa.setPoint(6,TQPoint(0,size*2))
pa.setPoint(7,TQPoint(-size/2,size*2))
pa.setPoint(8,TQPoint(size/4,size*3/2))
pa.setPoint(9,TQPoint(0,size))
pa.setPoint(10,TQPoint(-size/4,size/2))
pa.setPoint(11,TQPoint(-size/2,0))
i.setControlPoints(pa)
i.setBrush( TQBrush(TQColor(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 = TQCanvasText(self.canvas)
i.setText("TQCanvasText")
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 = TQCanvasLine(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( TQPen(TQColor(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 = TQBrush( TQt.red )
if not self.tp:
self.tp = TQPen( TQt.black )
nodecount = 0;
w = self.canvas.width()
h = self.canvas.height()
dist = 30
rows = h / dist
cols = w / dist
#ifndef TQT_NO_PROGRESSDIALOG
#progress=TQProgressDialog( "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 TQT_NO_PROGRESSDIALOG
#progress.setProgress( j )
#if progress.wasCancelled() :
# break
#endif
#ifndef TQT_NO_PROGRESSDIALOG
#progress.setProgress( rows )
#endif
#// tqDebug( "%d nodes, %d edges", nodecount, EdgeItem::count() );
def addRectangle(self):
i = TQCanvasRectangle( 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( TQBrush(TQColor(z,z,z) ))
i.setPen( TQPen(TQColor(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=TQApplication(sys.argv)
if len(sys.argv) > 1:
butterfly_fn=TQString(sys.argv[1])
else:
butterfly_fn=TQString("butterfly.png")
if len(sys.argv) > 2:
logo_fn = TQString(sys.argv[2])
else:
logo_fn=TQString("qtlogo.png")
canvas=TQCanvas(800,600)
canvas.setAdvancePeriod(30)
m=Main(canvas,None,"pyqt canvas example")
m.resize(m.sizeHint())
tqApp.setMainWidget(m)
m.setCaption("TQt Canvas Example ported to PyTQt")
if TQApplication.desktop().width() > m.width() + 10 and TQApplication.desktop().height() > m.height() + 30:
m.show()
else:
m.showMaximized()
m.show();
#// m.help();
tqApp.setMainWidget(None);
TQObject.connect( tqApp, SIGNAL("lastWindowClosed()"), tqApp, 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