#!/usr/bin/env python # TQt tutorial 11. import sys import math from qt import * class LCDRange(TQVBox): def __init__(self,parent=None,name=None): TQVBox.__init__(self,parent,name) lcd = TQLCDNumber(2,self,'lcd') self.slider = TQSlider(TQt.Horizontal,self,'slider') self.slider.setRange(0,99) self.slider.setValue(0) self.connect(self.slider,SIGNAL('valueChanged(int)'),lcd,SLOT('display(int)')) self.connect(self.slider,SIGNAL('valueChanged(int)'),self,PYSIGNAL('valueChanged(int)')) self.setFocusProxy(self.slider) def value(self): return self.slider.value() def setValue(self,value): self.slider.setValue(value) def setRange(self,minVal,maxVal): if minVal < 0 or maxVal > 99 or minVal > maxVal: raise ValueError, 'LCDRange.setRange(): invalid range' self.slider.setRange(minVal,maxVal) class CannonField(TQWidget): def __init__(self,parent=None,name=None): TQWidget.__init__(self,parent,name) self.ang = 45 self.f = 0 self.timerCount = 0 self.autoShootTimer = TQTimer(self,'movement handler') self.connect(self.autoShootTimer,SIGNAL('timeout()'),self.moveShot) self.shoot_ang = 0 self.shoot_f = 0 self.setPalette(TQPalette(TQColor(250,250,200))) self.barrelRect = TQRect(33,-4,15,8) def angle(self): return self.ang def setAngle(self,degrees): if degrees < 5: degrees = 5 if degrees > 70: degrees = 70 if self.ang == degrees: return self.ang = degrees self.repaint(self.cannonRect(),0) self.emit(PYSIGNAL('angleChanged(int)'),(self.ang,)) def force(self): return self.f def setForce(self,newton): if newton < 0: newton = 0 if self.f == newton: return self.f = newton self.emit(PYSIGNAL('forceChanged(int)'),(self.f,)) def shoot(self): if self.autoShootTimer.isActive(): return self.timerCount = 0 self.shoot_ang = self.ang self.shoot_f = self.f self.autoShootTimer.start(50) def moveShot(self): r = TQRegion(self.shotRect()) self.timerCount = self.timerCount + 1 shotR = self.shotRect() if shotR.x() > self.width() or shotR.y() > self.height(): self.autoShootTimer.stop() else: r = r.unite(TQRegion(shotR)) self.repaint(r) def paintEvent(self,ev): updateR = ev.rect() p = TQPainter(self) if updateR.intersects(self.cannonRect()): self.paintCannon(p) if self.autoShootTimer.isActive() and updateR.intersects(self.shotRect()): self.paintShot(p) def paintShot(self,p): p.setBrush(TQt.black) p.setPen(TQt.NoPen) p.drawRect(self.shotRect()) def paintCannon(self,p): cr = self.cannonRect() pix = TQPixmap(cr.size()) pix.fill(self,cr.topLeft()) tmp = TQPainter(pix) tmp.setBrush(TQt.blue) tmp.setPen(TQt.NoPen) tmp.translate(0,pix.height() - 1) tmp.drawPie(TQRect(-35,-35,70,70),0,90 * 16) tmp.rotate(-self.ang) tmp.drawRect(self.barrelRect) tmp.end() p.drawPixmap(cr.topLeft(),pix) def cannonRect(self): r = TQRect(0,0,50,50) r.moveBottomLeft(self.rect().bottomLeft()) return r def shotRect(self): gravity = 4.0 time = self.timerCount / 4.0 velocity = self.shoot_f radians = self.shoot_ang * 3.14159265 / 180 velx = velocity * math.cos(radians) vely = velocity * math.sin(radians) x0 = (self.barrelRect.right() + 5) * math.cos(radians) y0 = (self.barrelRect.right() + 5) * math.sin(radians) x = x0 + velx * time y = y0 + vely * time - 0.5 * gravity * time * time r = TQRect(0,0,6,6) r.moveCenter(TQPoint(x,self.height() - 1 - y)) return r def sizePolicy(self): return TQSizePolicy(TQSizePolicy.Expanding,TQSizePolicy.Expanding) class MyWidget(TQWidget): def __init__(self,parent=None,name=None): TQWidget.__init__(self,parent,name) quit = TQPushButton('&Quit',self,'quit') quit.setFont(TQFont('Times',18,TQFont.Bold)) self.connect(quit,SIGNAL('clicked()'),tqApp,SLOT('quit()')) self.angle = LCDRange(self,'angle') self.angle.setRange(5,70) self.force = LCDRange(self,'force') self.force.setRange(10,50) self.cannonField = CannonField(self,'cannonField') self.connect(self.angle,PYSIGNAL('valueChanged(int)'),self.cannonField.setAngle) self.connect(self.cannonField,PYSIGNAL('angleChanged(int)'),self.angle.setValue) self.connect(self.force,PYSIGNAL('valueChanged(int)'),self.cannonField.setForce) self.connect(self.cannonField,PYSIGNAL('forceChanged(int)'),self.force.setValue) shoot = TQPushButton('&Shoot',self,'shoot') shoot.setFont(TQFont('Times',18,TQFont.Bold)) self.connect(shoot,SIGNAL('clicked()'),self.cannonField.shoot) grid = TQGridLayout(self,2,2,10) grid.addWidget(quit,0,0) grid.addWidget(self.cannonField,1,1) grid.setColStretch(1,10) leftBox = TQVBoxLayout() grid.addLayout(leftBox,1,0) leftBox.addWidget(self.angle) leftBox.addWidget(self.force) topBox = TQHBoxLayout() grid.addLayout(topBox,0,1) topBox.addWidget(shoot) topBox.addStretch(1) self.angle.setValue(60) self.force.setValue(25) self.angle.setFocus() TQApplication.setColorSpec(TQApplication.CustomColor) a = TQApplication(sys.argv) w = MyWidget() w.setGeometry(100,100,500,355) a.setMainWidget(w) w.show() a.exec_loop()