class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.progress_bar = QProgressBar(self) self.progress_bar.setGeometry(30, 40, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(30, 80) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 self.setGeometry(300, 300, 280, 170) self.setWindowTitle('QProgressBar') self.show() def timerEvent(self, QTimerEvent): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step += 1 self.progress_bar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop')
class AutoSaver(QObject): """ Class implementing the auto saver. """ AUTOSAVE_IN = 1000 * 3 MAXWAIT = 1000 * 15 def __init__(self, parent, save): """ Constructor @param parent reference to the parent object (QObject) @param save slot to be called to perform the save operation @exception RuntimeError raised, if no parent is given """ super(AutoSaver, self).__init__(parent) if parent is None: raise RuntimeError("AutoSaver: parent must not be None.") self.__save = save self.__timer = QBasicTimer() self.__firstChange = QTime() def changeOccurred(self): """ Public slot handling a change. """ if self.__firstChange.isNull(): self.__firstChange.start() if self.__firstChange.elapsed() > self.MAXWAIT: self.saveIfNeccessary() else: self.__timer.start(self.AUTOSAVE_IN, self) def timerEvent(self, evt): """ Protected method handling timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__timer.timerId(): self.saveIfNeccessary() else: super(AutoSaver, self).timerEvent(evt) def saveIfNeccessary(self): """ Public method to activate the save operation. """ if not self.__timer.isActive(): return self.__timer.stop() self.__firstChange = QTime() self.__save()
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.pbar = QProgressBar(self) self.pbar.setGeometry(30, 40, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(40, 80) self.btn.clicked.connect(self.doAction) # タイマー self.timer = QBasicTimer() self.step = 0 self.setGeometry(300, 300, 280, 170) self.setWindowTitle('QProgressBar') self.show() def timerEvent(self, e): # カウントが100に達すると終了 if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return # 呼ばれるたび1ずつ増やす self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): """ボタンが押されると呼ばれる""" # タイマーが実行中ならタイマーを停止する if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') # タイマーが停止中ならタイマーを実行する else: # (timeout[ms], イベントの受取先) # timeoutで指定した時間間隔でシグナルが飛ぶ模様 self.timer.start(1000, self) self.btn.setText('Stop')
class WigglyLabel(object): def __init__(self, clazz): self.clazz = clazz # clazz.setBackgroundRole(QPalette.Midlight) # clazz.setAutoFillBackground(True) setattr(clazz, "paintEvent", self.paintEvent) setattr(clazz, "timerEvent", self.timerEvent) # newFont = self.clazz.font() # newFont.setPointSize(newFont.pointSize() + 20) # self.clazz.setFont(newFont) self.timer = QBasicTimer() self.step = 0; self.timer.start(60, self.clazz) def __del__(self): self.timer.stop() def getText(self): return self.clazz.text() def paintEvent(self, event): # 上下跳动 # sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38) metrics = QFontMetrics(self.clazz.font()) x = (self.clazz.width() - metrics.width(self.getText())) / 2 y = (self.clazz.height() + metrics.ascent() - metrics.descent()) / 2 color = QColor() painter = QPainter(self.clazz) for i, ch in enumerate(self.getText()): index = (self.step + i) % 16 color.setHsv((15 - index) * 16, 255, 191) painter.setPen(color) # 上下跳动 # painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), ch) painter.drawText(x, y , ch) x += metrics.width(ch) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): self.step += 1 self.clazz.update() else: super(WigglyLabel, self).timerEvent(event)
class MyQt(QWidget): def __init__(self): super(MyQt, self).__init__() self.initUI() def initUI(self): # 构建一个进度条 self.pbar = QProgressBar(self) # 从左上角30-50的界面,显示一个200*25的界面 self.pbar.setGeometry(30, 50, 200, 25) # 设置进度条的位置 # 设置开始按钮 self.btn = QPushButton('开始', self) self.btn.move(50, 90) # 按钮移动的位置 # 点击按钮 # 信号函数不能加括号 self.btn.clicked.connect(self.doAction) # 构建一个计时器 self.timer = QBasicTimer() # 计数 self.step = 0 self.setGeometry(300,300,280,170) self.setWindowTitle('我是进度条') self.setWindowIcon(QIcon('1.jpg')) self.show() def doAction(self): # 判断是否处于激活状态 if self.timer.isActive(): self.timer.stop() self.btn.setText('开始') else: self.timer.start(100,self) self.btn.setText('停止') def timerEvent(self, *args, **kwargs): if self.step>=100: # 停止进度条 self.timer.stop() self.btn.setText('完成') return self.step+=1 # 把进度条每次充值的值赋给进图条 self.pbar.setValue(self.step)
class Board(QWidget): terminoe_signal = pyqtSignal(int) line_signal = pyqtSignal(int) game_over_signal = pyqtSignal() Speed = 300 block_size = 20 BLOCK_OUTLINE_WIDTH = 2 board_width = 15 board_height = 22 AlreadyStarted = False generation = 0 def __init__(self): super(Board,self).__init__() #(win) self.currDict = {} self.initUI() self.step = 0 self.max = 500 self.timer = QBasicTimer() self.timer.start(self.max, self) self.curentShape = 4 self.currentX = 4 self.currentY = 1 self.started = False self.paused = False self.itemDown = False self.shape = Terminoe() self.counter = 0 self.totalShapes = 0 self.totalLines = 0 self.totalFullLines = 0 self.new_start = True self.chcip_app = False def initUI(self): pass # self.setFocusPolicy(Qt.StrongFocus) def start_game_again(self): self.curentShape = 4 self.currentX = 4 self.currentY = 1 self.paused = False self.itemDown = False self.shape = Terminoe() self.counter = 0 self.totalShapes = 0 self.totalLines = 0 self.totalFullLines = 0 self.clearDict() self.new_start = False self.shape.setCurrentTermino(0,True) #(1,False) self.setCurrentX(0,True) #(1,False) self.setCurrentY(self.shape.getMinY()+1,False) self.started = True def paintEvent(self, event): qp = QPainter(self) if self.chcip_app: #qp.end() sys.exit(self) #app.quit() self.update_set(qp) def draw_square(self, x, y, w, h, color, qp ) : qp.fillRect(self.block_size*x,self.block_size*y, w, h, color) qp.setPen(Qt.black) qp.drawRect(self.block_size*x,self.block_size*y, w, h) def clearDict(self): self.currDict={} for j in range(1,self.board_height+1): for i in range(1,self.board_width+1): self.currDict.update({(i,j):0}) def update_set(self , qp): if self.new_start: self.start_game_again() if not self.started: self.gameOver() self.checkFullLine() self.shape.setCurrentTermino(0,True) #(1,False) self.setCurrentX(0,True) #(1,False) self.setCurrentY(self.shape.getMinY()+1,False) self.started = True for j in range(1,self.board_height+1): for i in range(1,self.board_width+1): self.draw_square(i, j, self.block_size, self.block_size, self.shape.terminoesColors[self.currDict[i,j]],qp) for item in self.shape.terminoesCoords[self.shape.currentTermino][self.shape.status]: self.draw_square(self.currentX+item[0], self.currentY+item[1], self.block_size, self.block_size, self.shape.terminoesColors[self.shape.currentColor],qp) self.lineDown() def gameOver(self): for i in range(self.board_width): if self.currDict[i+1,1] > 0: self.game_over_signal.emit() self.timer.stop() self.started = False def new_game(self,qp): self.game_over_signal.emit() reply = QMessageBox.question(self, "G A M E O V E R!", "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: print('yes!!!!!!!!!!!!') #QApplication.quit() # return qp.end() #pyqtRestoreInputHook() sys.exit(QApplication.exec_()) else: print('no!!!!!!!!!!!!!1') self.start_game_again() return #event.ignore() ############### testing area # term = 3 # self.currentX =5 # self.currentY = 5 # for item in self.shape.terminoesCoords[term][self.counter]: # self.draw_square(self.currentX+item[0], self.currentY+item[1], self.block_size, self.block_size, self.shape.terminoesColors[term],qp) # self.currentX =5 # self.currentY = 11 # for item in self.shape.terminoesCoords[term][1]: # titem = transform() # self.draw_square(self.currentX+titem[0], self.currentYt+item[1], self.block_size, self.block_size, self.shape.terminoesColors[term],qp) # if self.counter == 3: self.counter = 0 # else: self.counter += 1 ######################################### def checkRotation(self): if self.currentX+self.shape.currentTerminoMaxX > self.board_width: return False if self.currentX-self.shape.currentTerminoMinX < 1: return False if self.currentY+self.shape.currentTerminoMaxY > self.board_height: return False for item in self.shape.terminoesCoords[self.shape.currentTermino][self.shape.status]: if self.currDict[self.currentX+item[0],self.currentY+item[1]] > 0: return False return True def checkPos(self, x): for item in self.shape.terminoesCoords[self.shape.currentTermino][self.shape.status]: if (x != 0): if (x == 1 and self.currentX+item[0]+1 > self.board_width): return False if (x == -1 and self.currentX+item[0]-1 < 1): return False if (self.currDict[self.currentX+item[0]+x,self.currentY+item[1]] > 0): return False else: if (self.currentY+self.shape.currentTerminoMaxY >= self.board_height) \ or (self.currDict[self.currentX+item[0],self.currentY+item[1]+1] > 0): self.addTerminou() return False return True def addTerminou(self): for item in self.shape.terminoesCoords[self.shape.currentTermino][self.shape.status]: self.currDict.update({(item[0]+self.currentX,item[1]+self.currentY):self.shape.currentColor}) self.started = False self.totalShapes += 1 self.terminoe_signal.emit(self.totalShapes) def moveItem(self,left): if left: if self.checkPos(-1): self.setCurrentX(self.currentX-1,False) return else: if self.checkPos(1): self.setCurrentX(self.currentX+1,False) def setCurrentX(self,i, rnd): if rnd: xx = random.randint(1,self.board_width) if xx+self.shape.getMaxX() > self.board_width: xx = self.board_width-self.shape.getMaxX() if xx-self.shape.getMinX() < 1: xx = self.shape.getMinX()+1 self.currentX = xx else: self.currentX = i def setCurrentY(self,i,rnd): if rnd: self.currentY = (random.randint(1,self.board_height)) else: self.currentY = i def timerEvent(self, event): if event.timerId() == self.timer.timerId(): self.step += 1 self.update() else: super(Board, self).timerEvent(event) def lineDown(self): if self.checkPos(0): self.setCurrentY(self.currentY+1,False) def goDown(self): while self.checkPos(0): self.setCurrentY(self.currentY+1,False) def pause(self): pass def checkFullLine(self): for i in range(1,self.board_width+1): if (self.currDict[i,self.board_height] == 0): return self.totalFullLines += 1 self.line_signal.emit(self.totalFullLines) winsound.Beep(4040, 100) # frequency, duration self.deleteHistoryLine() def deleteHistoryLine(self): oldDict = self.currDict line = self.board_height while line > 1: for i in range(1,self.board_width+1,1): self.currDict[i,line]=oldDict[i,line-1] line -=1 for i in range(1,self.board_width+1,1): self.currDict[i,1]=0 def keyPressEvent(self, event): '''processes key press events''' #if not self.started: # or self.curPiece.shape() == Tetrominoe.NoShape: # super(Board, self).keyPressEvent(event) # return key = event.key() if key == Qt.Key_P: self.pause() return if self.paused: return elif key == Qt.Key_Space: self.goDown() elif key == Qt.Key_Left: self.moveItem(True) elif key == Qt.Key_Right: self.moveItem(False) elif key == Qt.Key_Down: self.shape.setRotateRight() if not self.checkRotation(): self.shape.setRotateLeft() elif key == Qt.Key_Up: self.shape.setRotateLeft() if not self.checkRotation(): self.shape.setRotateRight() elif key == Qt.Key_D: # self.lineDown() pass else: super(Board, self).keyPressEvent(event) def change_speed(self, new_value): self.timer.start(new_value, self)
class Game(QObject): # must be static boardUpdated = pyqtSignal() statusUpdated = pyqtSignal(str) scoreUpdated = pyqtSignal(int) levelUpdated = pyqtSignal(int) pointsForSingleBlock = 1 pointsForRowCleared = 5 pointsForLevelUp = 20 # after gaining n points ** level, level increases baseSpeed = 320 # update interval for lvl 1 speedDecrement = 20 # decrement of timer for each level highSpeed = 50 # timer interval when space is pressed def __init__(self, board: Board): super().__init__() self._timer = QBasicTimer() self._board = board self._speed = self.baseSpeed self._speedBackup = self._speed self._highSpeedMode = False self._score = 0 self._level = 1 self._status = "" self._game_over = False self.new_game() def start(self): if not self._game_over: self._timer.start(self._speed, self) def stop(self): self._timer.stop() def _change_speed(self, speed): self._speed = speed if self._timer.isActive(): self.start() def _add_points(self, added): """ Updates score and speed. Number of added points is level dependent """ added = added * self._level self._score = self._score + added self.scoreUpdated.emit(self._score) self.unset_high_speed() if self._score > self._number_of_points_to_change_level( ) and self._speed - self.speedDecrement > 0: self._level = self._level + 1 self.levelUpdated.emit(self._level) self._change_speed(self._speed - self.speedDecrement) def _number_of_points_to_change_level(self): return self.pointsForLevelUp**self._level def _change_status_message(self, msg): self._status = msg self.statusUpdated.emit(msg) def timerEvent(self, event): if event.timerId() == self._timer.timerId(): if self._board.can_move_current_block(0, 1): self._board.current_block.move_down() else: self._board.permanently_insert_current_block() self._add_points(self.pointsForSingleBlock) rows_removed = self._board.remove_full_rows() self._add_points(self.pointsForRowCleared * rows_removed) if not self._board.try_insert_random_block(): self._change_status_message("Game over!") self._game_over = True self.stop() self.boardUpdated.emit() def get_status(self) -> str: return self._status def get_score(self) -> int: return self._score def get_level(self) -> int: return self._level def set_high_speed(self): if not self._highSpeedMode: self._highSpeedMode = True self._speedBackup = self._speed self._change_speed(self.highSpeed) def unset_high_speed(self): if self._highSpeedMode: self._change_speed(self._speedBackup) self._highSpeedMode = False def toggle_pause(self): if not self._game_over: if self._timer.isActive(): self._change_status_message("Paused") self.stop() else: self.start() self._change_status_message("") def new_game(self): self.stop() self._speed = self.baseSpeed self._speedBackup = self._speed self._highSpeedMode = False self._score = 0 self._level = 1 self._game_over = False self.scoreUpdated.emit(self._score) self.levelUpdated.emit(self._level) self._change_status_message("") self._board.remove_all() self._board.try_insert_random_block() self.boardUpdated.emit()
class Example(QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): # checkBox cb = QCheckBox('show title', self) cb.move(10, 10) cb.toggle() cb.stateChanged.connect(self.changeTitle) # 颜色混合 self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 30) redb.clicked[bool].connect(self.setColor) grnb = QPushButton('Green', self) grnb.setCheckable(True) grnb.move(10, 60) grnb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 90) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 50, 50) self.square.setStyleSheet("QWidget { background-color: %s}" % self.col.name()) # slider 滚动条 sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(10, 120, 100, 10) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel(self) self.label.setPixmap(QPixmap('1.png')) self.label.setGeometry(150, 90, 80, 80) # 进度条ProgressBar self.pbar = QProgressBar(self) self.pbar.setGeometry(10, 170, 200, 20) self.btn = QPushButton('Start', self) self.btn.move(10, 200) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # Calendar 日历 cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(10, 230) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(80, 440) self.setGeometry(300, 200, 300, 500) self.setWindowTitle('Toggle') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('Toogle') else: self.setWindowTitle(' ') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame {background-color: %s}" % self.col.name()) def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('1.png')) elif 0 < value <= 30: self.label.setPixmap(QPixmap('2.png')) elif 30 < value < 80: self.label.setPixmap(QPixmap('3.png')) else: self.label.setPixmap(QPixmap('4.png')) def timerEvent(self, *args, **kwargs): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step += 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop') def showDate(self, date): self.lbl.setText(date.toString())
class LightMaps(QWidget): def __init__(self, parent = None): super(LightMaps, self).__init__(parent) self.pressed = False self.snapped = False self.zoomed = False self.invert = False self._normalMap = SlippyMap(self) self._largeMap = SlippyMap(self) self.pressPos = QPoint() self.dragPos = QPoint() self.tapTimer = QBasicTimer() self.zoomPixmap = QPixmap() self.maskPixmap = QPixmap() self._normalMap.updated.connect(self.updateMap) self._largeMap.updated.connect(self.update) def setCenter(self, lat, lng): self._normalMap.latitude = lat self._normalMap.longitude = lng self._normalMap.invalidate() self._largeMap.invalidate() # slots def toggleNightMode(self): self.invert = not self.invert self.update() def updateMap(self, r): self.update(r) def activateZoom(self): self.zoomed = True self.tapTimer.stop() self._largeMap.zoom = self._normalMap.zoom + 1 self._largeMap.width = self._normalMap.width * 2 self._largeMap.height = self._normalMap.height * 2 self._largeMap.latitude = self._normalMap.latitude self._largeMap.longitude = self._normalMap.longitude self._largeMap.invalidate() self.update() def resizeEvent(self, event): self._normalMap.width = self.width() self._normalMap.height = self.height() self._normalMap.invalidate() self._largeMap.width = self._normalMap.width * 2 self._largeMap.height = self._normalMap.height * 2 self._largeMap.invalidate() def paintEvent(self, event): p = QPainter() p.begin(self) self._normalMap.render(p, event.rect()) p.setPen(Qt.black) p.drawText(self.rect(), Qt.AlignBottom | Qt.TextWordWrap, "Map data CCBYSA 2009 OpenStreetMap.org contributors") p.end() if self.zoomed: dim = min(self.width(), self.height()) magnifierSize = min(MAX_MAGNIFIER, dim * 2 / 3) radius = magnifierSize / 2 ring = radius - 15 box = QSize(magnifierSize, magnifierSize) # reupdate our mask if self.maskPixmap.size() != box: self.maskPixmap = QPixmap(box) self.maskPixmap.fill(Qt.transparent) g = QRadialGradient() g.setCenter(radius, radius) g.setFocalPoint(radius, radius) g.setRadius(radius) g.setColorAt(1.0, QColor(255, 255, 255, 0)) g.setColorAt(0.5, QColor(128, 128, 128, 255)) mask = QPainter(self.maskPixmap) mask.setRenderHint(QPainter.Antialiasing) mask.setCompositionMode(QPainter.CompositionMode_Source) mask.setBrush(g) mask.setPen(Qt.NoPen) mask.drawRect(self.maskPixmap.rect()) mask.setBrush(QColor(Qt.transparent)) mask.drawEllipse(g.center(), ring, ring) mask.end() center = self.dragPos - QPoint(0, radius) center += QPoint(0, radius / 2) corner = center - QPoint(radius, radius) xy = center * 2 - QPoint(radius, radius) # only set the dimension to the magnified portion if self.zoomPixmap.size() != box: self.zoomPixmap = QPixmap(box) self.zoomPixmap.fill(Qt.lightGray) if True: p = QPainter(self.zoomPixmap) p.translate(-xy) self._largeMap.render(p, QRect(xy, box)) p.end() clipPath = QPainterPath() clipPath.addEllipse(QPointF(center), ring, ring) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setClipPath(clipPath) p.drawPixmap(corner, self.zoomPixmap) p.setClipping(False) p.drawPixmap(corner, self.maskPixmap) p.setPen(Qt.gray) p.drawPath(clipPath) if self.invert: p = QPainter(self) p.setCompositionMode(QPainter.CompositionMode_Difference) p.fillRect(event.rect(), Qt.white) p.end() def timerEvent(self, event): if not self.zoomed: self.activateZoom() self.update() def mousePressEvent(self, event): if event.buttons() != Qt.LeftButton: return self.pressed = self.snapped = True self.pressPos = self.dragPos = event.pos() self.tapTimer.stop() self.tapTimer.start(HOLD_TIME, self) def mouseMoveEvent(self, event): if not event.buttons(): return if not self.zoomed: if not self.pressed or not self.snapped: delta = event.pos() - self.pressPos self.pressPos = event.pos() self._normalMap.pan(delta) return else: threshold = 10 delta = event.pos() - self.pressPos if self.snapped: self.snapped &= delta.x() < threshold self.snapped &= delta.y() < threshold self.snapped &= delta.x() > -threshold self.snapped &= delta.y() > -threshold if not self.snapped: self.tapTimer.stop() else: self.dragPos = event.pos() self.update() def mouseReleaseEvent(self, event): self.zoomed = False self.update() def keyPressEvent(self, event): if not self.zoomed: if event.key() == Qt.Key_Left: self._normalMap.pan(QPoint(20, 0)) if event.key() == Qt.Key_Right: self._normalMap.pan(QPoint(-20, 0)) if event.key() == Qt.Key_Up: self._normalMap.pan(QPoint(0, 20)) if event.key() == Qt.Key_Down: self._normalMap.pan(QPoint(0, -20)) if event.key() == Qt.Key_Z or event.key() == Qt.Key_Select: self.dragPos = QPoint(self.width() / 2, self.height() / 2) self.activateZoom() else: if event.key() == Qt.Key_Z or event.key() == Qt.Key_Select: self.zoomed = False self.update() delta = QPoint(0, 0) if event.key() == Qt.Key_Left: delta = QPoint(-15, 0) if event.key() == Qt.Key_Right: delta = QPoint(15, 0) if event.key() == Qt.Key_Up: delta = QPoint(0, -15) if event.key() == Qt.Key_Down: delta = QPoint(0, 15) if delta != QPoint(0, 0): self.dragPos += delta self.update()
class Tetris(QMainWindow): def __init__(self): super().__init__() self.isStarted = False self.isPaused = False self.nextMove = None self.lastShape = Shape.shapeNone self.initUI() def initUI(self): self.gridSize = 22 self.speed = 10 self.timer = QBasicTimer() self.setFocusPolicy(Qt.StrongFocus) hLayout = QHBoxLayout() self.tboard = Board(self, self.gridSize) hLayout.addWidget(self.tboard) self.sidePanel = SidePanel(self, self.gridSize) hLayout.addWidget(self.sidePanel) self.statusbar = self.statusBar() self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage) self.start() self.center() self.setWindowTitle('Tetris') self.show() self.setFixedSize(self.tboard.width() + self.sidePanel.width(), self.sidePanel.height() + self.statusbar.height()) def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2) def start(self): if self.isPaused: return self.isStarted = True self.tboard.score = 0 BOARD_DATA.clear() self.tboard.msg2Statusbar.emit(str(self.tboard.score)) BOARD_DATA.createNewPiece() self.timer.start(self.speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.tboard.msg2Statusbar.emit("paused") else: self.timer.start(self.speed, self) self.updateWindow() def updateWindow(self): self.tboard.updateData() self.sidePanel.updateData() self.update() def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if TETRIS_AI and not self.nextMove: self.nextMove = TETRIS_AI.nextMove() if self.nextMove: k = 0 while BOARD_DATA.currentDirection != self.nextMove[0] and k < 4: BOARD_DATA.rotateRight() k += 1 k = 0 while BOARD_DATA.currentX != self.nextMove[1] and k < 5: if BOARD_DATA.currentX > self.nextMove[1]: BOARD_DATA.moveLeft() elif BOARD_DATA.currentX < self.nextMove[1]: BOARD_DATA.moveRight() k += 1 # lines = BOARD_DATA.dropDown() lines = BOARD_DATA.moveDown() self.tboard.score += lines if self.lastShape != BOARD_DATA.currentShape: self.nextMove = None self.lastShape = BOARD_DATA.currentShape self.updateWindow() else: super(Tetris, self).timerEvent(event) def keyPressEvent(self, event): if not self.isStarted or BOARD_DATA.currentShape == Shape.shapeNone: super(Tetris, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: BOARD_DATA.moveLeft() elif key == Qt.Key_Right: BOARD_DATA.moveRight() elif key == Qt.Key_Up: BOARD_DATA.rotateLeft() elif key == Qt.Key_Space: self.tboard.score += BOARD_DATA.dropDown() else: super(Tetris, self).keyPressEvent(event) self.updateWindow()
class HAdjustmentBar(QWidget): valueChanged = pyqtSignal(int) def __init__(self, parent=None): super(HAdjustmentBar, self).__init__(parent) self.value = 50 self.step = 1 self.hi_value = 100 self.low_value = 50 self.timer_value = 25 self.texttemplate = 'Value = %s' self.timer = QBasicTimer() self.showToggleButton = True self.showSettingMenu = True self.bar = LabeledBar() #self.bar.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) # black magic class patching # so calling these functions actually calls the self.bar's functions. self.minimum = self.bar.minimum self.maximum = self.bar.maximum def buildWidget(self): layout = QHBoxLayout(self) layout.setContentsMargins(0,0,0,0) SettingMenu = QMenu() exitButton = QAction(QIcon('exit24.png'), 'Set As High', self) exitButton.triggered.connect(self.setHigh) SettingMenu.addAction(exitButton) setlowButton = QAction(QIcon('exit24.png'), 'Set As Low', self) setlowButton.triggered.connect(self.setLow) SettingMenu.addAction(setlowButton) self.tb_down = QToolButton() self.tb_down.pressed.connect(self.on_click_down) self.tb_down.released.connect(self.on_released) self.tb_down.setArrowType(Qt.LeftArrow) self.tb_up = QToolButton() self.tb_up.pressed.connect(self.on_click_up) self.tb_up.released.connect(self.on_released) self.tb_up.setArrowType(Qt.RightArrow) if self.showToggleButton: tb_set = QToolButton() tb_set.clicked.connect(self.on_click_set_value) tb_set.setText('<>') if self.showSettingMenu: tb_set.setMenu(SettingMenu) tb_set.setPopupMode(QToolButton.DelayedPopup) layout.addWidget(self.tb_down) layout.addWidget(self.bar) layout.addWidget(self.tb_up) if self.showToggleButton: layout.addWidget(tb_set) layout.setSpacing(0) def on_click_up(self): self.timer.start(self.timer_value, self) self.value += self.step self._setValue() def on_click_down(self): self.timer.start(self.timer_value, self) self.value -= self.step self._setValue() def on_released(self): self.timer.stop() def on_click_set_value(self): if self.value == self.hi_value: self.value = self.low_value else: self.value = self.hi_value self._setValue() def timerEvent(self, e): if self.value < self.maximum() and self.value > self.minimum(): if self.tb_down.isDown(): self.value -= self.step else: self.value += self.step self._setValue() else: self.timer.stop() def _setValue(self): if self.value < self.minimum():self. value = self.minimum() if self.value > self.maximum(): self.value = self.maximum() self.valueChanged.emit(self.value) def setValue(self, value): if value < self.minimum(): value = self.minimum() if value > self.maximum(): value = self.maximum() self.value = int(value) tmpl = lambda s: self.texttemplate % s try: self.bar.text = tmpl(int(value)) except: self.bar.text = self.texttemplate self.bar.setValue(int(value)) self.bar.update() def setHigh(self): self.hi_value = self.value def setLow(self): self.low_value = self.value def setMaximum(self, data): if data < self.hi_value: self.hi_value = data self.bar.setMaximum(data) def setMinimum(self, data): if data > self.low_value: self.low_value = data self.bar.setMinimum(data)
class Gui(QWidget): def __init__(self): super().__init__() self.mySocket = socket.socket() self.params = {} self.responseThread = ResponseThread(self.mySocket) self.isPlaying = False self.setGeometry(300, 200, 280, 300) self.setWindowTitle('Kodi Remote Control') self.setWindowIcon(QIcon(ICON_PATH)) self.img = QLabel('img') self.img.setPixmap(QPixmap(IMG_PATH)) self.status = QLabel('OK') self.pbar = QProgressBar() self.progress = 0 self.timer = QBasicTimer() box = QVBoxLayout() box.addWidget(self.img) box.addWidget(self.status) box.addWidget(self.pbar) self.setLayout(box) self.show() self.setFixedSize(self.size()) self.responseThread.mySignal.connect(self.handleSignals) self.responseThread.start() def handleSignals(self, signal, param): if signal == 'Input.OnInputRequested': self.showInputDialog() print("Text sending") if signal == 'Player.OnStop': self.isPlaying = False self.status.setText( 'Nothing playing now' ) self.img.setPixmap(QPixmap(IMG_PATH)) if self.timer.isActive(): self.timer.stop() self.pbar.setValue(0) print('Stoping timer') if signal == 'play': self.isPlaying = True self.status.setText( param ) self.rpc("Player.GetItem",{"properties":["thumbnail","fanart"],"playerid":1}, True) if not self.timer.isActive(): self.timer.start(1000, self) print('Starting timer') if signal == 'queue': gui.rpc("GUI.ShowNotification",{"title":"Added to playlist!", "message":param}, False) if signal == 'System.OnQuit' or signal == 'System.OnRestart': if self.timer.isActive(): self.timer.stop() print('Stoping timer') self.quit(False) if signal == 'thumbnail': url = urllib.parse.unquote(param) try: img_arr = urllib.request.urlopen(url).read() qImg = QImage() qImg.loadFromData(img_arr) self.img.setPixmap(QPixmap(qImg)) except Exception as e: print("---> Error while getting image: %s" % e) if signal == 'time': tokens = param.split('-',1) curTime = int(tokens[0]) totTime = int(tokens[1]) if totTime>0: self.pbar.setValue((curTime/totTime)*100) if signal == 'addons': OpenDialog(param, self).exec_() #print (signal) def timerEvent(self, e): self.rpc("Player.GetProperties",{"playerid":1,"properties":["totaltime","time"]}, True) def showInputDialog(self): text, ok = QInputDialog.getText(self, 'Send Text', 'Type here what you want to send:') if ok: self.rpc("Input.SendText",{"text":str(text)}, False) def showHelpDialog(self): HelpDialog().exec_() def keyPressEvent(self, e): if e.key() == Qt.Key_Up: self.rpc("Input.Up",[], False) elif e.key() == Qt.Key_Down: self.rpc("Input.Down",[], False) elif e.key() == Qt.Key_Left: self.rpc("Input.Left",[], False) elif e.key() == Qt.Key_Right: self.rpc("Input.Right",[], False) elif e.key() == Qt.Key_F9: self.rpc("Input.ExecuteAction",{"action":"volumedown"}, False) elif e.key() == Qt.Key_F10: self.rpc("Input.ExecuteAction",{"action":"volumeup"}, False) elif e.key() == Qt.Key_F11: self.rpc("Input.ExecuteAction",{"action":"mute"}, False) elif e.key() == Qt.Key_Tab: self.rpc("Input.ExecuteAction",{"action":"fullscreen"}, False) elif e.key() == Qt.Key_Space: self.rpc("Input.ExecuteAction",{"action":"playpause"}, False) elif e.key() == Qt.Key_Control: if self.isPlaying: self.rpc("Input.ShowOSD",[], False) elif e.key() == Qt.Key_PageUp: self.rpc("Input.ExecuteAction",{"action":"pageup"}, False) elif e.key() == Qt.Key_PageDown: self.rpc("Input.ExecuteAction",{"action":"pagedown"}, False) elif e.key() == Qt.Key_Escape: self.rpc("Input.ExecuteAction",{"action":"parentfolder"}, False) elif e.key() == Qt.Key_Home: self.rpc("Input.Home",[], False) elif e.key() == Qt.Key_Backspace: self.rpc("Input.Back",[], False) elif e.key() == Qt.Key_Return: self.rpc("Input.Select",[], False) elif e.key() == Qt.Key_I: if self.isPlaying: self.rpc("Player.GetItem",{"playerid":1}, True) else: self.rpc("Input.Info",[], False) elif e.key() == Qt.Key_O: self.rpc("Addons.GetAddons",{"content":"video"}, True) elif e.key() == Qt.Key_Q: self.status.setText("Quiting now...") self.quit(True) elif e.key() == Qt.Key_A: self.rpc("Input.ExecuteAction",{"action":"queue"}, True) elif e.key() == Qt.Key_C: self.rpc("Input.ContextMenu",[], False) elif e.key() == Qt.Key_P: self.rpc("Input.ExecuteAction",{"action":"playlist"}, True) elif e.key() == Qt.Key_Z: self.rpc("Input.ExecuteAction",{"action":"aspectratio"}, False) elif e.key() == Qt.Key_Comma: self.rpc("Input.ExecuteAction",{"action":"stepback"}, False) elif e.key() == Qt.Key_Period: self.rpc("Input.ExecuteAction",{"action":"stepforward"}, False) elif e.key() == Qt.Key_BracketLeft: self.rpc("Input.ExecuteAction",{"action":"subtitledelayminus"}, False) elif e.key() == Qt.Key_BracketRight: self.rpc("Input.ExecuteAction",{"action":"subtitledelayplus"}, False) elif e.key() == Qt.Key_Equal: self.rpc("Input.ExecuteAction",{"action":"volampup"}, False) elif e.key() == Qt.Key_Minus: self.rpc("Input.ExecuteAction",{"action":"volampdown"}, False) elif e.key() == Qt.Key_1: self.rpc("Addons.ExecuteAddon",{"addonid":"plugin.video.exodus"}, False) elif e.key() == Qt.Key_2: self.rpc("Addons.ExecuteAddon",{"addonid":"plugin.video.twitch"}, False) elif e.key() == Qt.Key_F1: self.showHelpDialog() elif e.key() == Qt.Key_Backslash: self.showInputDialog() def rpc(self, method, params, should_respond): d = { "jsonrpc": "2.0", "method": method, "params": params, } if should_respond: d.update({"id":1}) m = json.dumps(d) self.mySocket.send(m.encode()) def quit(self, shutdownKodi): if self.responseThread.isRunning(): #print("Killing thread") self.responseThread.terminate() print("Killed thread") if shutdownKodi: self.rpc("System.Shutdown",[], False) self.mySocket.close() print("Dropped tcp connection") sys.exit(0)
class TetrixBoard(QFrame): BoardWidth = 10 BoardHeight = 22 scoreChanged = pyqtSignal(int) levelChanged = pyqtSignal(int) linesRemovedChanged = pyqtSignal(int) def __init__(self, parent=None): super(TetrixBoard, self).__init__(parent) self.timer = QBasicTimer() self.nextPieceLabel = None self.isWaitingAfterLine = False self.curPiece = TetrixPiece() self.nextPiece = TetrixPiece() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.numPiecesDropped = 0 self.score = 0 self.level = 0 self.board = None self.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() self.nextPiece.setRandomShape() def shapeAt(self, x, y): return self.board[(y * TetrixBoard.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * TetrixBoard.BoardWidth) + x] = shape def timeoutTime(self): return 1000 / (1 + self.level) def squareWidth(self): return self.contentsRect().width() / TetrixBoard.BoardWidth def squareHeight(self): return self.contentsRect().height() / TetrixBoard.BoardHeight def setNextPieceLabel(self, label): self.nextPieceLabel = label def sizeHint(self): return QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2, TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2) def minimumSizeHint(self): return QSize(TetrixBoard.BoardWidth * 5 + self.frameWidth() * 2, TetrixBoard.BoardHeight * 5 + self.frameWidth() * 2) def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.numPiecesDropped = 0 self.score = 0 self.level = 1 self.clearBoard() self.linesRemovedChanged.emit(self.numLinesRemoved) self.scoreChanged.emit(self.score) self.levelChanged.emit(self.level) self.newPiece() self.timer.start(self.timeoutTime(), self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() else: self.timer.start(self.timeoutTime(), self) self.update() def paintEvent(self, event): super(TetrixBoard, self).paintEvent(event) painter = QPainter(self) rect = self.contentsRect() if self.isPaused: painter.drawText(rect, Qt.AlignCenter, "Pause") return boardTop = rect.bottom( ) - TetrixBoard.BoardHeight * self.squareHeight() for i in range(TetrixBoard.BoardHeight): for j in range(TetrixBoard.BoardWidth): shape = self.shapeAt(j, TetrixBoard.BoardHeight - i - 1) if shape != NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (TetrixBoard.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): if not self.isStarted or self.isPaused or self.curPiece.shape( ) == NoShape: super(TetrixBoard, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(TetrixBoard, self).keyPressEvent(event) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() self.timer.start(self.timeoutTime(), self) else: self.oneLineDown() else: super(TetrixBoard, self).timerEvent(event) def clearBoard(self): self.board = [ NoShape for i in range(TetrixBoard.BoardHeight * TetrixBoard.BoardWidth) ] def dropDown(self): dropHeight = 0 newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 dropHeight += 1 self.pieceDropped(dropHeight) def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped(0) def pieceDropped(self, dropHeight): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.numPiecesDropped += 1 if self.numPiecesDropped % 25 == 0: self.level += 1 self.timer.start(self.timeoutTime(), self) self.levelChanged.emit(self.level) self.score += dropHeight + 7 self.scoreChanged.emit(self.score) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 for i in range(TetrixBoard.BoardHeight - 1, -1, -1): lineIsFull = True for j in range(TetrixBoard.BoardWidth): if self.shapeAt(j, i) == NoShape: lineIsFull = False break if lineIsFull: numFullLines += 1 for k in range(TetrixBoard.BoardHeight - 1): for j in range(TetrixBoard.BoardWidth): self.setShapeAt(j, k, self.shapeAt(j, k + 1)) for j in range(TetrixBoard.BoardWidth): self.setShapeAt(j, TetrixBoard.BoardHeight - 1, NoShape) if numFullLines > 0: self.numLinesRemoved += numFullLines self.score += 10 * numFullLines self.linesRemovedChanged.emit(self.numLinesRemoved) self.scoreChanged.emit(self.score) self.timer.start(500, self) self.isWaitingAfterLine = True self.curPiece.setShape(NoShape) self.update() def newPiece(self): self.curPiece = copy.deepcopy(self.nextPiece) self.nextPiece.setRandomShape() self.showNextPiece() self.curX = TetrixBoard.BoardWidth // 2 + 1 self.curY = TetrixBoard.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(NoShape) self.timer.stop() self.isStarted = False def showNextPiece(self): if self.nextPieceLabel is None: return dx = self.nextPiece.maxX() - self.nextPiece.minX() + 1 dy = self.nextPiece.maxY() - self.nextPiece.minY() + 1 pixmap = QPixmap(dx * self.squareWidth(), dy * self.squareHeight()) painter = QPainter(pixmap) painter.fillRect(pixmap.rect(), self.nextPieceLabel.palette().window()) for i in range(4): x = self.nextPiece.x(i) - self.nextPiece.minX() y = self.nextPiece.y(i) - self.nextPiece.minY() self.drawSquare(painter, x * self.squareWidth(), y * self.squareHeight(), self.nextPiece.shape()) painter.end() self.nextPieceLabel.setPixmap(pixmap) def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= TetrixBoard.BoardWidth or y < 0 or y >= TetrixBoard.BoardHeight: return False if self.shapeAt(x, y) != NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class mywindow(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.F = MyFigure(width=1,height=1,dpi=100) self.F.plotsin() self.timer = QBasicTimer() self.step = 0 #self.workmodule1.clicked.connect(self.workmodule_1) #全局布局 self.GlobalLayout=QHBoxLayout() #三个按钮 self.fasong_btn1 = QPushButton('存储', self) self.fasong_btn1.setFont(QFont("微软雅黑",20,QFont.Bold)) self.fasong_btn1.setFixedSize(140,60) self.fasong_btn1.clicked.connect(self.cunchu) self.fasong_btn2 = QPushButton('温度',self) self.fasong_btn2.setFont(QFont("微软雅黑",20,QFont.Bold)) self.fasong_btn2.setFixedSize(140,60) self.fasong_btn2.clicked.connect(self.wendu) self.fasong_btn3 = QPushButton('工作状态',self) self.fasong_btn3.setFont(QFont("微软雅黑",12,QFont.Bold)) self.fasong_btn3.setFixedSize(140,60) self.fasong_btn3.clicked.connect(self.work) #工作模式按钮 self.workmodule1=QPushButton('模式1',self) self.workmodule1.setFont(QFont("微软雅黑",18,QFont.Bold)) self.workmodule1.setFixedSize(100,100) #self.workmodule1.clicked.connect(self.workmodule_1) self.workmodule1.clicked.connect(self.doAction) self.workmodule2=QPushButton('模式2',self) self.workmodule2.setFont(QFont("微软雅黑",18,QFont.Bold)) self.workmodule2.setFixedSize(100,100) self.workmodule3=QPushButton('模式3',self) self.workmodule3.setFont(QFont("微软雅黑",18,QFont.Bold)) self.workmodule3.setFixedSize(100,100) #存储按钮 self.cunchu_btn1 = QPushButton('',self) self.cunchu_btn1.clicked.connect(self.cunchu_btn1_1) self.cunchu_btn1.setFixedSize(90,90) self.cunchu_btn1.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn2 = QPushButton('',self) self.cunchu_btn2.setFixedSize(90,90) self.cunchu_btn3 = QPushButton('',self) self.cunchu_btn3.setFixedSize(90,90) self.cunchu_btn4 = QPushButton('',self) self.cunchu_btn4.setFixedSize(90,90) self.cunchu_btn5 = QPushButton('',self) self.cunchu_btn5.setFixedSize(90,90) self.cunchu_btn6 = QPushButton('',self) self.cunchu_btn6.setFixedSize(90,90) self.cunchu_btn7 = QPushButton('',self) self.cunchu_btn7.setFixedSize(90,90) self.cunchu_btn8 = QPushButton('',self) self.cunchu_btn8.setFixedSize(90,90) self.cunchu_btn9 = QPushButton('',self) self.cunchu_btn9.setFixedSize(90,90) self.cunchu_btn10 = QPushButton('',self) self.cunchu_btn10.setFixedSize(90,90) self.cunchu_btn11 = QPushButton('',self) self.cunchu_btn11.setFixedSize(90,90) self.cunchu_btn12 = QPushButton('',self) self.cunchu_btn12.setFixedSize(90,90) self.cunchu_btn13 = QPushButton('',self) self.cunchu_btn13.setFixedSize(90,90) self.cunchu_btn14 = QPushButton('',self) self.cunchu_btn14.setFixedSize(90,90) self.cunchu_btn15 = QPushButton('',self) self.cunchu_btn15.setFixedSize(90,90) self.cunchu_btn16 = QPushButton('',self) self.cunchu_btn16.setFixedSize(90,90) self.cunchu_btn17 = QPushButton('',self) self.cunchu_btn17.setFixedSize(90,90) self.cunchu_btn18 = QPushButton('',self) self.cunchu_btn18.setFixedSize(90,90) self.cunchu_btn19 = QPushButton('',self) self.cunchu_btn19.setFixedSize(90,90) self.cunchu_btn20 = QPushButton('',self) self.cunchu_btn20.setFixedSize(90,90) self.cunchu_btn21 = QPushButton('',self) self.cunchu_btn21.setFixedSize(90,90) self.cunchu_btn22 = QPushButton('',self) self.cunchu_btn22.setFixedSize(90,90) self.cunchu_btn23 = QPushButton('',self) self.cunchu_btn23.setFixedSize(90,90) self.cunchu_btn24 = QPushButton('',self) self.cunchu_btn24.setFixedSize(90,90) self.cunchu_btn25 = QPushButton('',self) self.cunchu_btn25.setFixedSize(90,90) self.cunchu_btn26 = QPushButton('',self) self.cunchu_btn26.setFixedSize(90,90) self.cunchu_btn27 = QPushButton('',self) self.cunchu_btn27.setFixedSize(90,90) self.cunchu_btn28 = QPushButton('',self) self.cunchu_btn28.setFixedSize(90,90) self.cunchu_btn29 = QPushButton('',self) self.cunchu_btn29.setFixedSize(90,90) self.cunchu_btn30 = QPushButton('',self) self.cunchu_btn30.setFixedSize(90,90) self.cunchu_btn31 = QPushButton('',self) self.cunchu_btn31.setFixedSize(90,90) self.cunchu_btn32 = QPushButton('',self) self.cunchu_btn32.setFixedSize(90,90) self.cunchu_btn33 = QPushButton('',self) self.cunchu_btn33.setFixedSize(90,90) self.cunchu_btn34 = QPushButton('',self) self.cunchu_btn34.setFixedSize(90,90) self.cunchu_btn35 = QPushButton('',self) self.cunchu_btn35.setFixedSize(90,90) self.cunchu_btn36 = QPushButton('',self) self.cunchu_btn36.setFixedSize(90,90) self.cunchu_btn2.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn3.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn4.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn5.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn6.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn7.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn8.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn9.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn10.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn11.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn12.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn13.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn14.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn15.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn16.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn17.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn18.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn19.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn20.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn21.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn22.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn23.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn24.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn25.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn26.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn27.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn28.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn29.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn30.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn31.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn32.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn33.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn34.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn35.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") self.cunchu_btn36.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(255,0,0)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") #左边框 vlayout = QVBoxLayout(self) vlayout.addWidget(self.fasong_btn1) vlayout.addWidget(self.fasong_btn2) vlayout.addWidget(self.fasong_btn3) #hbox = QHBoxLayout(self) ###将界面分割成可以自由拉伸的三个窗口 #第一个,左上角,图像显示框 self.topleft = QFrame(self) self.topleft.setFrameShape(QFrame.StyledPanel) self.topleft.setLayout(vlayout) #第二个,右上角串口选择框 self.topright = QStackedWidget(self) self.topright.setStyleSheet("background:url(:Icon/meidui.jpg)") CunFrame = QFrame() CunFrame.setFrameShape(QFrame.StyledPanel) Cunlayout = QGridLayout() Cunlayout.addWidget(self.cunchu_btn1,0,0) Cunlayout.addWidget(self.cunchu_btn2,0,1) Cunlayout.addWidget(self.cunchu_btn3,0,2) Cunlayout.addWidget(self.cunchu_btn4,0,3) Cunlayout.addWidget(self.cunchu_btn5,0,4) Cunlayout.addWidget(self.cunchu_btn6,0,5) Cunlayout.addWidget(self.cunchu_btn7,1,0) Cunlayout.addWidget(self.cunchu_btn8,1,1) Cunlayout.addWidget(self.cunchu_btn9,1,2) Cunlayout.addWidget(self.cunchu_btn10,1,3) Cunlayout.addWidget(self.cunchu_btn11,1,4) Cunlayout.addWidget(self.cunchu_btn12,1,5) Cunlayout.addWidget(self.cunchu_btn13,2,0) Cunlayout.addWidget(self.cunchu_btn14,2,1) Cunlayout.addWidget(self.cunchu_btn15,2,2) Cunlayout.addWidget(self.cunchu_btn16,2,3) Cunlayout.addWidget(self.cunchu_btn17,2,4) Cunlayout.addWidget(self.cunchu_btn18,2,5) Cunlayout.addWidget(self.cunchu_btn19,3,0) Cunlayout.addWidget(self.cunchu_btn20,3,1) Cunlayout.addWidget(self.cunchu_btn21,3,2) Cunlayout.addWidget(self.cunchu_btn22,3,3) Cunlayout.addWidget(self.cunchu_btn23,3,4) Cunlayout.addWidget(self.cunchu_btn24,3,5) Cunlayout.addWidget(self.cunchu_btn25,4,0) Cunlayout.addWidget(self.cunchu_btn26,4,1) Cunlayout.addWidget(self.cunchu_btn27,4,2) Cunlayout.addWidget(self.cunchu_btn28,4,3) Cunlayout.addWidget(self.cunchu_btn29,4,4) Cunlayout.addWidget(self.cunchu_btn30,4,5) Cunlayout.addWidget(self.cunchu_btn31,5,0) Cunlayout.addWidget(self.cunchu_btn32,5,1) Cunlayout.addWidget(self.cunchu_btn33,5,2) Cunlayout.addWidget(self.cunchu_btn34,5,3) Cunlayout.addWidget(self.cunchu_btn35,5,4) Cunlayout.addWidget(self.cunchu_btn36,5,5) CunFrame.setLayout(Cunlayout) self.topright.addWidget(CunFrame) #温度 WenFrame = QFrame(self) WenFrame.setFrameShape(QFrame.StyledPanel) Wenlayout = QHBoxLayout() Wenlayout.addWidget(self.F) WenFrame.setLayout(Wenlayout) self.topright.addWidget(WenFrame) #工作状态 WorkFrame = QFrame(self) WorkFrame.setFrameShape(QFrame.StyledPanel) Worklayout = QVBoxLayout() self.WeiZhi_btn = QPushButton('未知血型',self) self.WeiZhi_btn.setFont(QFont("微软雅黑",16,QFont.Bold)) self.WeiZhi_btn.setFixedSize(140,80) self.YiZhi_btn = QPushButton('已知血型',self) self.YiZhi_btn.setFont(QFont("微软雅黑",16,QFont.Bold)) self.YiZhi_btn.setFixedSize(140,80) self.ChuXue_btn = QPushButton('直接出血',self) self.ChuXue_btn.setFont(QFont("微软雅黑",16,QFont.Bold)) self.ChuXue_btn.setFixedSize(140,80) hFrame = QFrame() vFrame = QFrame() #vFrame.setFocus() hwg = QHBoxLayout() vwg = QVBoxLayout() hwg.addWidget(self.WeiZhi_btn) hwg.addWidget(self.YiZhi_btn) hwg.addWidget(self.ChuXue_btn) self.prsbar = QProgressBar(self) self.jindu_btn = QPushButton(self) self.jindu_btn.setFixedSize(180,80) #self.lb1 = QLineEdit(self) #vwg.setAlignment(Qt.AlignVCenter) vwg.setAlignment(Qt.AlignHCenter) #vwg.addWidget(self.jindu_btn) vwg.addWidget(self.prsbar,Qt.AlignHCenter) #vwg.addWidget(self.lb1,Qt.AlignHCenter) vwg.addWidget(self.jindu_btn) hFrame.setLayout(hwg) vFrame.setLayout(vwg) Worklayout.addWidget(hFrame) Worklayout.addWidget(vFrame) WorkFrame.setLayout(Worklayout) self.topright.addWidget(WorkFrame) #第三个,底部,串口通信框 self.bottom = QFrame(self) self.bottom.setFrameShape(QFrame.StyledPanel) bwg=QHBoxLayout() bwg.addWidget(self.workmodule1) bwg.addWidget(self.workmodule2) bwg.addWidget(self.workmodule3) self.bottom.setLayout(bwg) self.bottom.setStyleSheet("#MainWindow{border-image:url(Icon/xinbo.png);}") #调用splitter控件,使窗口可以拖动起来 splitter1 = QSplitter(Qt.Horizontal) splitter1.addWidget(self.topleft) splitter1.addWidget(self.topright) splitter1.setSizes([80,600]) splitter2=QSplitter(Qt.Vertical) splitter2.addWidget(splitter1) splitter2.addWidget(self.bottom) splitter2.setSizes([800,200]) self.GlobalLayout.addWidget(splitter2) #topright.setLayout(hbox) self.setLayout(self.GlobalLayout) self.setGeometry(300, 300, 800, 600) self.setWindowTitle('莘博医疗') self.setWindowIcon(QIcon('Icon\senbo.jpg')) self.show() def cunchu_btn1_1(self): self.cunchu_btn1.setStyleSheet("QPushButton{color:black}" "QPushButton:hover{color:red}" "QPushButton{background-color:rgb(175,238,238)}" "QPushButton{border:2px}" "QPushButton{border-radius:10px}" "QPushButton{padding:2px 4px}") def workmodule_31(self): print(self.step) #self.jindu_btn.setText('jiaocha') if self.step == 18 : #print('asdas') self.jindu_btn.setText('交叉配血') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) elif self.step == 40: self.jindu_btn.setText('孵育') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) elif self.step == 60: self.jindu_btn.setText('离心') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) elif self.step ==80: self.jindu_btn.setText('图像处理') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) def timerEvent(self, e): if self.step == 100: self.jindu_btn.setText('检测完毕') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) self.timer.stop() #return self.step = self.step+1 self.workmodule_31() # print('jwhy') # if(int(self.step) >= 100): # self.jindu_btn.setText('离心') # print('jwhy') # self.lb1.setText('djaoisdj') self.prsbar.setValue(self.step) def doAction(self, value): if self.timer.isActive(): self.timer.stop() else: self.timer.start(700, self) self.jindu_btn.setText('离心') self.jindu_btn.setFont(QFont("微软雅黑",20,QFont.Bold)) def closeEvent(self, event): reply = QMessageBox.question(self, '提示', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def cunchu(self): self.topright.setCurrentIndex(0) def wendu(self): self.topright.setCurrentIndex(1) def work(self): self.topright.setCurrentIndex(2)
class FieldUI(QFrame): def __init__(self, parent, game): super().__init__(parent) self.main_window = parent self.game = game self.rocks = self.game.rocks self.powerups = self.game.powerups self.bullets = self.game.bullets self.width, self.height = self.game.dimensions self.init_timers() self.start_timers() self.player_ui = PlayerUI(self, self.game) self.init_signals() self.setFocusPolicy(Qt.StrongFocus) def init_timers(self): """Initializes the timers in the game.""" self.game_timer = QBasicTimer() self.rock_timer = QBasicTimer() self.level_timer = QBasicTimer() self.powerup_timer = QBasicTimer() self.ticker_timer = QBasicTimer() self.bullet_timer = QBasicTimer() self.player_invincibility_timer = QBasicTimer() self.big_bomb_timer = QBasicTimer() self.slow_down_rocks_timer = QBasicTimer() self.shoot_rocks_timer = QBasicTimer() self.powerup_duration_timer = QTimer() def start_timers(self): """Starts the timers in the game.""" self.game_timer.start(self.game.game_speed, self) self.rock_timer.start(self.game.rock_speed, self) self.level_timer.start(self.game.level_speed, self) self.powerup_timer.start(self.game.rock_speed, self) self.player_invincibility_timer.start(int(PowerupTimeInterval.medium), self) self.big_bomb_timer.start(int(PowerupTimeInterval.big), self) self.slow_down_rocks_timer.start(int(PowerupTimeInterval.medium), self) self.shoot_rocks_timer.start(int(PowerupTimeInterval.very_big), self) self.bullet_timer.start(self.game.bullet_speed, self) def stop_timers(self): """Stops the timers in the game.""" self.game_timer.stop() self.rock_timer.stop() self.level_timer.stop() self.powerup_timer.stop() self.ticker_timer.stop() self.bullet_timer.stop() self.player_invincibility_timer.stop() self.big_bomb_timer.stop() self.slow_down_rocks_timer.stop() self.shoot_rocks_timer.stop() self.powerup_duration_timer.stop() def init_signals(self): """Initializes the signals in the game that connect to a method and calls it after the singnals are emitted. """ self.com = Communicate() self.com.move_left.connect(self.player_ui.move_left) self.com.move_right.connect(self.player_ui.move_right) self.com.restart.connect(self.main_window.restart_game) self.com.exit.connect(UserInterface.close_app) self.com.win.connect(self.win_the_game) def timerEvent(self, event): """Gets the emitted events from the timers and calls the appropriate methods for each of them. """ self.powerups_timer_events(event) self.gameplay_timer_events(event) if event.timerId() == self.ticker_timer.timerId(): self.ticker["value"] -= 1 if self.ticker["type"] == "player_invincibility": self.show_player_invincibility_info(self.ticker["value"]) if self.ticker["type"] == "slow_down_rocks": self.show_slow_down_rocks_info(self.ticker["value"]) if self.ticker["type"] == "shoot_rocks": self.show_shoot_rocks_info(self.ticker["value"]) self.bullet_ui = BulletUI(self, self.game, self.player_ui) self.bullets.append(self.bullet_ui) else: super(FieldUI, self).timerEvent(event) def gameplay_timer_events(self, event): """Gets the emitted events from the timers related to the gameplay and calls the appropriate methods and initializes the appropriate objects for each of them. """ if event.timerId() == self.game_timer.timerId(): self.rock_ui = RockUI(self, self.game) self.rocks.append(self.rock_ui) elif event.timerId() == self.rock_timer.timerId(): self.drop_down_rocks() elif event.timerId() == self.powerup_timer.timerId(): self.drop_down_powerups() elif event.timerId() == self.level_timer.timerId(): self.game.level_up() self.game_level = self.game.level if self.game_level == 21: self.com.win.emit() return self.game.set_speed_after_levelup() self.main_window.communicate.message_statusbar.\ emit("Level " + str(self.game_level)) self.game_timer.start(self.game.game_speed, self) self.rock_timer.start(self.game.rock_speed, self) elif event.timerId() == self.bullet_timer.timerId(): if self.bullets.count != 0: self.shoot_bullets() def powerups_timer_events(self, event): """Gets the emitted events from the timers related to the powerups and calls the appropriate methods and initializes the appropriate objects for each of them. """ if event.timerId() == self.player_invincibility_timer.timerId(): self.powerup_timer.start(self.game.rock_speed, self) self.powerup_ui = PowerupUI(self, self.game, PowerupType. player_invinciblility) self.powerups.append(self.powerup_ui) elif event.timerId() == self.big_bomb_timer.timerId(): self.powerup_timer.start(self.game.rock_speed, self) self.powerup_ui = PowerupUI(self, self.game, PowerupType.big_bomb) self.powerups.append(self.powerup_ui) elif event.timerId() == self.slow_down_rocks_timer.timerId(): self.powerup_timer.start(self.game.rock_speed, self) self.powerup_ui = PowerupUI(self, self.game, PowerupType.slow_down_rocks) self.powerups.append(self.powerup_ui) elif event.timerId() == self.shoot_rocks_timer.timerId(): self.powerup_timer.start(self.game.rock_speed, self) self.powerup_ui = PowerupUI(self, self.game, PowerupType.shoot_rocks) self.powerups.append(self.powerup_ui) def win_the_game(self): """Wins the game and shows an appropriate message to the player.""" self.game.win() self.stop_timers() self.main_window.communicate.message_statusbar.\ emit("You've won the game. You are a survivor. Well done!") def drop_down_powerups(self): """Moves the powerups down and check if the move is out of the game field. If that is true the powerups are removed from the field. """ temp_powerup = None for powerup in self.powerups: if(powerup.y >= self.game.dimensions[1] - powerup.height): temp_powerup = powerup else: powerup.drop_down() self.check_collision_between_player_and_powerup(powerup) if temp_powerup is not None: self.remove_powerup_from_field(temp_powerup) def check_collision_between_player_and_powerup(self, powerup): """Checks for a collision between the player and the powerups. If that is true initializes the powerups' effect according to their type. """ if(self.game.collision_detected(self.player_ui, powerup)): if powerup.type == PowerupType.player_invinciblility: self.init_player_invincibility(powerup) elif powerup.type == PowerupType.big_bomb: self.init_big_bomb() elif powerup.type == PowerupType.slow_down_rocks: self.init_slow_down_rocks(powerup) elif powerup.type == PowerupType.shoot_rocks: self.init_shoot_rocks(powerup) def init_slow_down_rocks(self, powerup): """Initializes the powerup slow_down_rocks and it's effect of the game.""" self.game.set_rock_speed(self.game.rock_speed + 3) self.game.set_speed(self.game.game_speed + 25) self.game_timer.start(self.game.game_speed, self) self.rock_timer.start(self.game.rock_speed, self) self.ticker = {"type": "slow_down_rocks", "value": powerup.duration // 1000} self.show_slow_down_rocks_info(self.ticker["value"]) self.ticker_timer.start(PowerupTimeInterval.second, self) self.powerup_duration_timer.setSingleShot(True) self.powerup_duration_timer.singleShot(powerup.duration, self.stop_slow_down_rocks) def show_slow_down_rocks_info(self, value): """Shows information about the powerup slow_down_rocks to the player. """ self.main_window.communicate.message_statusbar.\ emit("The rock are slowed down for " + str(value) + " seconds") def stop_slow_down_rocks(self): """Stops the effect of the powerup slow_down_rocks and shows a message to the player. """ self.powerup_duration_timer.stop() self.ticker_timer.stop() self.game.set_rock_speed(self.game.rock_speed - 3) self.game.set_speed(self.game.game_speed - 25) self.game_timer.start(self.game.game_speed, self) self.rock_timer.start(self.game.rock_speed, self) self.main_window.communicate.message_statusbar.\ emit("The rock are no longer slowed down. Be careful!") def shoot_bullets(self): """Moves the bullets up (to the target) and check if the move is out of the game field. If that is true the bullets are removed from the field. """ temp_bullet = None for bullet in self.bullets: if(bullet.y <= 1): temp_bullet = bullet else: bullet.move_to_target() self.check_collision_between_bullet_and_rock(bullet) if temp_bullet is not None: self.remove_bullet_from_field(temp_bullet) def check_collision_between_bullet_and_rock(self, bullet): """Checks for a collision between the bullets and the rocks. If that is true removes the rocks from the game field. """ for rock in self.rocks: if self.game.collision_detected(bullet, rock): self.remove_rock_from_field(rock) def init_shoot_rocks(self, powerup): """Initializes the powerup shoot_rocks and it's effect of the game.""" self.ticker = {"type": "shoot_rocks", "value": powerup.duration // 1000} self.show_shoot_rocks_info(self.ticker["value"]) self.ticker_timer.start(PowerupTimeInterval.second, self) self.powerup_duration_timer.setSingleShot(True) self.powerup_duration_timer.singleShot(powerup.duration, self.stop_shoot_rocks) def show_shoot_rocks_info(self, value): """Shows information about the powerup shoot_rocks to the player.""" self.main_window.communicate.message_statusbar.\ emit("You have bullets for " + str(value) + " seconds") def stop_shoot_rocks(self): """Stops the effect of the powerup shoot_rocks and shows a message to the player. """ self.powerup_duration_timer.stop() self.ticker_timer.stop() self.main_window.communicate.message_statusbar.\ emit("No more bullets!") def init_big_bomb(self): """Initializes the powerup big_bomb and it's effect of the game.""" temp_rocks = self.rocks[:] for temp_rock in temp_rocks: self.remove_rock_from_field(temp_rock) self.main_window.communicate.message_statusbar.\ emit("BOOM! The blast totally destroyed everything on the field!") def init_player_invincibility(self, powerup): """Initializes the powerup player_invincibility and it's effect of the game. """ if not self.player_ui.is_player_invincible: self.player_ui.set_player_invinciblity() self.ticker = {"type": "player_invincibility", "value": powerup.duration // 1000} self.show_player_invincibility_info(self.ticker["value"]) self.ticker_timer.start(PowerupTimeInterval.second, self) self.powerup_duration_timer.setSingleShot(True) self.powerup_duration_timer.singleShot( powerup.duration, self.stop_player_invincibility ) def stop_player_invincibility(self): """Stops the effect of the powerup player_invincibility and shows a message to the player. """ self.powerup_duration_timer.stop() self.ticker_timer.stop() self.player_ui.set_player_invinciblity() self.main_window.communicate.message_statusbar.\ emit("The player's invinciblility is off. You are mortal again!") def show_player_invincibility_info(self, value): """Shows information about the powerup player_invincibility_info to the player. """ self.main_window.communicate.message_statusbar.\ emit("The player is invincible for " + str(value) + " seconds") def remove_powerup_from_field(self, powerup): """Removes a powerup from the game field.""" self.powerups.remove(powerup) powerup.remove_shape() if(self.powerups.count == 0): self.powerup_timer.stop() def remove_bullet_from_field(self, bullet): """Removes a bullet from the game field.""" self.bullets.remove(bullet) bullet.remove_shape() if(self.bullets.count == 0): self.bullet_timer.stop() def remove_rock_from_field(self, rock): """Removes a rock from the game field.""" self.rocks.remove(rock) rock.remove_shape() def drop_down_rocks(self): """Moves the rocks down and check if the move is out of the game field. If that is true the rocks are removed from the field. """ temp_rock = None for rock in self.rocks: if(rock.y >= self.game.dimensions[1] - rock.height - 15): temp_rock = rock else: rock.drop_down() self.check_collision_between_rock_and_player(rock) if temp_rock is not None: self.remove_rock_from_field(temp_rock) def check_collision_between_rock_and_player(self, rock): """Checks for a collision between the rock and the player. If that is true the game is over. """ if(not self.player_ui.is_player_invincible and self.game.collision_detected(self.player_ui, rock)): self.stop_timers() self.game.lose() self.main_window.communicate.message_statusbar.\ emit("Game Over") def keyPressEvent(self, event): """Gets the events emitted when the player presses a key on the keyboard and calls the appropriate method. """ super(FieldUI, self).keyPressEvent(event) key = event.key() if key == Qt.Key_Escape: self.com.exit.emit() elif key == Qt.Key_R: self.com.restart.emit() elif self.game.is_lost: return elif key == Qt.Key_P: if self.game.is_running: self.pause_game() else: self.resume_game() return if self.game.is_paused: return elif key == Qt.Key_Left: self.com.move_left.emit() elif key == Qt.Key_Right: self.com.move_right.emit() def pause_game(self): """Pauses the game and shows a message to the player.""" if self.game.is_running: self.game.pause() self.stop_timers() self.main_window.communicate.message_statusbar.emit("Paused") def resume_game(self): """Resumes the game and shows a message to the player.""" if self.game.is_paused: self.game.resume() self.start_timers() self.main_window.communicate.message_statusbar.emit("Running") self.update()
class MouseFollower(QWidget): def __init__(self, *args): super(MouseFollower, self).__init__(*args) self.following = False self.grabbing = False self.cursorTimer = QBasicTimer() def isGrabbing(self): return self.grabbing def isFollowing(self): return self.following mouseMoved = Signal(QPoint) clickWhileGrabbed = Signal() @Slot() def toggleGrab(self): refollow = self.following if refollow: self.endFollow() self.grabbing = not self.grabbing if refollow: self.startFollow() def toggleFollow(self): if self.following: self.endFollow() else: self.startFollow() @Slot() def startFollow(self): if not self.grabbing: self.cursorTimer.start(100, self) else: self.setMouseTracking(True) self.grabMouse() self.following = True @Slot() def endFollow(self): if not self.grabbing: self.cursorTimer.stop() else: self.releaseMouse() self.following = False def timerEvent(self, ev): if ev.timerId() == self.cursorTimer.timerId(): self.mouseMoved.emit(QCursor.pos()) else: super(MouseFollower, self).timerEvent(ev) def mouseMoveEvent(self, ev): self.mouseMoved.emit(QCursor.pos()) return super(MouseFollower, self).mouseMoveEvent(ev) def mousePressEvent(self, ev): if self.grabbing: self.clickWhileGrabbed.emit() return super(MouseFollower, self).mousePressEvent(ev)
class CheckCreds(QDialog): """ This class manages the authentication process for oVirt. If credentials are saved, they're tried automatically. If they are wrong, the username/password dialog is shown. """ def __init__(self, parent, username, password, remember): QDialog.__init__(self, parent) self.uname = username self.pw = password self.remember = False if conf.CONFIG['allow_remember'] == '0' else remember self.setModal(True) self.initUI() def initUI(self): """ Description: A progress bar, a status message will be shown and a timer() method will be invoked as part of the authentication process. Arguments: None Returns: Nothing """ self.pbar = QProgressBar(self) self.pbar.setGeometry(30, 40, 200, 25) self.status = QLabel(self) self.status.setGeometry(30, 75, 200, 20) self.timer = QBasicTimer() self.step = 0 self.setGeometry(300, 300, 255, 100) self.center() self.setWindowTitle(_('loading')) self.show() self.timer.start(100, self) def timerEvent(self, e): """ Description: Called periodically as part of the QBasicTimer() object. Authentication will be handled within this method. Arguments: The event. Won't be used, though. Returns: Nothing, just exits when progress bar reaches 100% """ global conf err = QMessageBox() self.status.setText(_('authenticating')) if not conf.USERNAME: try: kvm = API(url=conf.CONFIG['ovirturl'], username=self.uname + '@' + conf.CONFIG['ovirtdomain'], password=self.pw, insecure=True, timeout=int(conf.CONFIG['conntimeout']), filter=True) conf.OVIRTCONN = kvm conf.USERNAME = self.uname conf.PASSWORD = self.pw self.status.setText(_('authenticated_and_storing')) self.step = 49 except ConnectionError as e: err.critical(self, _('apptitle') + ': ' + _('error'), _('ovirt_connection_error') + ': ' + sub('<[^<]+?>', '', str(e))) self.status.setText(_('error_while_authenticating')) self.step = 100 except RequestError as e: err.critical(self, _('apptitle') + ': ' + _('error'), _('ovirt_request_error') + ': ' + sub('<[^<]+?>', '', str(e))) self.status.setText(_('error_while_authenticating')) self.step = 100 if self.step >= 100: # Authenticacion process has concluded self.timer.stop() self.close() return elif self.step == 50: # Credentials were ok, we check whether we should store them for further uses if self.remember: self.status.setText(_('storing_credentials')) with os.fdopen(os.open(conf.USERCREDSFILE, os.O_WRONLY | os.O_CREAT, 0600), 'w') as handle: handle.write('[credentials]\nusername=%s\npassword=%s' % (self.uname, encode(self.pw, 'rot_13'))) handle.close() self.step = 99 else: self.status.setText(_('successfully_authenticated')) self.step = 99 self.step = self.step + 1 self.pbar.setValue(self.step)
class DedeNimeur(QMainWindow): def __init__(self): super(DedeNimeur, self).__init__() self.statusBar() self.size, self.height, self.width, self.mines = 30, 10, 10, 10 self.lcd = QLCDNumber() self.lcd.setFixedSize(300, 60) self.board = Board(self.height, self.width, self.mines, self.size) self.timer = QBasicTimer() self.real_timer = QElapsedTimer() vbox = QVBoxLayout() vbox.addWidget(self.lcd) vbox.addWidget(self.board) central = QWidget() central.setLayout(vbox) self.setCentralWidget(central) start = QAction('Start', self) start.setStatusTip('Start') start.setShortcut('Ctrl+N') start.triggered.connect(self.init) exit = QAction('Exit', self) exit.setStatusTip('Exit') exit.setShortcut('Ctrl+Q') exit.triggered.connect(qApp.quit) height = QAction('Height', self) height.setStatusTip('Set board width') height.triggered.connect(self.set_height) width = QAction('Width', self) width.setStatusTip('Set board height') width.triggered.connect(self.set_width) mines = QAction('Mines', self) mines.setStatusTip('Set board mines') mines.triggered.connect(self.set_mines) size = QAction('Size', self) size.setStatusTip('Set button size') size.triggered.connect(self.set_size) toolbar = self.addToolBar('Toolbar') toolbar.addAction(start) toolbar.addAction(width) toolbar.addAction(height) toolbar.addAction(mines) toolbar.addAction(size) toolbar.addAction(exit) self.setWindowTitle(u'DédéNimeur') self.show() def init(self): if self.mines < self.height * self.width: self.board.height = self.height self.board.width = self.width self.board.mines = self.mines self.board.size = self.size self.board.init() else: QMessageBox.question(self, 'NOPE', u"Va falloir spécifier un truc cohérent…", QMessageBox.Ok) def set_height(self): text, ok = QInputDialog.getText(self, 'Settings', 'height') if ok: self.height = int(text) self.init() def set_width(self): text, ok = QInputDialog.getText(self, 'Settings', 'width') if ok: self.width = int(text) self.init() def set_mines(self): text, ok = QInputDialog.getText(self, 'Settings', 'mines') if ok: self.mines = int(text) self.init() def set_size(self): text, ok = QInputDialog.getText(self, 'Settings', 'size') if ok: self.size = int(text) self.init() def start_timers(self): self.timer.start(100, self) self.real_timer.start() self.lcd.display(int(self.real_timer.elapsed() / 1000)) def stop_timers(self): self.timer.stop() return self.real_timer.elapsed() def timerEvent(self, e): self.lcd.display(int(self.real_timer.elapsed() / 1000))
class MyMainForm(QMainWindow, Ui_Form): def __init__(self, parent=None): super(MyMainForm, self).__init__(parent) self.setupUi(self) self.lineEdit_select_folder.setReadOnly(True) # 选择文件夹文本框不可编辑只能选择 self.step = 1 # 进度条步长 self.toolButton_select_un7z_folder.clicked.connect(self.select_folder) self.PushButton_uncompress.clicked.connect(self.extract_show) # self.PushButton_uncompress.clicked.connect(self.one_cilck_extract) # self.PushButton_delete.clicked.connect(self.ProgressDialog) self.PushButton_delete.clicked.connect(self.delete_compressed_package) self.pushButton_cancel.clicked.connect(self.close) # 选择待解压文件夹 def select_folder(self): directory = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "") # 通过按钮获取文件夹路径 print("starting at:",directory) ''' self.lineEdit_select_folder.clear() # 清除上一次选择的路径 self.lineEdit_select_folder.insert(directory) # 文件夹路径显示在文本框上 ''' self.lineEdit_select_folder.setText(directory) # 文件夹路径显示在文本框上 # 删除压缩包 def delete_compressed_package(self): folderPath = self.lineEdit_select_folder.text() if not folderPath or folderPath == "": msg = "文件路径无效" QMessageBox.warning(self, "解压失败", msg, QMessageBox.Close) return result = remove_compressed_file(folderPath) if result: QMessageBox.information(self, "删除结果", "成功", QMessageBox.Close) else: QMessageBox.warning(self, "删除结果", "失败", QMessageBox.Close) # 解压和显示进度条 def extract_show(self): # 获取解压必需的参数 folderPath = self.lineEdit_select_folder.text() if not folderPath or folderPath == "": msg = "文件路径无效" QMessageBox.warning(self, "解压失败", msg, QMessageBox.Close) return password = self.lineEdit_input_password.text() fileType = self.comboBox.currentText() self.timer = QBasicTimer() # 初始化一个时钟 self.progressDialog = QProgressDialog(self) # 初始化进度条 self.progressDialog.setWindowTitle("请稍等") self.progressDialog.setLabelText("正在解压...") self.progressDialog.setCancelButtonText("取消") # 其实取消按钮应该能够停止解压操作 # self.progressDialog.setWindowModality(Qt.WindowModal) self.progressDialog.setMinimumDuration(1000) self.progressDialog.setRange(0,100) self.progressDialog.setValue(0) begin = time.time() filesize = get_compressed_filesize(folderPath, fileType) self.PushButton_uncompress.setEnabled(False) # 设置button暂时不可用 x = filesize//(1024*1024*100) y = x**2/100+x*25 print("x = %d, y = %d" %(x,y)) self.timer.start(y, self) # 通过文件大小来估算进度条时间 self.thread_extract = Thread_Extract(folderPath, fileType, password) # self.thread_extract._signal.connect(self.set_btn) # 此线程执行完毕后需要恢复button self.thread_extract._signal.connect(self.extract_callback) # 执行回调函数 self.thread_extract.start() show_size, file_byte = filesize, 0 while show_size > 1024: show_size = show_size/1024 file_byte += 1 if file_byte == 0: print("filesize = {} Byte".format(show_size)) elif file_byte == 1: print("filesize = %.3f KB" %(show_size)) elif file_byte == 2: print("filesize = %.3f MB" %(show_size)) elif file_byte == 3: print("filesize = %.3f GB" %(show_size)) else: print("filesize = %.3f TB" %(show_size)) end = time.time() time_cost = end-begin if time_cost>1: print("get filesize cost {}s".format(time_cost)) elif time_cost*1000>1: print("get filesize cost {}us".format(time_cost*1000)) elif time_cost*1000000>1: print("get filesize cost {}ms".format(time_cost*1000000)) # 主线程弹窗 # if filesize > 0: # self.ProgressDialog((filesize // 100)) # def set_btn(self): # self.PushButton_uncompress.setEnabled(True) def extract_callback(self, result): # 解压结果回调函数 self.step = -1 self.progressDialog.setValue(100) print("result = ", result) if result['code'] == 0: # QMessageBox.information(self, "解压结果", "成功", QMessageBox.Yes | QMessageBox.No) msg = str(result['success_times']) + "个文件解压成功," + str(result['failed_times']) + "个文件解压失败," + str( result['unknown_times']) + "个文件无需解压或类型不支持" print(msg) QMessageBox.information(self, "解压完毕", msg, QMessageBox.Close) elif result['code'] == 2: msg = "文件类型错误" QMessageBox.critical(self, "解压失败", msg, QMessageBox.Close) self.PushButton_uncompress.setEnabled(True) # self.progressDialog.setValue(0) # 一键解压 def one_cilck_extract(self): folderPath = self.lineEdit_select_folder.text() if not folderPath or folderPath == "": msg = "文件路径无效" QMessageBox.warning(self, "解压失败", msg, QMessageBox.Close) return password = self.lineEdit_input_password.text() fileType = self.comboBox.currentText() result = extract_file(folderPath, fileType, password) print("result = ",result) if result['code'] == 0: # QMessageBox.information(self, "解压结果", "成功", QMessageBox.Yes | QMessageBox.No) msg = str(result['success_times'])+"个文件解压成功,"+str(result['failed_times'])+"个文件解压失败,"+str(result['unknown_times'])+"个文件无需解压或类型不支持" print(msg) QMessageBox.information(self, "解压完毕", msg, QMessageBox.Close) elif result['code'] == 2: msg = "文件类型错误" QMessageBox.critical(self, "解压失败", msg, QMessageBox.Close) # 进度条弹窗 def ProgressDialog(self, num = 100000): print("num = ",num) progress = QProgressDialog(self) progress.setWindowTitle("请稍等") progress.setLabelText("正在操作...") progress.setCancelButtonText("取消") progress.setMinimumDuration(1000) progress.setWindowModality(Qt.WindowModal) progress.setRange(0, num) for i in range(num + 1): progress.setValue(i) if progress.wasCanceled(): # QMessageBox.warning(self, "提示", "操作失败") break else: pass # progress.setValue(num) # QMessageBox.information(self, "提示", "操作成功") def timerEvent(self, *args, **kwargs): # QBasicTimer的事件回调函数 if self.step != -1: # 把step每次重置的值赋给进度条 self.progressDialog.setValue(self.step) else: # 解压完毕后停止时钟 self.timer.stop() return if self.step >= 100: # 停止进度条 self.timer.stop() self.step = 1 return # 把进度条卡在99,等处理好了再到100 elif self.step < 99 and self.step > 0: self.step += 1
class Board(QFrame): msg2Statusbar = pyqtSignal(str) BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def get_connect(self, client, username): self.client = client print(type(self.client)) self.username = username def initBoard(self): self.timer = QBasicTimer() self.isWaitingAfterLine = False self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() def shapeAt(self, x, y): return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * Board.BoardWidth) + x] = shape def squareWidth(self): return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): return self.contentsRect().height() // Board.BoardHeight def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.newPiece() self.timer.start(Board.Speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.update() def paintEvent(self, event): painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() for i in range(Board.BoardHeight): for j in range(Board.BoardWidth): shape = self.shapeAt(j, Board.BoardHeight - i - 1) if shape != Tetrominoe.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != Tetrominoe.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_Enter: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif key == Qt.Key_Down: self.oneLineDown() else: super(Board, self).keyPressEvent(event) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: super(Board, self).timerEvent(event) def clearBoard(self): for i in range(Board.BoardHeight * Board.BoardWidth): self.board.append(Tetrominoe.NoShape) def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines msg = { "behavior": "grade", "grade": self.numLinesRemoved, "username": self.username } self.client.send((json.dumps(msg)).encode("utf-8")) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() def newPiece(self): self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over") def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoe.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Board(QFrame): BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): self.timer = QBasicTimer() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() def shapeAt(self, x, y): return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * Board.BoardWidth) + x] = shape def squareWidth(self): return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): return self.contentsRect().height() // Board.BoardHeight def start(self): pass def pause(self): pass def paintEvent(self, QPaintEvent): pass def keyPressEvent(self, *args, **kwargs): pass def timerEvent(self, *args, **kwargs): pass def clearBoard(self): pass def dropDown(self): newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() def newPiece(self): self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over")
class Tetris(QFrame): BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): QFrame.__init__(self, parent) self.timer = QBasicTimer() self.isWaitingAfterLine = False self.curPiece = Shape() self.nextPiece = Shape() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() self.nextPiece.setRandomShape() self._parent = parent def message(self, string): self._parent.setTitle(string) def shapeAt(self, x, y): return self.board[(y * Tetris.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * Tetris.BoardWidth) + x] = shape def squareWidth(self): return self.contentsRect().width() / Tetris.BoardWidth def squareHeight(self): return self.contentsRect().height() / Tetris.BoardHeight def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.message("Score : %s" % self.numLinesRemoved) self.newPiece() self.timer.start(Tetris.Speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.message("Paused") else: self.timer.start(Tetris.Speed, self) self.message("Score : %s" % self.numLinesRemoved) self.update() def paintEvent(self, event): painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Tetris.BoardHeight * self.squareHeight() for i in range(Tetris.BoardHeight): for j in range(Tetris.BoardWidth): shape = self.shapeAt(j, Tetris.BoardHeight - i - 1) if shape != Tetrominoes.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != Tetrominoes.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (Tetris.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): if not self.isStarted or self.curPiece.shape() == Tetrominoes.NoShape: QWidget.keyPressEvent(self, event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down or key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY) elif key == Qt.Key_D: self.oneLineDown() else: QWidget.keyPressEvent(self, event) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: QFrame.timerEvent(self, event) def clearBoard(self): for i in range(Tetris.BoardHeight * Tetris.BoardWidth): self.board.append(Tetrominoes.NoShape) def dropDown(self): newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 rowsToRemove = [] for i in range(Tetris.BoardHeight): n = 0 for j in range(Tetris.BoardWidth): if not self.shapeAt(j, i) == Tetrominoes.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Tetris.BoardHeight): for l in range(Tetris.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.message("Score : %s" % self.numLinesRemoved) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoes.NoShape) self.update() def newPiece(self): self.curPiece = self.nextPiece self.nextPiece.setRandomShape() self.curX = Tetris.BoardWidth / 2 + 1 self.curY = Tetris.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoes.NoShape) self.timer.stop() self.isStarted = False self.message("Game over") def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Tetris.BoardWidth or y < 0 or y >= Tetris.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoes.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.light()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.dark()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # 选择框 QCheckBox cb = QCheckBox("show title", self) cb.move(20, 20) #cb.toggle() cb.stateChanged.connect(self.changeTitle) # 切换按钮 self.col = QColor(0, 0, 0) redb = QPushButton('RED', self) redb.setCheckable(True) redb.move(20, 40) redb.clicked[bool].connect(self.setColor) # 将点击信号转换为布尔值,并与函数关联起来 greenb = QPushButton('GREEN', self) greenb.setCheckable(True) greenb.move(20, 60) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('BLUE', self) blueb.setCheckable(True) blueb.move(20, 80) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QFrame{background-color:%s}" % self.col.name()) # 滑块 QSlider sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(19) sld.setGeometry(20, 160, 100, 30) sld.valueChanged[int].connect(self.changeSliderValue) self.label = QLabel(self) qpix = QPixmap(sys.path[0] + '/music2.png').scaled(QSize(30, 30)) self.label.setPixmap(qpix) self.label.setGeometry(150, 160, 30, 30) self.labelText = QLabel(self) self.labelText.setGeometry(190, 160, 13, 10) # 进度条 self.pbar = QProgressBar(self) self.pbar.setGeometry(120, 200, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(20, 200) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # 日历 hbox = QHBoxLayout() hbox.addStretch(1) cal = QCalendarWidget(self) cal.setGridVisible(True) cal.clicked[QDate].connect(self.showDate) hbox.addWidget(cal) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) hbox.addWidget(self.lbl) self.setLayout(hbox) # 窗口 self.setGeometry(300, 300, 500, 400) self.setWindowTitle('Control') self.show() # 通过checkbox改变标题 def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QChekcBox') else: self.setWindowTitle('Control') # 通过button改变颜色 def setColor(self, preesed): source = self.sender() # 找到事件信号发送者 if preesed: val = 255 else: val = 0 if source.text() == "RED": self.col.setRed(val) elif source.text() == 'GREEN': self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame{background-color:%s}" % self.col.name()) # 通过QSlider滑动改变 def changeSliderValue(self, value): # 置label为value self.labelText.setText(str(value)) if value == 0: self.label.setPixmap( QPixmap(sys.path[0] + '/music2.png').scaled(QSize(30, 30))) elif value > 0 and value <= 30: self.label.setPixmap( QPixmap(sys.path[0] + '/music.png').scaled(QSize(30, 30))) elif value > 30 and value < 80: self.label.setPixmap( QPixmap(sys.path[0] + '/music.png').scaled(QSize(30, 30))) else: self.label.setPixmap( QPixmap(sys.path[0] + '/music.png').scaled(QSize(30, 30))) # QBasicTimer的start()方法触发的事件,重载 def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText("Finished") return self.step = self.step + 1 self.pbar.setValue(self.step) # 按钮信号,控制开始/停止 def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText("Start") else: self.timer.start(100, self) self.btn.setText("Stop") # 日期 def showDate(self, date): self.lbl.setText(date.toString())
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # checkbox cb = QCheckBox('Show title', self) cb.move(20, 160) cb.toggle() cb.stateChanged.connect(self.changeTitle) # toggle button self.col = QColor(0, 0, 0) redb = QPushButton('Red', self) redb.setCheckable(True) redb.move(10, 10) redb.clicked[bool].connect(self.setColor) redb = QPushButton('Green', self) redb.setCheckable(True) redb.move(10, 60) redb.clicked[bool].connect(self.setColor) blueb = QPushButton('Blue', self) blueb.setCheckable(True) blueb.move(10, 110) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()) # slider sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(30, 210, 100, 30) sld.valueChanged[int].connect(self.changeValue) # pixmap self.label = QLabel(self) self.label.setPixmap(QPixmap('web.png')) self.label.setGeometry(160, 210, 80, 30) # process bar self.pbar = QProgressBar(self) self.pbar.setGeometry(30, 260, 200, 25) self.btn = QPushButton('Start', self) self.btn.move(40, 310) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # calendar cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(300, 10) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(300, 260) # line edit self.lbl2 = QLabel(self) qle = QLineEdit(self) qle.move(300, 310) self.lbl2.move(480, 310) qle.textChanged[str].connect(self.onChanged) self.setGeometry(300, 300, 640, 480) self.setWindowTitle('QCheckBox') self.show() def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('') def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == "Red": self.col.setRed(val) elif source.text() == "Green": self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name()) def changeValue(self, value): if value == 0: self.label.setPixmap(QPixmap('web.png')) elif value > 0 and value <= 30: self.label.setPixmap(QPixmap('web.png')) elif value > 30 and value < 80: self.label.setPixmap(QPixmap('web.png')) else: self.label.setPixmap(QPixmap('web.png')) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100, self) self.btn.setText('Stop') def showDate(self, date): self.lbl.setText(date.toString()) def onChanged(self, text): self.lbl2.setText(text) self.lbl2.adjustSize()
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) loadUi("init/window.ui", self) self.setFixedSize(self.width(), self.height()); self.setWindowIcon(QIcon('init/cloud.ico')) self.setWindowTitle('CAN数据解析__HIRAIN TECH.') self.setWindowFlags(Qt.WindowStaysOnTopHint) #强制置顶 self.new_dbc_file_name = './dbc_file/new/'+'new_dbc_hirain.csv' #更新dbc文件路径 self.dbc_exist_flag = self.dbc_flag() #重置dbc标志文件,如果文件存在则置1 self.pushButton_3.setEnabled(False) self.statusbar.showMessage('初始化成功', 3000) self.pushButton_2.clicked.connect(self.getCANdata) self.pushButton.clicked.connect(self.freshDBCfile) self.pushButton_3.clicked.connect(self.can_data_parse) self.pushButton_4.clicked.connect(self.initDBCfile) self.pbar = QProgressBar(self) self.pbar.setValue(0) self.pbar.setGeometry(0,186,450,3) self.pbar.setFixedHeight(3) # 设置进度条高度 self.pbar.setTextVisible(False) # 不显示进度条文字 self.timer = QBasicTimer() # 初始化一个时钟 self.step = 0 # 选择要解析的CAN数据 def getCANdata(self): fileName1, filetype = QFileDialog.getOpenFileName(self, "选取文件", "./","Text Files (*.csv);;All Files (*)") # 设置文件扩展名过滤,注意用双分号间隔 self.pbar.setValue(0) if fileName1: self.lineEdit.setText(fileName1) self.CAN_data_file = fileName1 file_path_list = fileName1.split('/')[0:-1] #获取文件路径 self.filename = fileName1.split('/')[-1] self.file_path = '/'.join(file_path_list) self.pushButton_3.setEnabled(True) self.statusbar.showMessage(f'加载{self.filename}文件成功!') return fileName1 else: self.statusbar.showMessage('选择DBC文件!',1000) # 按钮更新DBC文件,可以选择新的DBC文件 def freshDBCfile(self): if self.dbc_exist_flag == 1: self.initDBCfile() fileName1, filetype = QFileDialog.getOpenFileName(self, "选取文件", "./","Text Files (*.csv);;All Files (*)") # 设置文件扩展名过滤,注意用双分号间隔 if fileName1: oldname = fileName1 fresh_dbc_file_name = fileName1.split('/')[-1] shutil.copyfile(oldname, self.new_dbc_file_name) self.dbc_exist_flag = 1; #如果文件夹里存在新dbc则,将dbc的标志置为1 self.pushButton_4.setEnabled(True) self.statusbar.showMessage(f'更新{fresh_dbc_file_name}文件成功!') else: pass # 按钮可以重置DBC文件,删除用户上传的DBC文件,回到程序内置的DBC文件 def initDBCfile(self): """ 重置dbc文件,删除new文件夹的dbc文件。 :return: """ if self.dbc_exist_flag == 1: os.remove(self.new_dbc_file_name) self.pushButton_4.setEnabled(False) self.statusbar.showMessage('重置文件成功!') else: self.pushButton_4.setEnabled(True) pass # 用于监测文件夹中是否有新的DBC文件 def dbc_flag(self): """ 监测是否有新的dbc文件 :return: """ if (os.path.exists(self.new_dbc_file_name)): return 1 else: self.pushButton_4.setEnabled(False) return 0 # 选择的源数据解析 def can_data_parse(self): """ 采用最新的解析函数 :return: """ if self.dbc_exist_flag == 1: self.CAN_DBC_file_name = self.new_dbc_file_name #如果dbc的文件已经更新则使用最新的dbc文件 else: self.CAN_DBC_file_name = r".\dbc_file\init\DBC_std_v1.0.csv" self.CAN_file_name = self.CAN_data_file self.save_path = self.file_path + '/result-' + self.filename self.lineEdit.setText('') self.pushButton_3.setEnabled(False) sz = os.path.getsize(self.CAN_file_name) # 获取文件大小 if sz < 1_000_000: fresh_time = 50 elif sz < 2_000_000: fresh_time = 120 elif sz < 3_000_000: fresh_time = 170 else: fresh_time = int(sz/40000) # 估计运算时间,40M大约16分钟 self.timer.start(fresh_time, self) # 启动QBasicTimer,每100ms调用一次事件回调函数 self.step = 0 self.my_cal = MyCal(self.CAN_file_name, self.CAN_DBC_file_name, self.save_path) # 实例化线程 self.my_cal.cal_signal.connect(self.cal_callback) # 将线程累中定义的信号连接到本类中的信号接收函数中 self.my_cal.start() # 开启进程 # 计算完毕的回调函数,用于显示计算的结果 def cal_callback(self, back_msg): self.step = 99 file_window = (self.file_path).replace('/', '\\') msg = back_msg[0] t_t = back_msg[1] if msg == 1: os.system("start explorer " + file_window) self.pushButton_3.setEnabled(True) self.statusbar.showMessage(f'{self.filename}文件解析完成!用时{str(t_t)}秒') else: self.statusbar.showMessage(f'{self.filename}文件解析失败,请重新提交!') # 进度条显示的函数 def timerEvent(self, *args, **kwargs): # QBasicTimer的事件回调函数 # 把进度条每次充值的值赋给进度条 self.pbar.setValue(self.step) if self.step >= 100: # 停止进度条 self.timer.stop() self.step = 0 return # 把进度条卡在99,等处理好了再到100 if self.step < 99: self.step += 1 self.statusbar.showMessage(f'正在解析文件,完成进度{self.step}%')
class YaP(QWidget): rate_url = 'poligon.info' query = '' query_list = [] res_label = '' file_path_label = '' rank = 0 file_taken = False res_list = [] file_queries = [] fname = '' r_count = 0 db_path = 'keywords.db' xls_path = 'rating.xls' yandex_limits = [ [0, 230, 0], [1, 276, 0], [2, 276, 0], [3, 276, 0], [4, 276, 0], [5, 230, 0], [6, 161, 0], [7, 92, 0], [8, 46, 0], [9, 46, 0], [10, 46, 0], [11, 46, 0], [12, 46, 0], [13, 46, 0], [14, 46, 0], [15, 46, 2], [16, 46, 0], [17, 46, 0], [18, 46, 0], [19, 46, 0], [20, 92, 0], [21, 161, 0], [22, 230, 0], [23, 240, 0] ] # req_date = str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) req_date = str(datetime.now().strftime('%Y-%m-%d')) query_url = 'https://yandex.ru/search/xml?user=webmaster-poligon\ &key=03.279908682:25776a70171503eb70359c5bd5b820dc&l10n=ru\ &groupby=groups-on-page%3D100&lr=2&query=' def __init__(self): super().__init__() self.initUI() self.search_btn.clicked.connect(self.set_query) self.search_btn.clicked.connect(self.start_search) self.qfile_btn.clicked.connect(self.showOpenDialog) self.sfile_btn.clicked.connect(self.db_xls) def initUI(self): grid = QGridLayout() self.setLayout(grid) lbl = QLabel('Выбран запрос: ') grid.addWidget(lbl, 0, 0) lbl1 = QLabel('Поиск по запросу: ') grid.addWidget(lbl1, 3, 0) self.label = QLabel(self) grid.addWidget(self.label, 0, 1) self.field = QLineEdit(self) grid.addWidget(self.field, 3, 1) self.field.textChanged[str].connect(self.push_query) self.search_btn = QPushButton('Поиск') grid.addWidget(self.search_btn, 3, 2) self.qfile_btn = QPushButton('Файл запросов') grid.addWidget(self.qfile_btn, 5, 0) self.sfile_btn = QPushButton('Сохранить') grid.addWidget(self.sfile_btn, 5, 2) label_fake = QLabel() grid.addWidget(label_fake, 4, 0) label_fake1 = QLabel() grid.addWidget(label_fake1, 2, 0) self.label_done = QLabel() grid.addWidget(self.label_done, 6, 1) self.label_r = QLabel(self.res_label) grid.addWidget(self.label_r, 4, 1) self.label_fp = QLabel(self.file_path_label) grid.addWidget(self.label_fp, 5, 1) self.setGeometry(700, 350, 600, 200) self.setWindowTitle('\"YaP\" - is a Yandex ratings for Poligon.info') self.pbar = QProgressBar(self) grid.addWidget(self.pbar, 7, 1) self.timer = QBasicTimer() self.step = 0 self.show() def timerEvent(self, e): if self.step >= 100: self.timer.stop() return self.step = self.step + 1 self.pbar.setValue(self.step) def sql_con(self, res_list): conn = sqlite3.connect(self.db_path) db = conn.cursor() db.execute("select name from sqlite_master \ where type='table' and name='requests'") if db.fetchone(): for res in self.res_list: if len(self.file_queries) == 0: k = (self.query.encode('utf-8').decode('cp1251'), self.req_date,) db.execute("select * from requests \ where keyword=? and date=?", k) if db.fetchone(): db.execute("delete from requests \ where keyword=? and date=?", k) else: continue else: for q in self.file_queries: k = (q, self.req_date,) db.execute("select * from requests \ where keyword=? and date=?", k) if db.fetchone(): db.execute("delete from requests \ where keyword=? and date=?", k) else: continue db.executemany( "insert into requests values (?, ?, ?)", self.res_list) else: db.execute("create table requests (keyword, position, date)") db.executemany( "insert into requests values (?, ?, ?)", self.res_list) conn.commit() db.close() conn.close() def db_xls(self): conn = sqlite3.connect(self.db_path) db = conn.cursor() db.execute("select name from sqlite_master \ where type='table' and name='requests'") wb = Workbook() ws = wb.add_sheet('keywords') plain = easyxf('') if db.fetchone(): for r, row in enumerate(db.execute("select * from requests")): for c, col in enumerate(row): if (type(col) is int) != True: ws.write(r, c, col.encode('cp1251') .decode('utf-8'), plain) else: ws.write(r, c, col, plain) print(col) wb.save(self.xls_path) db.close() conn.close() def showOpenDialog(self): self.fname, _ = QFileDialog.getOpenFileName(self, 'Open file', 'C:\\Users\\gnato\\\ Desktop\\Igor\\progs\\\ python_progs\\YaP\\') if len(self.fname) > 0: book = xlrd.open_workbook(self.fname, 'rt', formatting_info=True) sh = book.sheet_by_index(0) else: pass for i in range(sh.nrows): self.query_list.append(sh.cell_value(i, 0)) print('query_list is: ') for l in self.query_list: print(l.encode('utf-8').decode('cp1251')) self.file_taken = True fname_chars = [] for char in self.fname: if (char == '/'): fname_chars.append('\\') else: fname_chars.append(char) win_path = ''.join(fname_chars) self.label_fp.setText(win_path) self.label_fp.adjustSize() self.start_search(self.event) def keyPressEvent(self, event): if type(event) == QKeyEvent: if event.key() == Qt.Key_Escape: self.close() elif event.key() == Qt.Key_Return: self.set_query(self) self.start_search(self) def set_query(self, event): self.query = self.field.text() self.rank = 0 self.file_queries = [] def push_query(self, query): self.label.setText(query) self.label.adjustSize() def start_search(self, event): if self.timer.isActive(): self.timer.stop() else: self.timer.start(100, self) self.label_done.setText( 'Запросы обработаны, результаты занесены в базу данных.\n\ Для сохранения в файл нажмите кнопку \"Сохранить\".') if self.file_taken: for j, item in enumerate(self.query_list): self.query = self.query_list[j] r = requests.get(self.query_url + self.query) self.r_count += 1 # функция limit() может быть вызвана только один раз # # во избежание неправильных показателей счётчика. # limit_data = limit(self.r_count, self.db_path, self.req_date) # # ########################################################### # if (limit_data[0]): result = r.text result_list = result.split('<url>') for i, item in enumerate(result_list): if self.rate_url in item: self.rank += i break self.res_list.append(( self.query.encode('utf-8').decode('cp1251'), self.rank, self.req_date,)) self.file_queries.append( self.query.encode('utf-8').decode('cp1251')) limit_resume = str(limit_data[1]) + ' - Winter is close!' else: limit_resume = str(limit_data[1]) +\ 'Hour limit is here... Wait about ' +\ str(60 - int(datetime.now().strftime('%M'))) +\ ' minuntes, please!' self.sql_con(self.res_list) print(limit_resume) print(int(datetime.now().strftime('%Y-%m-%d'))) print(int(datetime.now().strftime('%Y-%m-%d'))-1) else: r = requests.get(self.query_url + self.query) self.r_count += 1 result = r.text result_list = result.split('<url>') for i, item in enumerate(result_list): if self.rate_url in item: self.rank += i break if self.rank != 0: self.res_label = ('По запросу \"' + self.query + '\" сайт poligon.info \ находится на ' + str(self.rank) + '-й позиции.\nДата запроса : ' + self.req_date + '.') self.label_r.setText(self.res_label) self.label_r.adjustSize() self.res_list.append(( self.query.encode('utf-8').decode('cp1251'), self.rank, self.req_date,)) self.sql_con(self.res_list) else: self.res_label = ('По запросу \"' + self.query + '\" сайт poligon.info \ находится ниже 100-й позиции.\nДата запроса : ' + self.req_date + '.') self.label_r.setText(self.res_label) self.label_r.adjustSize() self.res_list.append(( self.query.encode('utf-8').decode('cp1251'), self.rank, self.req_date,)) self.sql_con(self.res_list) print('end') print(self.res_list)
class main_window_class(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): #self.statusBar().showMessage('Load completed') grid = QGridLayout() self.setLayout(grid) url_label = QLabel('CBS URL:') usr_label = QLabel('Username:'******'Password:'******'users.xml:') pgb_label = QLabel('Current Operation Progress:') inf_label = QLabel('''Guide: 1) Enter CBS URL. If your CBS address is https://ahsaycbs.com:1000, enter ahsaycbs.com:1000. 2) Enter username and password for a system user or API user. 3) Click List Destination(s) and wait for a popup Window. Choose which Predefined Destination you want to push the old quota to and click “Confirm”. Though this tool allows you to run it for multiple destinations at once, we would recommend you doing it for one destination each time to avoid confusion. 4) Click “Select…” and locate the users.xml’s backup you saved before upgrading to v7.15.6.x. You can find it in CBS\conf\Backup\dr-*date*.zip\conf\\users.xml if you haven’t kept it. 5) Click Analyse. This updater will generate a getUser.csv file to the directory where it resides in. It contains everything which will be pushed on to the server in the later stage. You can check or make amendments to it. The “Quota” will be pushed to the relative “User” for the “Destination” shown. 6) Click Update to start pushing quota updates to CBS. Final Report and Error Report will be outputted to the current directory. ''') self.url_edit = QLineEdit() self.usr_edit = QLineEdit() self.pwd_edit = QLineEdit() self.pwd_edit.setEchoMode(QLineEdit.Password) self.xml_edit = QLineEdit() #QLineEdit.setPlaceholderText(str):该属性包含行编辑的占位符文本。只要行编辑为空,设置此属性将使行编辑显示一个灰色的占位符文本。 #做自己version用,不用加一堆傻逼注释 lis_but = QPushButton('List Destination') sel_but = QPushButton('Select') ana_but = QPushButton('Analyse') upd_but = QPushButton('Update') grid.addWidget(url_label, 1, 0) grid.addWidget(self.url_edit, 1, 1, 1, 4) grid.addWidget(usr_label, 2, 0) grid.addWidget(self.usr_edit, 2, 1) grid.addWidget(pwd_label, 2, 2) grid.addWidget(self.pwd_edit, 2, 3) grid.addWidget(lis_but, 2, 4) grid.addWidget(xml_label, 3, 0) grid.addWidget(self.xml_edit, 3, 1, 1, 3) grid.addWidget(sel_but, 3, 4) grid.addWidget(ana_but, 4, 1) grid.addWidget(upd_but, 4, 3) upd_but.resize(upd_but.sizeHint()) ana_but.resize(upd_but.sizeHint()) # pb_label = QLabel('') # pb_bar = QProgressBar() self.pbar = QProgressBar() self.btn = QPushButton('Start') self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 grid.addWidget(pgb_label, 5, 0, 1, 2) grid.addWidget(self.pbar, 6, 0, 1, 5) grid.addWidget(inf_label, 7, 0, 10, 5) self.url_edit.textChanged.connect(self.setUrl) self.usr_edit.textChanged.connect(self.setUsr) self.pwd_edit.textChanged.connect(self.setPwd) #add funcitons to the buttons lis_but.clicked.connect(listDest) sel_but.clicked.connect(self.findPath) ana_but.clicked.connect(testFromServer) upd_but.clicked.connect(submitToServer) grid.setSpacing(10) self.resize(600,600) self.center() self.setWindowTitle('Ahsay v7.15.6.x Quota Updater') self.show() def center(self): #用一个qr obj来存储self之后要放的位置 qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('Finished') return self.step = self.step+1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() self.btn.setText('Start') else: self.timer.start(100,self) self.btn.setText('Stop') def findPath(self, event): file_, filetype = QFileDialog.getOpenFileName(self) print(file_) self.xml_edit.setText(file_) nonlocal usr_xml_path usr_xml_path = file_ #这个 file_ 被echo了 #得到的是一个string def setUrl(self): nonlocal sysAd sysAd = self.url_edit.text() print('setUrl') print(sysAd) def setUsr(self): nonlocal sysUser sysUser = self.usr_edit.text() print('setUsr') print(sysUser) def setPwd(self): nonlocal sysPwd sysPwd = self.pwd_edit.text() print('setPwd') print(sysPwd)
class Graphics(QMainWindow): def __init__(self, game, size): """ :type game: Game :type size: Point """ super().__init__() self.game = game self.pictures = dict() self.mouse_cursor = Point(size.x / 2, size.y - 1) self.setFixedSize(size.x, size.y) self.timer = QBasicTimer() self.initUi() self.initialize_balls() self.frog_picture = self.initialize_frog() self.bullet = self.initialize_bullet() self.data = self.initialize_level_data() def initUi(self): self.setWindowTitle('Zuma') self.setMouseTracking(True) self.timer.start(17, self) self.show() def draw_ball(self, ql: QLabel, b: Ball): offset = Ball.RADIUS / 2 ql.move(b.position.x - offset, b.position.y - offset) def paintEvent(self, event): qp = QPainter() qp.begin(self) qp.setPen(Qt.green) brush = QBrush(Qt.SolidPattern) qp.setBrush(brush) self.draw_level(qp) self.update() qp.end() def draw_level(self, qp): level = self.game.level offset = Ball.RADIUS / 2 qp.drawEllipse(level.start.x - offset, level.start.y - offset, Ball.RADIUS, Ball.RADIUS) qp.drawEllipse(level.end.x - offset, level.end.y - offset, Ball.RADIUS, Ball.RADIUS) qp.drawEllipse(self.game.frog.position.x, self.game.frog.position.y, 4, 4) qp.drawLine(level.start.x, level.start.y, level.end.x, level.end.y) # qp.drawPoints(*self.data) qp.drawPolyline(*self.data) def initialize_level_data(self): data = [] for i in range(0, 900): data.append(QPoint(i, self.game.level.get_value(i))) return data def update_graphic(self): tmp = self.game.level.sequence.head while tmp.past is not None: self.draw_ball(self.pictures[tmp.value], tmp.value) tmp = tmp.past bullet_pm = QPixmap(self.game.frog.current_ball.color.value).scaled(Ball.RADIUS, Ball.RADIUS) self.bullet.setPixmap(bullet_pm) def rotate_frog(self): t = QTransform().rotate(self.game.frog.angle) pm = QPixmap(self.game.frog.color.value).scaled(FROG_SIZE, FROG_SIZE, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.frog_picture.setPixmap(pm.transformed(t, Qt.SmoothTransformation)) def timerEvent(self, event: 'QTimerEvent'): self.game.update(1 / 4, self.mouse_cursor) self.update_graphic() if self.game.is_ending: self.timer.stop() self.rotate_frog() def initialize_balls(self): tmp = self.game.level.sequence.head while tmp.past is not None: ql = QLabel(self) ql.setFixedSize(Ball.RADIUS, Ball.RADIUS) ql.setPixmap(QPixmap(tmp.value.color.value).scaled(Ball.RADIUS, Ball.RADIUS)) self.pictures[tmp.value] = ql ql.show() tmp = tmp.past def initialize_frog(self): ql = QLabel(self) ql.setFixedSize(FROG_SIZE, FROG_SIZE) ql.setAlignment(Qt.AlignCenter) pm = QPixmap(self.game.frog.color.value).scaled(FROG_SIZE, FROG_SIZE, Qt.KeepAspectRatio, Qt.SmoothTransformation) ql.setPixmap(pm) ql.move(self.game.frog.position.x - FROG_SIZE / 2, self.game.frog.position.y - FROG_SIZE / 2) ql.show() return ql def initialize_bullet(self): ql = QLabel(self) ql.setFixedSize(Ball.RADIUS, Ball.RADIUS) ql.setPixmap(QPixmap(self.game.frog.current_ball.color.value).scaled(Ball.RADIUS, Ball.RADIUS)) ql.move(self.game.frog.position.x - Ball.RADIUS / 2, self.game.frog.position.y - Ball.RADIUS / 2) ql.show() return ql def keyPressEvent(self, event): key = event.key() if key == Qt.Key_Shift: self.game.frog.swap_balls() if key == Qt.Key_Space: self.game.shoot() def mouseMoveEvent(self, event): self.mouse_cursor = Point(event.x(), event.y()) def closeEvent(self, event): reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore()
class Lindworm(QMainWindow): def __init__(self, dir: str, parent: object = None) -> None: super(Lindworm, self).__init__(parent) loadUi(pjoin(dir, "res", "lindworm.ui"), self) self.setWindowIcon(QIcon(pjoin(dir, "res", "icon.png"))) # This is where all the objects are handled (drawn, updated, moved, painted, etc.) self.canvas = QGraphicsScene(self) # Use all the QGraphicsView area self.canvas.setSceneRect(0, 0, self.graphicsView.width(), self.graphicsView.height()) self.canvas.setBackgroundBrush( QBrush(QColor(52, 56, 56), Qt.SolidPattern)) self.graphicsView.setScene(self.canvas) # Application variables self.playing = False # Is the player playing? (obviously) self.timer = QBasicTimer( ) # Used for controlling the game speed, and the canvas update self.speed = 100 # Refresh rate which the game is updated (in milliseconds, # the greater it is, the slower is refresh) self.particleSize = 10 # Particle's size of the snake, food, border, ... (scale?) self.score = 0 # Keep track of the user's score self.playtime = QTime( ) # Keep track of the play time, uses later to increase the game speed self.snake = None self.food = None self.special = None self.drawBorder() self.centerOnScreen() self.show() # ####### Application Methods def startGame(self) -> None: """ Starts a New Game every time the user press [Enter, Return] if a game has not started yet """ self.playing = True # Reset the score self.score = 0 self.scoreLabel.setText(str(self.score)) # Start counting the time and the timer which controlls the game cycle self.speed = 100 self.playtime.start() self.timer.start(self.speed, Qt.PreciseTimer, self) # Check if there is a snake drawn on the canvas if self.snake is not None and self.snake in self.canvas.items(): self.canvas.removeItem(self.snake) # The same for the food and special food if self.food is not None and self.food in self.canvas.items(): self.canvas.removeItem(self.food) if self.special is not None and self.special in self.canvas.items(): self.canvas.removeItem(self.special) # Add the new Snake object to the canvas self.snake = Snake(self) self.canvas.addItem(self.snake) # Call the function to add a piece of Food self.addFood() def endGame(self) -> None: """ Handles the event when the Snake dies """ self.playing = False # Show the user the final score point = "point" if self.score == 1 else "points" self.scoreLabel.setText("Game Over. You scored <b>%d</b> %s" % (self.score, point)) # Stop the timer self.timer.stop() # Animate the Window self.shakeIt() def addFood(self, special: bool = False) -> None: """ Add a piece of Food to the canvas """ food = None # Check that the food doesn't spawns inside the snake's body while food is None: food = Food(self) position = [food.x(), food.y()] # If it's inside the body, try again if position in self.snake.body: food = None if special: self.special = food self.special.changeBrush() else: self.food = food self.canvas.addItem(food) def updateScore(self, points: int) -> None: self.score += points self.scoreLabel.setText(str(self.score)) # ####### QMainWindow events def closeEvent(self, event: QCloseEvent) -> None: """ Always remove junk when closing an application """ # Stop the Timer if it's active if self.timer.isActive(): self.timer.stop() # Continue with the closing event event.accept() def keyPressEvent(self, event: QKeyEvent) -> None: """ Listen to the user's input """ # Enter is the key located in the keypad, usually denoted by the text "Intro" # Return is the big key we usually use to create a break in a sentence start = [Qt.Key_Return, Qt.Key_Enter] # Game can be played using Arrow keys and WASD directions = [ Qt.Key_Left, Qt.Key_A, Qt.Key_Right, Qt.Key_D, Qt.Key_Up, Qt.Key_W, Qt.Key_Down, Qt.Key_S ] # Starts a new game if not already playing if not self.playing and event.key() in start: self.startGame() # Change the Snake's movement direction if self.playing and event.key() in directions: self.snake.changeDirection(event.key()) def timerEvent(self, event: QTimerEvent) -> None: """ In charge of, in this case, update the game and check the conditions to continue playing, grow, spawn food and special item """ # Check if the event if from the self.timer if event.timerId() is self.timer.timerId(): self.snake.update() # Add a piece of Special Food every 15 points if self.score % 15 == 0 and self.score != 0 and self.special is None: self.addFood(True) # Increase the movement speed of the Snake every 60 seconds if self.playtime.elapsed() > 60000: self.playtime.restart() self.speed -= 10 # Stop and start the timer, there is no method timer.setTime or # the like for changing the timer's speed of refresh self.timer.stop() self.timer.start(self.speed, Qt.PreciseTimer, self) # Check if the Snake ate the food if self.snake.ateFood(self.food): self.updateScore(1) self.addFood() # Same process for the Special food if self.snake.ateFood(self.special): self.updateScore(5) self.special = None # Check if Snake is out of bounds, or its head collided with # its body if self.snake.outOfBounds() or self.snake.headInsideOfTail(): self.endGame() else: super(Lindworm, self).timerEvent(event) # ####### "Beautifying" methods (graphics-wise) def drawBorder(self) -> None: """ Draw a decorative border in the perimeter of the QGraphicsView """ # Remove the outline outline = QPen(Qt.NoPen) # Change the background color for the object being drawn background = QBrush(QColor(0, 95, 107), Qt.Dense3Pattern) # [0, 10, 20, 30, ... , self.canvas.width()] with particle size set to 10 topBottom = range(0, int(self.canvas.width()), self.particleSize) # [10, 20, 30, 40, ... , self.canvas,height() - 10] with particle size set to 10 leftRight = range(self.particleSize, int(self.canvas.height()) - self.particleSize, self.particleSize) size = self.particleSize width = self.canvas.width() height = self.canvas.height() # Top, Bottom, Left, Right borders (in that order) areas = [ QRectF(0, 0, width, size), QRectF(0, height - size, width, size), QRectF(0, size, size, height - size * 2), QRectF(width - size, size, size, height - size * 2) ] for area in areas: self.canvas.addRect(area, outline, background) def shakeIt(self) -> None: """ Animate the Position of the Window when the Snake dies a horrible death due to the user's fault. In this case, the use of setStartValue and setEndValue cannot be implemented due to the fact that the initial and end position of the window are the same, hence the multiple calls of setKeyValueAt. """ self.animation = QPropertyAnimation(self, QByteArray().append("pos")) # Save the window's original position origin = self.pos() # Amount of pixels that the window is going to be moved offset = 40 self.animation.setKeyValueAt(0.0, QPointF(origin.x(), origin.y())) self.animation.setKeyValueAt(0.3, QPointF(origin.x() - offset, origin.y())) self.animation.setKeyValueAt(0.6, QPointF(origin.x() + offset, origin.y())) self.animation.setKeyValueAt(1.0, QPointF(origin.x(), origin.y())) # Duration of the animation, in milliseconds (1s = 1000ms) self.animation.setDuration(1000) # QEasingCurve.InOutElastic is a type of animation path self.animation.setEasingCurve(QEasingCurve.InOutElastic) # Start and Delete the animation when done self.animation.start(QAbstractAnimation.DeleteWhenStopped) def centerOnScreen(self) -> None: """ Centers the window on the screen keeping in mind the available space for the window to show """ frameGeometry = self.frameGeometry() centerPoint = QDesktopWidget().availableGeometry().center() frameGeometry.moveCenter(centerPoint) self.move(frameGeometry.topLeft())
class Board(QFrame): # 创建一个自定义的信号。 # 当我们想写一个信息或状态栏的分数的时候, # msg2Statusbar发出一个信号 msg2Statusbar = pyqtSignal(str) # 这些都是Board的类变量。 # BoardWidth和BoardHeight定义的块的大小。 # Speed定义了游戏的速度。每个300 ms将开始一个新游戏循环。 BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): self.timer = QBasicTimer() self.isWaitingAfterLine = False # 我们在initBoard()方法初始化一些重要的变量。 # board变量是一个从0到7的数字列表。 # 它代表了面板上各种形状和位置。 self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() # shapeAt()方法确定在给定形状块的类型。 def shapeAt(self, x, y): return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * Board.BoardWidth) + x] = shape # Board可以动态地调整大小。因此,块的大小可能会有所改变。 # squareWidth()计算单一方块像素的宽度并返回它。 # Board.BoardWidth方块板的大小。 def squareWidth(self): return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): return self.contentsRect().height() // Board.BoardHeight def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.newPiece() self.timer.start(Board.Speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.update() def paintEvent(self, event): painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() # 游戏的绘制分为两个步骤, # 第一步,绘制所有方块,这些方块都要保存在底部列表中。 # 列表通过shapeAt() 方法来添加方块。 for i in range(Board.BoardHeight): for j in range(Board.BoardWidth): shape = self.shapeAt(j, Board.BoardHeight - i - 1) if shape != Tetrominoe.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) # 第二步绘制下降中的方块 if self.curPiece.shape() != Tetrominoe.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) # keyPressEvent()方法检查按下键。。 def keyPressEvent(self, event): if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) # 当按右箭头键,我们试图向右移动一块。我们使用tyrMove,因为可能无法移动 elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) # 向上箭头键将旋转方块。 elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) # 空格键立即下降到底部 elif key == Qt.Key_Space: self.dropDown() # 向下箭头可以加速下降。 elif key == Qt.Key_D: self.oneLineDown() else: super(Board, self).keyPressEvent(event) # 计时器事件,当我们前一个方块降到底部后,创建一个新的方块。 def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: super(Board, self).timerEvent(event) # clearBoard()方法通过设置Tetrominoe.NoShape清除面板 def clearBoard(self): for i in range(Board.BoardHeight * Board.BoardWidth): self.board.append(Tetrominoe.NoShape) def dropDown(self): newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() # 如果到达底部,会调用removeFullLines()方法。 # 我们会检查所有完整的线条然后删除它们。 # 然后移动所有行高于当前删除整行一行。 # 请注意,我们反的顺序行被删除。否则,就会出错。 def removeFullLines(self): numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() # 通过newPiece()方法创建一个新的方块,如果不能进入它的初始位置,游戏就结束了。 def newPiece(self): self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over") # 使用tryMove()方法尝试移动方块。 # 如果方块的边缘已经接触到面板边缘或者不能移动,我们返回False。 # 否则我们当前块下降到一个新的位置。 def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoe.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Board(QFrame): def __init__(self): super().__init__() self.__num_y = 23 self.__num_x = 25 self.__time_step = 400 self.__initPara() self.__initUI() self.__initNet() self.setFocusPolicy(Qt.StrongFocus) # 初始化参数 def __initPara(self): self.__score = 0 self.__level = 0 self.__timer = QBasicTimer() self.__FACTOR = 4 / 5 self.__FACTOR_SCREEN = 0.6 self.__canvas_w = self.geometry().width() * self.__FACTOR self.__canvas_h = self.geometry().height() self.__szy = int(self.__canvas_h / self.__num_y) self.__szx = int(self.__canvas_w / self.__num_x) self.__gameOverFlag = False self.__net = [] self.__mshape = Shape() self.__block = Block( 1, 1, self.__mshape.name[random.randint(0, self.__mshape.num - 1)], self.__mshape, self.__mshape.color[random.randint(0, self.__mshape.num_col - 1)]) # 初始化网格列表 def __initNet(self): self.__net = [[0 for j in range(self.__num_x - 1)] for j in range(self.__num_y - 1)] # 初始化界面 def __initUI(self): hb1 = QHBoxLayout() score_info_la = QLabel('Score: ') self.__score_la = QLabel('0') hb1.addWidget(score_info_la) hb1.addWidget(self.__score_la) hb1.addStretch(1) hb2 = QHBoxLayout() level_info_la = QLabel('Level: ') self.__level_la = QLabel('0') hb2.addWidget(level_info_la) hb2.addWidget(self.__level_la) hb2.addStretch(1) self.__speed_la = QLabel() self.__speed_la.setText(str((1010 - self.__time_step) / 10)) self.__speed_label = QLabel('Speed:') self.__sd_slider = QSlider() self.__sd_slider.setOrientation(Qt.Horizontal) self.__sd_slider.setMaximum(1) self.__sd_slider.setMaximum(100) self.__sd_slider.setValue(int((1010 - self.__time_step) / 10)) self.__sd_slider.valueChanged.connect(self.__LineEdt) hb3 = QHBoxLayout() hb3.addWidget(self.__speed_label) hb3.addWidget(self.__speed_la) hb2.addStretch(1) x_num_la = QLabel('X number:') self.__x_num_la_show = QLabel() self.__x_num_la_show.setText(str(self.__num_x - 1)) hb12 = QHBoxLayout() hb12.addWidget(x_num_la) hb12.addWidget(self.__x_num_la_show) hb12.addStretch(1) self.__x_num_sl = QSlider(Qt.Horizontal, self) self.__x_num_sl.setMaximum(100) self.__x_num_sl.setMinimum(1) self.__x_num_sl.setValue(self.__num_x - 1) self.__x_num_sl.valueChanged.connect(self.__setXNum) y_num_la = QLabel('Y number:') self.__y_num_la_show = QLabel() self.__y_num_la_show.setText(str(self.__num_y - 1)) hb13 = QHBoxLayout() hb13.addWidget(y_num_la) hb13.addWidget(self.__y_num_la_show) hb13.addStretch(1) self.__y_num_sl = QSlider(Qt.Horizontal, self) self.__y_num_sl.setMinimum(1) self.__y_num_sl.setMaximum(100) self.__y_num_sl.setValue(self.__num_y - 1) self.__y_num_sl.valueChanged.connect(self.__setYNum) self.__st_btn = QPushButton('Start') self.__st_btn.setEnabled(True) hb7 = QHBoxLayout() hb7.addWidget(self.__st_btn) hb7.addStretch(1) self.__stop_btn = QPushButton('Stop') self.__stop_btn.setEnabled(True) hb8 = QHBoxLayout() hb8.addWidget(self.__stop_btn) hb8.addStretch(1) self.__pause_btn = QPushButton('Pause') self.__pause_btn.setEnabled(True) hb9 = QHBoxLayout() hb9.addWidget(self.__pause_btn) hb9.addStretch(1) self.__new_btn = QPushButton('New Game') self.__new_btn.setEnabled(True) hb10 = QHBoxLayout() hb10.addWidget(self.__new_btn) hb10.addStretch(1) self.__exit_btn = QPushButton('Exit') self.__exit_btn.setEnabled(True) hb11 = QHBoxLayout() hb11.addWidget(self.__exit_btn) hb11.addStretch(1) self.__new_btn.clicked.connect(self.__newGameBtnAction) self.__st_btn.clicked.connect(self.__stBtnAction) self.__stop_btn.clicked.connect(self.__stopBtnAction) self.__pause_btn.clicked.connect(self.__pauseBtnAction) self.__exit_btn.clicked.connect(self.close) self.__lcd = QLCDNumber() self.__lcd.setMinimumSize(100, 100) hb4 = QHBoxLayout() hb4.addWidget(self.__lcd) hb4.addStretch(1) vb = QVBoxLayout() vb.addLayout(hb1) vb.addLayout(hb2) vb.addLayout(hb4) vb.addStretch(1) vb.addLayout(hb3) vb.addWidget(self.__sd_slider) vb.addLayout(hb7) vb.addLayout(hb8) vb.addLayout(hb9) vb.addStretch(1) vb.addLayout(hb12) vb.addWidget(self.__x_num_sl) vb.addLayout(hb13) vb.addWidget(self.__y_num_sl) vb.addLayout(hb10) vb.addStretch(10) vb.addLayout(hb11) hb5 = QHBoxLayout() hb5.addStretch(1) hb5.addLayout(vb) self.setLayout(hb5) screen = QDesktopWidget().screenGeometry() width = screen.width() * self.__FACTOR_SCREEN height = screen.height() * self.__FACTOR_SCREEN x0 = screen.width() * (1 - self.__FACTOR_SCREEN) / 2 y0 = screen.height() * (1 - self.__FACTOR_SCREEN) / 2 self.setGeometry(x0, y0, width, height) self.__canva_w = self.geometry().width() * self.__FACTOR self.__canva_h = self.geometry().height() self.__szx = int(self.__canva_w / self.__num_x) self.__szy = int(self.__canva_h / self.__num_y) self.setWindowTitle("Russian Block") self.setWindowIcon(QIcon('example.png')) self.show() # 绘制网格 def __drawNetGrid(self, qp): pen = QPen(Qt.lightGray, 1, Qt.DashLine) qp.setPen(pen) for i in range(self.__num_y): qp.drawLine(int(self.__szx / 2), int(i * self.__szy + self.__szy / 2), int(self.__num_x * self.__szx - self.__szx / 2), int(i * self.__szy + self.__szy / 2)) for i in range(self.__num_x): qp.drawLine(int(i * self.__szx + self.__szx / 2), int(self.__szy / 2), int(i * self.__szx + self.__szx / 2), int(self.__num_y * self.__szy - self.__szy / 2)) # 提示Game Over def __gameOver(self, qp, x, y): pen = QPen(Qt.red) qp.setPen(pen) qp.setFont(QFont('Blackoak Std', 20)) qp.drawText(x, y, self.__canva_w / 2, self.__canva_h / 2, True, 'Game Over!') # 类的自调用painter绘制函数 def paintEvent(self, e): self.__canvas_w = self.geometry().width() * self.__FACTOR self.__canvas_h = self.geometry().height() self.__szx = int(self.__canvas_w / self.__num_x) self.__szy = int(self.__canvas_h / self.__num_y) qp = QPainter() qp.begin(self) self.__drawNetGrid(qp) # 绘制网格 # 绘制形状 for i, eles in enumerate(self.__net): for j, ele in enumerate(eles): if not ele == 0: self.__drawRect(qp, j + 1, i + 1, self.__szx, self.__szy, ele) if self.__timer.isActive(): self.__drawBlock(qp, self.__block, self.__szx, self.__szy) # game over if self.__gameOverFlag: self.__gameOverFlag = False self.__gameOver(qp, self.__canva_w / 4, self.__canva_h / 2) qp.end() # timer def timerEvent(self, e): if self.__isNextPosEmpty(self.__block, 0, 1): self.__moveBlock(0, 1) else: self.__refreshFullNet(self.__block) for k, ele in enumerate(self.__net): if 0 not in ele: self.__score += 1 self.__level += int(self.__score / 10) self.__update_score() self.__update_level() for i in range(k): self.__net[k - i] = self.__net[k - 1 - i] self.__net[0] = [0 for i in range(self.__num_x - 1)] # 游戏结束 if sum([1 for ele in self.__net[0] if not ele == 0]) > 0: self.stop() self.__st_btn.setEnabled(False) self.__pause_btn.setEnabled(False) self.__stop_btn.setEnabled(False) self.__gameOverFlag = True else: self.__block = self.__generateRandomBlock() self.update() # 键盘按键事件 def keyPressEvent(self, e): key = e.key() x, y = self.__block.getXY() if key == Qt.Key_Left: if (x > 1) & self.__isNextPosEmpty(self.__block, -1, 0): self.__block.setXY(x - 1, y) elif key == Qt.Key_Right: if self.__isNextPosEmpty(self.__block, +1, 0): self.__block.setXY(x + 1, y) elif key == Qt.Key_Down: if self.__isNextPosEmpty(self.__block, 0, 2): self.__block.setXY(x, y + 2) elif key == Qt.Key_Up: block = Block(self.__block.getXY()[0], self.__block.getXY()[1], self.__block.getShape(), self.__mshape, self.__block.getColor()) block.rota90() if (block.getDownBoun() > self.__num_y - 1) | ( block.getLeftBoun() < 1) | (block.getRightBoun() > self.__num_x - 1): pass else: self.__block.rota90() elif key == Qt.Key_P: if self.__timer.isActive(): self.stop() else: self.start() self.update() # 窗口大小改变自动调用事件 def resizeEvent(self, e): self.update() # 判占位列表是否空 def __isNextPosEmpty(self, block, step_x, step_y): bot = block.getDownBoun() right = block.getRightBoun() if ((bot + step_y) > self.__num_y - 1) | ((step_x > 0) & ( (right + step_x) > self.__num_x - 1)): return False pos = block.getPos() for p in pos: if p[1] < 1: pass elif not self.__net[p[1] - 1 + step_y][p[0] - 1 + step_x] == 0: return False return True # 更新占位列表 def __refreshFullNet(self, block): for pos in block.getPos(): if (pos[0] < 1) | (pos[1] < 1) | (pos[0] > self.__num_x - 1) | ( pos[1] > self.__num_y - 1): pass self.__net[pos[1] - 1][pos[0] - 1] = block.getColor() # 生成一个随机对象 def __generateRandomBlock(self): num_sha = random.randint(0, self.__mshape.num - 1) sha = self.__mshape.name[num_sha] num_col = random.randint(0, self.__mshape.num_col - 1) color = self.__mshape.color[num_col] x = random.randint(1, self.__num_x) block = Block(x, 1, sha, self.__mshape, color) while block.getRightBoun() > (self.__num_x - 1): x = random.randint(1, self.__num_x) block = Block(x, 1, sha, self.__mshape, color) return block # 绘制方块 def __drawRect(self, qp, x, y, szx, szy, color): x_loca = x * szx - szx / 2 y_loca = y * szy - szy / 2 # Brush brush = QBrush(color) brush.setStyle(Qt.SolidPattern) qp.setBrush(brush) qp.drawRect(x_loca, y_loca, szx, szy) # Pen pen = QPen(Qt.darkBlue, 2, Qt.SolidLine) qp.setPen(pen) qp.drawRect(x_loca, y_loca, szx, szy) # 绘制特定形状 def __drawBlock(self, qp, block, szx, szy): color = block.getColor() pos = block.getPos() x1 = pos[0][0] y1 = pos[0][1] x2 = pos[1][0] y2 = pos[1][1] x3 = pos[2][0] y3 = pos[2][1] x4 = pos[3][0] y4 = pos[3][1] self.__drawRect(qp, x1, y1, szx, szy, color) self.__drawRect(qp, x2, y2, szx, szy, color) self.__drawRect(qp, x3, y3, szx, szy, color) self.__drawRect(qp, x4, y4, szx, szy, color) # 移动 def __moveBlock(self, speed_x, speed_y): self.__block.setXY(self.__block.getXY()[0] + speed_x, self.__block.getXY()[1] + speed_y) # 更新成绩 def __update_score(self): self.__score_la.setText(str(self.__score)) self.__lcd.display(str(self.__score)) # 更新等级 def __update_level(self): self.__level_la.setText(str(self.__level)) # 滑动条事件 def __LineEdt(self): self.__speed_la.setText(str(self.__sd_slider.value())) self.__time_step = 1010 - self.__sd_slider.value() * 10 if self.__stop_btn.isEnabled() & self.__pause_btn.isEnabled(): self.start() # 设置Xnum def __setXNum(self): self.stop() self.__st_btn.setEnabled(False) self.__stop_btn.setEnabled(False) self.__pause_btn.setEnabled(False) self.__x_num_la_show.setText(str(self.__x_num_sl.value())) self.__num_x = self.__x_num_sl.value() # 设置Y Num def __setYNum(self): self.stop() self.__st_btn.setEnabled(False) self.__stop_btn.setEnabled(False) self.__pause_btn.setEnabled(False) self.__y_num_la_show.setText(str(self.__y_num_sl.value())) self.__num_y = self.__y_num_sl.value() # 开始按钮事件 def __stBtnAction(self): if self.__timer.isActive(): pass else: self.__st_btn.setEnabled(False) self.__stop_btn.setEnabled(True) self.__pause_btn.setEnabled(True) self.__timer.start(self.__time_step, self) # 停止按钮事件 def __stopBtnAction(self): if self.__timer.isActive(): self.__timer.stop() self.__st_btn.setEnabled(False) self.__pause_btn.setEnabled(False) self.__stop_btn.setEnabled(False) self.__timer.stop() # 暂停按钮事件 def __pauseBtnAction(self): if self.__timer.isActive(): self.__timer.stop() self.__st_btn.setEnabled(True) self.__pause_btn.setEnabled(False) self.__stop_btn.setEnabled(True) # 新游戏按钮事件 def __newGameBtnAction(self): if self.__timer.isActive(): self.stop() self.__initPara() self.__initNet() self.__st_btn.setEnabled(True) self.__pause_btn.setEnabled(True) self.__stop_btn.setEnabled(True) self.update() self.start() # 启动时间循环时间 def start(self): self.__timer.start(self.__time_step, self) # 停止计时器 def stop(self): self.__timer.stop()
class Board(QFrame): msg2Statusbar = pyqtSignal(str) # todo set the board with and height in square boardWidth = 8 boardHeight = 8 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): '''initiates board''' self.timer = QBasicTimer() self.isWaitingAfterLine = False self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.resetGame() self.boardArray = [[2, 0, 2, 0, 2, 0, 2, 0], [0, 2, 0, 2, 0, 2, 0, 2], [2, 0, 2, 0, 2, 0, 2, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0, 1]] # 2d int/Piece array to story the state of the game self.move = [] self.printBoardArray() def printBoardArray(self): '''prints the boardArray in an arractive way''' print("boardArray:") print('\n'.join([ '\t'.join([str(cell) for cell in row]) for row in self.boardArray ])) def mousePosToColRow(self, event): '''convert the mouse click event to a row and column''' # x_point = QMouseEvent.pos() print("Test: " + self.squareWidth() / event.pos().x()) def squareWidth(self): '''returns the width of one square in the board''' return self.contentsRect().width() / Board.boardWidth def squareHeight(self): '''returns the height of one squarein the board''' return self.contentsRect().height() / Board.boardHeight def start(self): '''starts game''' if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.resetGame() self.msg2Statusbar.emit(str("status message")) self.timer.start(Board.Speed, self) def pause(self): '''pauses game''' if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str("status message")) self.update() def paintEvent(self, event): '''paints the board and the pieces of the game''' painter = QPainter(self) self.drawBoardSquares(painter) self.drawPieces(painter) def mousePressEvent(self, event): # print("click location [", event.x(), ",", event.y(), "]") xValue = (int)(event.x() / self.squareWidth()) yValue = (int)(event.y() / self.squareHeight()) if self.boardArray[yValue][xValue] == 1: self.move = [] self.move.append('1') self.move.append(yValue) self.move.append(xValue) print(self.move) elif self.boardArray[yValue][xValue] == 2: self.move = [] self.move.append('2') self.move.append(yValue) self.move.append(xValue) print(self.move) else: if len(self.move) > 2: self.move.append(yValue) self.move.append(xValue) print(self.move) if self.move[0] == '1': self.player1Move() else: self.player2Move() else: print('Not a Piece') # todo you could call some game logic here def player1Move(self): print('Player 1') from_y = self.move[1] from_x = self.move[2] to_y = self.move[3] to_x = self.move[4] temp = self.boardArray[from_y][from_x] self.boardArray[from_y][from_x] = self.boardArray[to_y][to_x] self.boardArray[to_y][to_x] = temp self.update() # painter = QPainter(self) # self.drawBoardSquares(painter) # self.drawPieces(painter) def player2Move(self): print('Player 2') from_y = self.move[1] from_x = self.move[2] to_y = self.move[3] to_x = self.move[4] temp = self.boardArray[from_y][from_x] self.boardArray[from_y][from_x] = self.boardArray[to_y][to_x] self.boardArray[to_y][to_x] = temp self.update() # painter = QPainter(self) # self.drawBoardSquares(painter) # self.drawPieces(painter) def keyPressEvent(self, event): '''processes key press events if you would like to do any''' if not self.isStarted or self.curPiece.shape() == Piece.NoPiece: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 2, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(Board, self).keyPressEvent(event) def timerEvent(self, event): '''handles timer event''' #todo adapter this code to handle your timers if event.timerId() == self.timer.timerId(): pass else: super(Board, self).timerEvent(event) def resetGame(self): '''clears pieces from the board''' # todo write code to reset game def tryMove(self, newX, newY): '''tries to move a piece''' def drawBoardSquares(self, painter): '''draw all the square on the board''' # todo set the dafault colour of the brush default_colour = Qt.black for row in range(0, Board.boardHeight): if default_colour == Qt.black: default_colour = Qt.white else: default_colour = Qt.black for col in range(0, Board.boardWidth): painter.save() colTransformation = col * self.squareWidth( ) # Todo set this value equal the transformation you would like in the column direction rowTransformation = row * self.squareHeight( ) # Todo set this value equal the transformation you would like in the column direction painter.translate(colTransformation, rowTransformation) painter.fillRect( 0, 0, self.squareWidth(), self.squareHeight(), default_colour) # Todo provide the required arguements painter.restore() # todo change the colour of the brush so that a checkered board is drawn if default_colour == Qt.black: default_colour = Qt.white else: default_colour = Qt.black def drawPieces(self, painter): '''draw the prices on the board''' colour = Qt.transparent painter.setPen(Qt.transparent) for row in range(0, len(self.boardArray)): for col in range(0, len(self.boardArray[0])): colTransformation = col * self.squareWidth( ) # Todo set this value equal the transformation you would like in the column direction rowTransformation = row * self.squareHeight( ) # Todo set this value equal the transformation you would like in the column direction print(colTransformation) print(rowTransformation) painter.save() painter.translate(colTransformation, rowTransformation) #Todo choose your colour and set the painter brush to the correct colour if self.boardArray[row][col] == 1: colour = Qt.red elif self.boardArray[row][col] == 2: colour = Qt.blue else: colour = Qt.transparent painter.setBrush(colour) # Todo draw some the pieces as elipses radius1 = (self.squareWidth() - 2) / 2 radius2 = (self.squareHeight() - 2) / 2 # print(radius) center = QPoint(radius1, radius2) print(center) painter.drawEllipse(center, radius1, radius2) painter.restore()
class SpielFeld(QWidget): #Array construction PlayFieldAR = [[0 for x in range(100)] for y in range(100)] BarrierList = [] Bullets = [] def __init__(self): super().__init__() # change texture preferences self.wallTexture = self.changeWall(wtexture) #print(wtexture) self.floorTexture = self.changeFloor(ftexture) self.spellcard = self.changeSpellcard(spellcard) #print(ftexture) self.SoundBomb = pygame.mixer.Sound('sounds/getbomb.wav') self.SoundRedBomb = pygame.mixer.Sound('sounds/getredbomb.wav') self.DeathSound = pygame.mixer.Sound('sounds/death.wav') self.RoboTextures = {0: QPixmap('textures/Robots/Robot01.png'), # MainRobot 1: QPixmap('textures/Robots/Robot_Dead.png'), # Dead 2: QPixmap('textures/Robots/Robot_In.png'), # Ivincible 3: QPixmap('textures/Robots/Robot02.png') # EnemyRobot } self.bombPosition = {0: [50,50], 1: [900,50], 2: [900,900], 3: [50,900], } #randomize inital bomb-status (50/50 Chance) number = random.randint(1, 2) if number == 1: self.bombStatus = 'green' elif number == 2: self.bombStatus = 'red' self.bombTime = BOMB_TIMER self.currentBombPos = 0 self.createBoard() self.RobotType = self # init Robots Robot1 = Robots.Robot(1, QVector2D(500, 500), 290, 2, 2, 15, 90, 0) Robot2 = Robots.Robot(2, QVector2D(100, 900), 90, 2, 2, 15, 90, 3) Robot3 = Robots.Robot(3, QVector2D(250, 650), 270, 2, 2, 15, 90, 3) Robot4 = Robots.Robot(4, QVector2D(950, 100), 180, 2, 2, 15, 90, 3) if self.spellcard == "Spellcard1": Robot1.setProgram(Control.PlayerRobot_Ability01(Robot1)) elif self.spellcard == "Spellcard2": Robot1.setProgram(Control.PlayerRobot_Ability02(Robot1)) elif self.spellcard == "Spellcard3": Robot1.setProgram(Control.PlayerRobot_Ability03(Robot1)) elif self.spellcard == "Spellcard4": Robot1.setProgram(Control.PlayerRobot_Ability04(Robot1)) elif self.spellcard == "Spellcard5": Robot1.setProgram(Control.PlayerRobot_Ability05(Robot1)) elif self.spellcard == "Spellcard6": Robot1.setProgram(Control.PlayerRobot_Ability06(Robot1)) elif self.spellcard == "Spellcard7": Robot1.setProgram(Control.PlayerRobot_Ability07(Robot1)) elif self.spellcard == "AllSpellcards": Robot1.setProgram(Control.PlayerRobot_All_Abilities(Robot1)) Robot2.setProgram(Control.TargetHunt(Robot2)) Robot3.setProgram(Control.TargetHunt(Robot3)) Robot4.setProgram(Control.TargetHunt(Robot4)) self.robots = [Robot1, Robot2, Robot3, Robot4] Robot1.executeProgram() Robot2.executeProgram() Robot3.executeProgram() Robot4.executeProgram() self.timer = QBasicTimer() self.tickCount = 0 self.initUI() def initUI(self): self.setGeometry(0, 0, SCREENWIDTH, SCREENHEIGHT) self.setWindowTitle('Game.exe') center(self) self.isStarted = False self.isPaused = False self.show() def changeSpellcard(self, name): Menu.CurSpell = name return name def changeWall(self, name): Menu.CurWall = name return QPixmap(wallTextures[name]) def changeFloor(self, name): Menu.CurFloor = name return QPixmap(floorTextures[name]) def start(self): if self.isPaused: return self.isStarted = True self.timer.start(FPS, self) def createBoard(self): # set Walls, set array value to 1 to place Wall # set Wall around the edges # SpielFeld.PlayFieldAR[90][90] = 1 # SpielFeld.PlayFieldAR[10][10] = 1 for x in range(0, 100, 1): SpielFeld.PlayFieldAR[x][0] = 1 SpielFeld.PlayFieldAR[x][99] = 1 for y in range(1, 99, 1): SpielFeld.PlayFieldAR[0][y] = 1 SpielFeld.PlayFieldAR[99][y] = 1 # set some Obstacle for i in range(0, 25, 1): SpielFeld.PlayFieldAR[70][i + 45] = 1 SpielFeld.PlayFieldAR[71][i + 45] = 1 for i in range(0, 40, 1): SpielFeld.PlayFieldAR[i + 10][40] = 1 SpielFeld.PlayFieldAR[i + 10][41] = 1 for i in range(0, 50, 1): SpielFeld.PlayFieldAR[i + 30][70] = 1 SpielFeld.PlayFieldAR[i + 30][71] = 1 for i in range(0, 30, 1): SpielFeld.PlayFieldAR[i + 25][20] = 1 SpielFeld.PlayFieldAR[i + 25][21] = 1 for i in range(0, 10, 1): SpielFeld.PlayFieldAR[10][i + 50] = 1 SpielFeld.PlayFieldAR[11][i + 50] = 1 def randomizeBombStatus(self): number = random.randint(1, 2) if number == 1: self.bombStatus = 'green' elif number == 2: self.bombStatus = 'red' def timerEvent(self, event): if event.timerId() == self.timer.timerId(): # Count self.tickCount += 1 # update RobotLists of each Robot if self.tickCount % 5 == 0: for y in self.robots: for x in self.robots: y.RobotList[x.robotid] = x.position # move robots on the game field for robot in self.robots: if robot.deathTime == 0: self.fetchBullets(robot) self.moveRobot(robot) self.barrierCollision(robot) self.roboCollision(robot, self.robots[0]) self.SightingData(robot) self.reduceDelay(robot) self.reduceDeathTime(robot) self.reduceImmuneTime(robot) self.reduceBombTime() #print(self.currentBombPos) # Green-Bomb : Grants immunity to the robot if self.bomb_hit(robot) and self.bombStatus == 'green': self.randomizeBombStatus() #Hier: Hit-Effekte self.setNextBombPos() # Immunity robot.immuneTime = 500 robot.texture = 2 pygame.mixer.Sound.play(self.SoundBomb) # Red-Bomb : Eliminates all other robots if self.bomb_hit(robot) and self.bombStatus == 'red' and robot.robotid == 1: self.setNextBombPos() self.randomizeBombStatus() for robot in self.robots: if robot.robotid != 1: robot.deathTime = 150 robot.texture = 1 pygame.mixer.Sound.play(self.SoundRedBomb) for bul in SpielFeld.Bullets: if bul.delay == 0: bul.moveBullet() bul.time -= 1 if bul.time == 0: SpielFeld.Bullets.remove(bul) if BulCollision: if self.BulletBarrierCollision(bul) and bul in SpielFeld.Bullets: SpielFeld.Bullets.remove(bul) Menu.CurCol = "Wall Collision On" else: Menu.CurCol = "Wall Collision Off" for robot in self.robots: if bul.one_hit(robot): if robot.robotid == 1 and robot.immuneTime == 0 and robot.deathTime == 0: robot.deathTime = DEATH_TIME robot.texture = 1 pygame.mixer.Sound.play(self.DeathSound) elif robot.robotid != 1 and robot.immuneTime == 0: self.teleport_bullet(robot) robot.immuneTime = IMMUNE_TIME robot.texture = 2 if bul in SpielFeld.Bullets: SpielFeld.Bullets.remove(bul) ### else: bul.delay -= 1 self.update() else: super(SpielFeld, self).timerEvent(event) def fetchBullets(self, Robot): SpielFeld.Bullets.extend(Robot.BulList) # print(SpielFeld.Bullets) Robot.BulList.clear() def reduceDelay(self, Robot): if Robot.reload != 0: Robot.reload -= 1 if Robot.coolDown != 0: Robot.coolDown -= 1 # Death Counter (Down) {see Constants} def reduceDeathTime(self, Robot): if Robot.deathTime != 0: Robot.deathTime -= 1 if Robot.deathTime == 0: Robot.immuneTime = IMMUNE_TIME Robot.texture = 2 def teleport_bullet(self, robo): spot = random.randint(1, 5) if spot == 1: robo.position = QVector2D(100, 100) elif spot == 2: robo.position = QVector2D(100, 850) elif spot == 3: robo.position = QVector2D(850, 100) elif spot == 4: robo.position = QVector2D(850, 850) elif spot == 5: robo.position = QVector2D(500, 500) def reduceImmuneTime(self, Robot): if Robot.immuneTime != 0: Robot.immuneTime -= 1 if Robot.immuneTime == 0: if Robot.robotid == 1: Robot.texture = 0 else: Robot.texture = 3 def paintEvent(self, qp): qp = QPainter() qp.begin(self) self.drawField(qp) # draw Robots on the game field for robot in self.robots: self.drawRobo(robot, qp) # qp.drawPath(self.FOV(robot)) for bul in SpielFeld.Bullets: if bul.delay == 0: bul.drawBullet(qp) if self.bombStatus == 'green': self.drawBomb(qp) if self.bombStatus == 'red': self.drawRedBomb(qp) def drawRobo(self, Robo, br): # Set Rotation, place etc texture = self.RoboTextures[Robo.texture] br.save() br.translate(Robo.position.x() + Robo.radius, Robo.position.y() + Robo.radius) br.rotate(-Robo.alpha) source = QRectF(0, 0, 2 * Robo.radius, 2 * Robo.radius) target = QRectF(-Robo.radius, -Robo.radius, 2 * Robo.radius, 2 * Robo.radius) # Draw br.drawPixmap(target, texture, source) br.restore() def FOV(self, Robo): view = QPainterPath() xPos = math.cos(math.radians(Robo.alpha + (Robo.FOV / 2))) * Robo.radius yPos = math.sin(math.radians(Robo.alpha + (Robo.FOV / 2))) * Robo.radius xPos2 = math.cos(math.radians(Robo.alpha - (Robo.FOV / 2))) * Robo.radius yPos2 = math.sin(math.radians(Robo.alpha - (Robo.FOV / 2))) * Robo.radius x1 = QPoint(int(round(Robo.position.x())) + Robo.radius, int(round(Robo.position.y())) + Robo.radius) x2 = x1 + QPoint((int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos, (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos) x3 = x1 + QPoint((int(round(Robo.position.x())) + Robo.radius) + 1000 * xPos2, (int(round(Robo.position.y())) + Robo.radius) - 1000 * yPos2) view.addPolygon(QPolygonF([x1, x2, x3])) view.closeSubpath() return view def SightingData(self, robo): viewPanel = self.FOV(robo) ids = [] # seeing other robots in FOV for x in self.robots: if robo != x: if viewPanel.intersects(x.roboShape()): ids.append(x.robotid) # print(robo.robotid, ids) else: robo.ViewList[x.robotid][3] = False # update ViewList for id in ids: for robot in self.robots: if robot.robotid == id and (robo.position - robot.position).length() < 300: viewedRobo = robot.robotid distance = (robo.position - robot.position).length() viewedDirection = robot.alpha seen = True toUpDate = {viewedRobo: [robot.position, distance, viewedDirection, seen]} robo.ViewList.update(toUpDate) # print(robo.robotid, robo.ViewList) def drawField(self, qp): qp.setPen(Qt.NoPen) texture = self.floorTexture if ftexture == "Background Dirt" or ftexture == "Background Pattern" or ftexture == "Background Sakura" or ftexture == "Background Water": qp.drawPixmap(- ((self.tickCount/2) % 1000), - ((self.tickCount/2) % 1000), texture) else: qp.drawPixmap(0,0, texture) #Draw the PlayField for i in range(0, 100, 1): for j in range(0, 100, 1): if SpielFeld.PlayFieldAR[i][j]==1: texture = self.wallTexture self.BarrierList.append(texture) qp.drawPixmap(i*10, j*10, texture) ## BOMB ## def bombShape(self, bombPos): shape = QPainterPath() shape.addRect(bombPos[0], bombPos[1], BOMB_SIZE, BOMB_SIZE) return shape def bomb_hit(self, robo): return self.bombShape(self.bombPosition[self.currentBombPos]).intersects(robo.roboShape()) def randomizeBombIcon(self): number = random.randint(1, 2) if number == 1: self.bombStatus = 'green' elif number == 2: self.bombStatus = 'red' def drawBomb(self, qp): texture = QPixmap('textures/bomb.jpg') qp.drawPixmap(self.bombPosition[self.currentBombPos][0], self.bombPosition[self.currentBombPos][1], texture) def drawRedBomb(self,qp): texture = QPixmap('textures/redbomb.jpg') qp.drawPixmap(self.bombPosition[self.currentBombPos][0], self.bombPosition[self.currentBombPos][1], texture) def reduceBombTime(self): if self.bombTime != 0: self.bombTime -= 1 if self.bombTime == 0: self.bombTime = BOMB_TIMER self.randomizeBombIcon() self.setNextBombPos() #self.setCurrBombPos() def setCurrBombPos(self, bombPos ): if bombPos >= 0 and bombPos < 3: bombPos += 1 else: bombPos = 0 return bombPos def setNextBombPos(self): self.currentBombPos = self.setCurrBombPos(self.currentBombPos) ## def keyPressEvent(self, event): if not self.isStarted: super(SpielFeld, self).keyPressEvent(event) return if event.type() == QEvent.KeyPress: key = event.key() if key == Qt.Key_P: self.pause() return else: super(SpielFeld, self).keyPressEvent(event) def Message(self): msgBox = QMessageBox() msgBox.setWindowTitle("Pause Screen") msgBox.setIconPixmap(QPixmap('textures/Board/pauseEmoji.png')) msgBox.setText("Your in the pause screen. \n Do you want to continue? \n") # set Buttons msgBox.addButton(QMessageBox.Yes) msgBox.addButton(QMessageBox.No) # change backgroundstyle p = self.palette() p.setColor(self.backgroundRole(), colors["white smoke"]) msgBox.setPalette(p) msgBox.exec_() return msgBox def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() # switch to pause screen self.msgBox = self.Message().result() if self.msgBox == QMessageBox.No: self.startMenu = Menu.start_Menu() self.close() else: self.isPaused = False self.timer.start(FPS, self) else: self.timer.start(FPS, self) self.update() def moveRobot(self, Robo): # berechne neue Lenkrichtung if (Robo.v_alpha + Robo.a_alpha) < -v_alpha_Max: Robo.v_alpha = -v_alpha_Max elif (Robo.v_alpha + Robo.a_alpha) <= v_alpha_Max: Robo.v_alpha = (Robo.v_alpha + Robo.a_alpha) elif (Robo.v_alpha + Robo.a_alpha) >= v_alpha_Max: Robo.v_alpha = v_alpha_Max # Neue Richtung Robo.alpha = (Robo.alpha + Robo.v_alpha) % 360 # berechne geschwindigkeit if (Robo.v + Robo.a) <= -vMax: Robo.v = -vMax elif (Robo.v + Robo.a) < vMax: Robo.v += Robo.a elif (Robo.v + Robo.a) >= vMax: Robo.v = vMax # X-Y Geschwindigkeit GesX = math.cos(math.radians(Robo.alpha)) * Robo.v GesY = - math.sin(math.radians(Robo.alpha)) * Robo.v # setze neue Geschwindigkeit Robo.v_vector = QVector2D(GesX, GesY) # berechne neue Position Robo.position.__iadd__(Robo.v_vector) def distanceTwoPoints(self, x1, y1, x2, y2): return math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) def distance(self, robo1, robo2): return self.distanceTwoPoints(int(round(robo1.position.x())) + robo1.radius, int(round(robo1.position.y())) + robo1.radius, int(round(robo2.position.x())) + robo2.radius, int(round(robo2.position.y())) + robo2.radius) def roboCollision(self, robo, target): for robot in self.robots: if robot != robo: distance = self.distance(robot, robo) if distance <= robot.radius + robo.radius: dx = (robot.position - robo.position).x() dy = (robot.position - robo.position).y() tangent = math.atan2(dy, dx) robo.alpha = 2 * tangent - robo.alpha angle = 0.5 * math.pi + tangent overlap = distance - (robot.radius - robo.radius) roboX = math.sin(angle) * overlap roboY = math.cos(angle) * overlap newVel = QVector2D(roboX, roboY).normalized() robo.position.__iadd__(newVel) robot.position.__iadd__(newVel * (-1)) def teleport(self, target, robot): MID = 500 if robot != target: distance = self.distance(robot, target) if distance <= target.radius + robot.radius: if int(round(target.position.x())) > MID and int(round(target.position.y())) < MID: robot.position = QVector2D(100, 850) elif int(round(target.position.x())) > MID and int(round(target.position.y())) > MID: robot.position = QVector2D(100, 100) elif int(round(target.position.x())) < MID and int(round(target.position.y())) < MID: robot.position = QVector2D(850, 850) elif int(round(target.position.x())) < MID and int(round(target.position.y())) > MID: robot.position = QVector2D(850, 100) def barrierCollision(self, robo): # Collision with Obstacles PosX = int(round(robo.position.x() / 10)) PosY = int(round(robo.position.y() / 10)) Rad = int(round((robo.radius * 2) / 10)) for i in range(0, Rad, 1): if 0 <= PosX + i < 100 and 0 <= PosX - i < 100 and 0 <= PosY + i < 100 and 0 <= PosY - i < 100: # oben if (SpielFeld.PlayFieldAR[PosX + i][PosY - 1] == 1) & (robo.v_vector.y() < 0): robo.position.__isub__(robo.v_vector) robo.v_vector = QVector2D(0, 0) robo.a = 0 # unten if (SpielFeld.PlayFieldAR[PosX + i][PosY + Rad] == 1) & (robo.v_vector.y() > 0): robo.position.__isub__(robo.v_vector) robo.v_vector = QVector2D(0, 0) robo.a = 0 # links if (SpielFeld.PlayFieldAR[PosX - 1][PosY + i] == 1) & (robo.v_vector.x() < 0): robo.position.__isub__(robo.v_vector) robo.v_vector = QVector2D(0, 0) robo.a = 0 # rechts if (SpielFeld.PlayFieldAR[PosX + Rad][PosY + i] == 1) & (robo.v_vector.x() > 0): robo.position.__isub__(robo.v_vector) robo.v_vector = QVector2D(0, 0) robo.a = 0 def BulletBarrierCollision(self, bullet): # Collision with Obstacles PosX = int(round(bullet.position.x() / 10)) PosY = int(round(bullet.position.y() / 10)) # oben if 0 <= PosX + 1 < 100 and 0 <= PosX - 1 < 100 and 0 <= PosY + 1 < 100 and 0 <= PosY - 1 < 100: if (SpielFeld.PlayFieldAR[PosX][PosY - 1] == 1): return True # unten if (SpielFeld.PlayFieldAR[PosX][PosY + 1] == 1): return True # links if (SpielFeld.PlayFieldAR[PosX - 1][PosY] == 1): return True # rechts if (SpielFeld.PlayFieldAR[PosX + 1][PosY] == 1): return True else: SpielFeld.Bullets.remove(bullet) return False
class Grid(QWidget): def __init__(self, x, y): super().__init__() self.grid = QGridLayout() self.grid.setSpacing(0) self.setLayout(self.grid) self.x_length = x self.y_length = y # Initialize all the cells in the grid for x in range(self.x_length): for y in range(self.y_length): cell = Cell() self.grid.addWidget(cell, x, y) # Initialize the QBasicTimer which will be used to manage the update (refresh rate) of the view self.timer = QBasicTimer() self.on = False self.clearGame() def timerEvent(self, event): # Calculate the future state of every cell in the grid (without updating the view) for i in range(self.grid.count()): x, y = self.grid.getItemPosition(i)[0], self.grid.getItemPosition(i)[1] cell = self.grid.itemAt(i).widget() self.futureState(cell, x, y) # Update the view for all cells simultaneously for i in range(self.grid.count()): self.grid.itemAt(i).widget().updateState() def startGame(self): self.timer.start(self.speed, self) self.on = True def pauseGame(self): self.timer.stop() self.on = False def clearGame(self): self.pauseGame() # Initialize the state of all cells for x in range(self.x_length): for y in range(self.y_length): self.grid.itemAtPosition(x, y).widget().alive = False self.grid.itemAtPosition(x, y).widget().next_state = False self.grid.itemAtPosition(x, y).widget().stateColor = 'white' self.update() def futureState(self, cell, x, y): alive_neighbors = 0 # Calculate all alive neighbors of a particular cell for i in [-1, 0, 1]: for j in [-1, 0, 1]: if not (i == j == 0) and (x+i in range(0, self.x_length)) and (y+j in range(0, self.y_length))\ and self.grid.itemAtPosition(x + i, y + j).widget().alive: alive_neighbors += 1 # According to game's rules change cell's next state which will be updated later when # all cells will have calculated their respective next state if cell.alive and (2 <= alive_neighbors <= 3): cell.next_state = cell.alive elif not cell.alive and alive_neighbors == 3: cell.next_state = True elif cell.alive and (alive_neighbors < 2 or alive_neighbors > 3): cell.next_state = False
class MyWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.createProgressBars() self.timer = QBasicTimer() self.classfyFolder = "." self.metFolder = "." grid = QGridLayout() grid.addWidget(self.createClassfyMImage(), 0, 0) grid.addWidget(self.createMetMImage(), 0, 1) self.setLayout(grid) self.setGeometry(200, 200, 500, 250) self.show() def createProgressBars(self): self.progressbarClassfy = QProgressBar(self) self.progressbarClassfy.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.progressbarClassfy.setMinimumHeight(50) self.progressbarClassfy.setMinimumWidth(50) self.progressbarClassfy_value = 0 self.progressbarMet = QProgressBar(self) self.progressbarMet.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.progressbarMet.setMinimumHeight(50) self.progressbarMet.setMinimumWidth(50) self.progressbarMet_value = 0 self.progressBars = [self.progressbarClassfy, self.progressbarMet] # 매크로 이미지 분류기 def createClassfyMImage(self): groupbox = QGroupBox('1. MACRO 이미지 분류') folderSettingButton = QPushButton("분류폴더 설정") folderSettingButton.resize(100, 50) folderSettingButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) folderSettingButton.setMinimumHeight(50) folderSettingButton.setMinimumWidth(50) folderSettingButton.clicked.connect( self.ClassfyFolderSettingButtonClicked) startClassfyButton = QPushButton("이미지분류 시작") startClassfyButton.resize(100, 50) startClassfyButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) startClassfyButton.setMinimumHeight(50) startClassfyButton.setMinimumWidth(50) startClassfyButton.clicked.connect(self.buttonClicked) self.statusClassfyLabel = QLabel("") vbox = QVBoxLayout() vbox.addWidget(folderSettingButton) vbox.addWidget(startClassfyButton) vbox.addStretch(1) vbox.addWidget(self.statusClassfyLabel) vbox.addWidget(self.progressbarClassfy) vbox.addStretch(1) groupbox.setLayout(vbox) return groupbox # 매크로 이미지 처리기 def createMetMImage(self): groupbox = QGroupBox('2. 지름 측정') folderSettingButton = QPushButton("매크로폴더 설정") folderSettingButton.resize(100, 50) folderSettingButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) folderSettingButton.setMinimumHeight(50) folderSettingButton.setMinimumWidth(50) folderSettingButton.clicked.connect(self.MetFolderSettingButtonClicked) startClassfyButton = QPushButton("지름측정 시작") startClassfyButton.resize(100, 50) startClassfyButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) startClassfyButton.setMinimumHeight(50) startClassfyButton.setMinimumWidth(50) startClassfyButton.clicked.connect(self.buttonClicked) self.statusMetLabel = QLabel() vbox = QVBoxLayout() vbox.addWidget(folderSettingButton) vbox.addWidget(startClassfyButton) vbox.addStretch(1) vbox.addWidget(self.statusMetLabel) vbox.addWidget(self.progressbarMet) vbox.addStretch(1) groupbox.setLayout(vbox) return groupbox def ClassfyFolderSettingButtonClicked(self): path = QFileDialog.getExistingDirectory(self) if path: self.classfyFolder = path statusString = "선택한 폴더 : \n" + self.classfyFolder self.statusClassfyLabel.setText(statusString) self.progressbarClassfy_value = 0 self.progressbarClassfy.setValue(self.progressbarClassfy_value) else: statusString = "폴더 설정을 취소하였습니다" self.statusClassfyLabel.setText(statusString) def MetFolderSettingButtonClicked(self): path = QFileDialog.getExistingDirectory(self) if path: self.metFolder = path statusString = "선택한 폴더 : \n" + self.metFolder self.statusMetLabel.setText(statusString) self.progressbarMet_value = 0 self.progressbarMet.setValue(self.progressbarMet_value) else: statusString = "폴더 설정을 취소하였습니다" self.statusMetLabel.setText(statusString) def buttonClicked(self): sender = self.sender() # 이미지분류 버튼 if sender.text() == "이미지분류 시작": if (not self.classfyFolder) or (self.classfyFolder == "."): QMessageBox.information(self, "폴더 설정", "폴더 설정이 필요합니다") else: if self.timer.isActive(): print('진행중') else: self.timer.start(100, self) print("스타트") # 지름측정 버튼 elif sender.text() == "지름측정 시작": if (not self.metFolder) or (self.metFolder == "."): QMessageBox.information(self, "폴더 설정", "폴더 설정이 필요합니다") self.progressbarMet_value = 0 self.progressbarMet.setValue(self.progressbarMet_value) return def timerEvent(self, QTimerEvent): if self.progressbarClassfy_value >= 100: self.timer.stop() return self.progressbarClassfy_value += 1 self.progressbarClassfy.setValue(self.progressbarClassfy_value)
class MyWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.now = 0 self.timer = QBasicTimer() self.step = 0 grid = QGridLayout() grid.setSpacing(10) self.holes = [] x, y = 0, 0 for i in range(9): self.holes.append(QPushButton('U', self)) self.holes[i].setFlat(True) self.holes[i].setIcon(QIcon(UNACTIVE)) self.holes[i].setIconSize(QSize(200, 200)) self.holes[i].clicked.connect(self.smash) grid.addWidget(self.holes[i], x, y) if x < 2: x += 1 else: y += 1 x = 0 self.count = QLabel('0') self.time = QLabel(str(TIME)) self.runBt = QPushButton('Start') self.runBt.clicked.connect(self.startGame) grid.addWidget(self.count, y, 0) grid.addWidget(self.runBt, y, 1) grid.addWidget(self.time, y, 2) self.setLayout(grid) self.setWindowTitle('UI, not GUI') self.setGeometry(100, 100, 720, 480) self.show() def showHim(self): number = randint(0, 9) kind = randint(0, 1) if kind: self.holes[number].setText('G') self.holes[number].setIcon(QIcon(GOOD)) else: self.holes[number].setText('B') self.holes[number].setIcon(QIcon(BAD)) self.now = number def clearHim(self): self.holes[self.now].setText('U') self.holes[self.now].setIcon(QIcon(UNACTIVE)) def timerEvent(self, e): self.clearHim() self.showHim() if self.step >= TIME * 2: self.timer.stop() self.runBt.setEnabled(True) self.time.setText(str(TIME)) self.step = 0 self.clearHim() return self.step += 1 if self.step % 2: time = int(self.time.text()) - 1 self.time.setText(str(time)) def startGame(self): time = TIME * 1000 // 60 self.timer.start(time, self) self.count.setText('0') self.runBt.setEnabled(False) def smash(self): sender = self.sender() if sender.text() == 'B': self.clearHim() count = int(self.count.text()) + 1 self.count.setText(str(count)) elif sender.text() == 'G': self.clearHim() count = int(self.count.text()) - 1 self.count.setText(str(count))
class Ui_manager_face(QWidget): def __init__(self): super(Ui_manager_face, self).__init__() # 初始化 ID self.ID_num = "" self.lab_face = QLabel(self) # 初始化进度条定时器 self.timer = QBasicTimer() self.step = 0 # 创建数字按键 self.btn_1 = QPushButton('1', self) self.btn_2 = QPushButton('2', self) self.btn_3 = QPushButton('3', self) self.btn_4 = QPushButton('4', self) self.btn_5 = QPushButton('5', self) self.btn_6 = QPushButton('6', self) self.btn_7 = QPushButton('7', self) self.btn_8 = QPushButton('8', self) self.btn_9 = QPushButton('9', self) self.btn_0 = QPushButton('0', self) self.btn_del = QPushButton('del', self) # 创建容器存放数字键,使用栅格布局 self.layoutWidget = QWidget(self) self.gridLayout = QGridLayout(self.layoutWidget) # 创建groupBox控件 self.groupBox = QtWidgets.QGroupBox(self) # 创建lab_ID控件 self.lab_ID = QLabel(self.groupBox) self.lab2 = QLabel(self.groupBox) self.Edit_ID = QLineEdit(self.groupBox) self.edit2 = QLineEdit(self.groupBox) self.btn_enter = QPushButton(self.groupBox) self.progressBar = QtWidgets.QProgressBar(self.groupBox) self.btn_back = QPushButton(self.groupBox) # 创建定时器 self.timer_camera = QtCore.QTimer() # 初始化摄像头数据 self.camera_init() # 初始化界面 self.init_ui() # 显示人脸识别视频界面 self.face_rec() # 定时器函数 self.timer_camera.timeout.connect(self.show_camera) # 点击按钮开启线程 self.btn_enter.clicked.connect(self.slot_btn_enter) # 初始化摄像头数据 def camera_init(self): # 打开设置摄像头对象 self.cap = cv2.VideoCapture() self.CAM_NUM = 0 self.__flag_work = 0 self.x = 0 self.count = 0 self.cap.set(4, 951) # set Width self.cap.set(3, 761) # set Height # 初始化界面 def init_ui(self): self.resize(1280, 800) self.lab_face.setGeometry(15, 40, 960, 720) self.lab_face.setFrameShape(QtWidgets.QFrame.Box) self.lab_face.setText("") self.lab_ID.setGeometry(10, 40, 31, 41) # 设置容器位置 self.layoutWidget.setGeometry(1010, 350, 231, 251) # 设置数字键高度 self.btn_0.setFixedHeight(50) self.btn_1.setFixedHeight(50) self.btn_2.setFixedHeight(50) self.btn_3.setFixedHeight(50) self.btn_4.setFixedHeight(50) self.btn_5.setFixedHeight(50) self.btn_6.setFixedHeight(50) self.btn_7.setFixedHeight(50) self.btn_8.setFixedHeight(50) self.btn_9.setFixedHeight(50) self.btn_del.setFixedHeight(50) # 对数字按键字体大小进行设置 self.btn_1.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_2.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_3.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_4.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_5.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_6.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_7.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_8.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_9.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_0.setStyleSheet("QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 self.btn_del.setStyleSheet( "QPushButton{color:rgb(0,0,0,255);" # 字体颜色为黑色 "font-size:30px;" # 大小为30 "font-family:Roman times;}") # Roman times字体 # 将数字存放进容器 self.gridLayout.addWidget(self.btn_1, 0, 0, 1, 1) self.gridLayout.addWidget(self.btn_2, 0, 1, 1, 1) self.gridLayout.addWidget(self.btn_3, 0, 2, 1, 1) self.gridLayout.addWidget(self.btn_4, 1, 0, 1, 1) self.gridLayout.addWidget(self.btn_5, 1, 1, 1, 1) self.gridLayout.addWidget(self.btn_6, 1, 2, 1, 1) self.gridLayout.addWidget(self.btn_7, 2, 0, 1, 1) self.gridLayout.addWidget(self.btn_8, 2, 1, 1, 1) self.gridLayout.addWidget(self.btn_9, 2, 2, 1, 1) self.gridLayout.addWidget(self.btn_0, 3, 0, 1, 1) self.gridLayout.addWidget(self.btn_del, 3, 1, 1, 2) # 对groupBox进行设置 self.groupBox.setTitle("人员录入管理") GPIO.output(20, GPIO.HIGH) GPIO.output(16, GPIO.HIGH) GPIO.output(12, GPIO.LOW) self.groupBox.setGeometry(990, 40, 281, 310) self.groupBox.setStyleSheet("QGroupBox {\n" "border-width:2px;\n" "border-style:solid;\n" "border-color:lightGray; \n" "font: 75 15pt; font-weight:bold; \n" "margin-top: 0.5ex;\n" "}\n" "QGroupBox::title {\n" "subcontrol-origin: margin;\n" "subcontrol-position: top left;\n" "left:10px;\n" "margin-left: 0px;\n" "padding:0px;\n" "}") # 设置groupBox里面的控件 self.lab_ID.setText("编号") self.lab_ID.setGeometry(10, 40, 61, 41) self.lab_ID.setStyleSheet("font: 15pt;") self.Edit_ID.setGeometry(60, 40, 200, 41) self.Edit_ID.setStyleSheet("font: 15pt;") self.lab2.setText("名称") self.lab2.setGeometry(10, 100, 61, 41) self.lab2.setStyleSheet("font: 15pt;") self.edit2.setGeometry(60, 100, 200, 41) self.edit2.setStyleSheet("font: 15pt;") self.btn_enter.setText("开始录入") self.btn_enter.setGeometry(10, 160, 250, 40) self.btn_enter.setStyleSheet("font: 75 16pt;") self.progressBar.setGeometry(10, 260, 250, 31) # self.progressBar.setProperty("value", 0) self.btn_back.setText("返回") self.btn_back.setGeometry(10, 210, 250, 40) self.btn_back.setStyleSheet("font: 75 16pt;") # 点击数字按钮输入用户名和密码 self.btn_0.clicked.connect(self.slot_btn_0) self.btn_1.clicked.connect(self.slot_btn_1) self.btn_2.clicked.connect(self.slot_btn_2) self.btn_3.clicked.connect(self.slot_btn_3) self.btn_4.clicked.connect(self.slot_btn_4) self.btn_5.clicked.connect(self.slot_btn_5) self.btn_6.clicked.connect(self.slot_btn_6) self.btn_7.clicked.connect(self.slot_btn_7) self.btn_8.clicked.connect(self.slot_btn_8) self.btn_9.clicked.connect(self.slot_btn_9) self.btn_del.clicked.connect(self.slot_btn_del) # 点击返回按键返回上一界面 self.btn_back.clicked.connect(self.slot_btn_back) # 点击数字按钮输入用户名和密码 def slot_btn_0(self): ID_num0 = self.btn_0.text() self.ID_num = self.ID_num + ID_num0 self.Edit_ID.setText(self.ID_num) def slot_btn_1(self): ID_num1 = self.btn_1.text() self.ID_num = self.ID_num + ID_num1 self.Edit_ID.setText(self.ID_num) def slot_btn_2(self): ID_num2 = self.btn_2.text() self.ID_num = self.ID_num + ID_num2 self.Edit_ID.setText(self.ID_num) def slot_btn_3(self): ID_num3 = self.btn_3.text() self.ID_num = self.ID_num + ID_num3 self.Edit_ID.setText(self.ID_num) def slot_btn_4(self): ID_num4 = self.btn_4.text() self.ID_num = self.ID_num + ID_num4 self.Edit_ID.setText(self.ID_num) def slot_btn_5(self): ID_num5 = self.btn_5.text() self.ID_num = self.ID_num + ID_num5 self.Edit_ID.setText(self.ID_num) def slot_btn_6(self): ID_num6 = self.btn_6.text() self.ID_num = self.ID_num + ID_num6 self.Edit_ID.setText(self.ID_num) def slot_btn_7(self): ID_num7 = self.btn_7.text() self.ID_num = self.ID_num + ID_num7 self.Edit_ID.setText(self.ID_num) def slot_btn_8(self): ID_num8 = self.btn_8.text() self.ID_num = self.ID_num + ID_num8 self.Edit_ID.setText(self.ID_num) def slot_btn_9(self): ID_num9 = self.btn_9.text() self.ID_num = self.ID_num + ID_num9 self.Edit_ID.setText(self.ID_num) # 将字符串从最后一位开始删除 def slot_btn_del(self): self.ID_num = self.ID_num[:-1] self.Edit_ID.setText(self.ID_num) # 点击返回按键返回上一界面 def slot_btn_back(self): self.logon = Ui_logon() self.logon.show() self.timer_camera.stop() self.cap.release() self.hide() # 显示人脸识别视频界面 def face_rec(self): if self.timer_camera.isActive() == False: flag = self.cap.open(self.CAM_NUM) if flag == False: msg = QtWidgets.QMessageBox.warning( self, u"Warning", u"请检测相机与电脑是否连接正确", buttons=QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok) else: self.timer_camera.start(30) else: self.timer_camera.stop() self.cap.release() def show_camera(self): flag, self.image = self.cap.read() self.image = cv2.flip(self.image, -1) gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5, minSize=(20, 20)) for (x, y, w, h) in faces: cv2.rectangle(self.image, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gray[y:y + h, x:x + w] roi_color = self.image[y:y + h, x:x + w] # 将视频显示在了label上 show = cv2.resize(self.image, (960, 720)) show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB) showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888) self.lab_face.setPixmap(QtGui.QPixmap.fromImage(showImage)) # 点击按钮开启线程 def slot_btn_enter(self): self.count = 0 self.step = 0 names[int(self.Edit_ID.text())] = self.edit2.text() # 创建线程并开启 self.thread = threading.Thread(target=self.thread_pic) self.thread.start() # 开启进度条定时器 self.timer.start(100, self) # 加载进度条 def timerEvent(self, e): if self.step > 58: self.timer.stop() return self.step = self.count + 1 self.progressBar.setValue(self.count) # 录入人脸线程 def thread_pic(self): print("线程出没!!!") print(self.Edit_ID.text()) # 创建目录,将获取的人脸照片放入指定的文件夹 self.file = "./Face_data/" GPIO.output(20, GPIO.HIGH) GPIO.output(16, GPIO.LOW) GPIO.output(12, GPIO.HIGH) while (True): ret, self.img = self.cap.read() # 垂直翻转视频图像 self.img = cv2.flip(self.img, -1) # 灰度化处理 gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) faces = faceCascade2.detectMultiScale(gray, 1.3, 5) # 判断是否存在文件夹如果不存在则创建为文件夹 self.folder = os.path.exists(self.file) if not self.folder: # makedirs 满权限创建文件时如果路径不存在会创建这个路径 os.makedirs(self.file) os.chmod(self.file, 0777) for (x, y, w, h) in faces: cv2.rectangle(self.img, (x, y), (x + w, y + h), (255, 0, 0), 2) self.count += 1 # 将捕获的图像保存到指定的文件夹中 bool = cv2.imwrite( self.file + "/User." + str(self.Edit_ID.text()) + '.' + str(self.count) + ".png", gray[y:y + h, x:x + w]) # 取60张人脸样本,停止录像 if self.count >= 60: print("OK!") break self.recognizer = cv2.face.createLBPHFaceRecognizer() GPIO.output(20, GPIO.HIGH) GPIO.output(16, GPIO.HIGH) GPIO.output(12, GPIO.LOW) # 函数获取图像和标签数据 def getImagesAndLabels(path): imagePaths = [os.path.join(path, f) for f in os.listdir(path)] faceSamples = [] ids = [] self.progressBar.setProperty("value", 65) for imagePath in imagePaths: # 转换为灰度 PIL_img = Image.open(imagePath).convert('L') img_numpy = np.array(PIL_img, 'uint8') id = int(os.path.split(imagePath)[-1].split(".")[1]) faces = faceCascade3.detectMultiScale(img_numpy) for (x, y, w, h) in faces: faceSamples.append(img_numpy[y:y + h, x:x + w]) ids.append(id) return faceSamples, ids self.progressBar.setProperty("value", 75) print("\n [INFO] Training faces. It will take a few seconds. Wait ...") # 调用函数,传递文件夹路径参数 faces, ids = getImagesAndLabels(self.file) self.recognizer.train(faces, np.array(ids)) self.progressBar.setProperty("value", 85) # 创建文件夹 self.triningfile = "./Face_training/" self.folder1 = os.path.exists(self.triningfile) if not self.folder1: os.makedirs(self.triningfile) os.chmod(self.triningfile, 0777) # 将训练好的数据保存到指定文件夹中 self.recognizer.save(self.triningfile + "/trainer.yml") # 打印经过训练的人脸编号和结束程序 print("\n [INFO] {0} faces trained. Exiting Program".format( len(np.unique(ids)))) self.progressBar.setProperty("value", 100)
class LightMaps(QWidget): def __init__(self, parent=None): super(LightMaps, self).__init__(parent) self.pressed = False self.snapped = False self.zoomed = False self.invert = False self._normalMap = SlippyMap(self) self._largeMap = SlippyMap(self) self.pressPos = QPoint() self.dragPos = QPoint() self.tapTimer = QBasicTimer() self.zoomPixmap = QPixmap() self.maskPixmap = QPixmap() self._normalMap.updated.connect(self.updateMap) self._largeMap.updated.connect(self.update) def setCenter(self, lat, lng): self._normalMap.latitude = lat self._normalMap.longitude = lng self._normalMap.invalidate() self._largeMap.invalidate() # slots def toggleNightMode(self): self.invert = not self.invert self.update() def updateMap(self, r): self.update(r) def activateZoom(self): self.zoomed = True self.tapTimer.stop() self._largeMap.zoom = self._normalMap.zoom + 1 self._largeMap.width = self._normalMap.width * 2 self._largeMap.height = self._normalMap.height * 2 self._largeMap.latitude = self._normalMap.latitude self._largeMap.longitude = self._normalMap.longitude self._largeMap.invalidate() self.update() def resizeEvent(self, event): self._normalMap.width = self.width() self._normalMap.height = self.height() self._normalMap.invalidate() self._largeMap.width = self._normalMap.width * 2 self._largeMap.height = self._normalMap.height * 2 self._largeMap.invalidate() def paintEvent(self, event): p = QPainter() p.begin(self) self._normalMap.render(p, event.rect()) p.setPen(Qt.black) p.drawText( self.rect(), Qt.AlignBottom | Qt.TextWordWrap, "Map data CCBYSA 2009 OpenStreetMap.org contributors", ) p.end() if self.zoomed: dim = min(self.width(), self.height()) magnifierSize = min(MAX_MAGNIFIER, dim * 2 / 3) radius = magnifierSize / 2 ring = radius - 15 box = QSize(magnifierSize, magnifierSize) # reupdate our mask if self.maskPixmap.size() != box: self.maskPixmap = QPixmap(box) self.maskPixmap.fill(Qt.transparent) g = QRadialGradient() g.setCenter(radius, radius) g.setFocalPoint(radius, radius) g.setRadius(radius) g.setColorAt(1.0, QColor(255, 255, 255, 0)) g.setColorAt(0.5, QColor(128, 128, 128, 255)) mask = QPainter(self.maskPixmap) mask.setRenderHint(QPainter.Antialiasing) mask.setCompositionMode(QPainter.CompositionMode_Source) mask.setBrush(g) mask.setPen(Qt.NoPen) mask.drawRect(self.maskPixmap.rect()) mask.setBrush(QColor(Qt.transparent)) mask.drawEllipse(g.center(), ring, ring) mask.end() center = self.dragPos - QPoint(0, radius) center += QPoint(0, radius / 2) corner = center - QPoint(radius, radius) xy = center * 2 - QPoint(radius, radius) # only set the dimension to the magnified portion if self.zoomPixmap.size() != box: self.zoomPixmap = QPixmap(box) self.zoomPixmap.fill(Qt.lightGray) if True: p = QPainter(self.zoomPixmap) p.translate(-xy) self._largeMap.render(p, QRect(xy, box)) p.end() clipPath = QPainterPath() clipPath.addEllipse(QPointF(center), ring, ring) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setClipPath(clipPath) p.drawPixmap(corner, self.zoomPixmap) p.setClipping(False) p.drawPixmap(corner, self.maskPixmap) p.setPen(Qt.gray) p.drawPath(clipPath) if self.invert: p = QPainter(self) p.setCompositionMode(QPainter.CompositionMode_Difference) p.fillRect(event.rect(), Qt.white) p.end() def timerEvent(self, event): if not self.zoomed: self.activateZoom() self.update() def mousePressEvent(self, event): if event.buttons() != Qt.LeftButton: return self.pressed = self.snapped = True self.pressPos = self.dragPos = event.pos() self.tapTimer.stop() self.tapTimer.start(HOLD_TIME, self) def mouseMoveEvent(self, event): if not event.buttons(): return if not self.zoomed: if not self.pressed or not self.snapped: delta = event.pos() - self.pressPos self.pressPos = event.pos() self._normalMap.pan(delta) return else: threshold = 10 delta = event.pos() - self.pressPos if self.snapped: self.snapped &= delta.x() < threshold self.snapped &= delta.y() < threshold self.snapped &= delta.x() > -threshold self.snapped &= delta.y() > -threshold if not self.snapped: self.tapTimer.stop() else: self.dragPos = event.pos() self.update() def mouseReleaseEvent(self, event): self.zoomed = False self.update() def keyPressEvent(self, event): if not self.zoomed: if event.key() == Qt.Key_Left: self._normalMap.pan(QPoint(20, 0)) if event.key() == Qt.Key_Right: self._normalMap.pan(QPoint(-20, 0)) if event.key() == Qt.Key_Up: self._normalMap.pan(QPoint(0, 20)) if event.key() == Qt.Key_Down: self._normalMap.pan(QPoint(0, -20)) if event.key() == Qt.Key_Z or event.key() == Qt.Key_Select: self.dragPos = QPoint(self.width() / 2, self.height() / 2) self.activateZoom() else: if event.key() == Qt.Key_Z or event.key() == Qt.Key_Select: self.zoomed = False self.update() delta = QPoint(0, 0) if event.key() == Qt.Key_Left: delta = QPoint(-15, 0) if event.key() == Qt.Key_Right: delta = QPoint(15, 0) if event.key() == Qt.Key_Up: delta = QPoint(0, -15) if event.key() == Qt.Key_Down: delta = QPoint(0, 15) if delta != QPoint(0, 0): self.dragPos += delta self.update()
class Board(QFrame): msg2Statusbar = pyqtSignal(str) BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): '''初始化 board''' self.timer = QBasicTimer() self.isWaitingAfterLine = False self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() def shapeAt(self, x, y): '''确定 shape at the board 的位置''' return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): '''设置 a shape at the board''' self.board[(y * Board.BoardWidth) + x] = shape def squareWidth(self): '''returns the width of one square''' return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): '''returns the height of one square''' return self.contentsRect().height() // Board.BoardHeight def start(self): '''开始游戏''' if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.newPiece() self.timer.start(Board.Speed, self) def pause(self): '''暂停游戏''' if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.update() def paintEvent(self, event): '''paints all shapes of the game''' painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() for i in range(Board.BoardHeight): for j in range(Board.BoardWidth): shape = self.shapeAt(j, Board.BoardHeight - i - 1) if shape != Tetrominoe.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != Tetrominoe.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare( painter, rect.left() + x * self.squareWidth(), boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): '''processes key press events''' if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(Board, self).keyPressEvent(event) def timerEvent(self, event): '''handles timer event''' if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: super(Board, self).timerEvent(event) def clearBoard(self): '''clears shapes from the board''' for i in range(Board.BoardHeight * Board.BoardWidth): self.board.append(Tetrominoe.NoShape) def dropDown(self): '''drops down a shape''' newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): '''goes one line down with a shape''' if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): '''after dropping shape, remove full lines and create new shape''' for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): '''removes all full lines from the board''' numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() def newPiece(self): '''creates a new shape''' self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over") def tryMove(self, newPiece, newX, newY): '''tries to move a shape''' for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoe.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): '''draws a square of a shape''' colorTable = [ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00 ] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Gui(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): """ Initialises all the widgets as well as the comThread. """ self.tInit = time() #marks the starting time for the tracer hbox = QHBoxLayout(self) p1 = pg.PlotWidget(self) #creates the plot widget topright = QFrame(self) topright.setFrameShape(QFrame.StyledPanel) vbox = QVBoxLayout(topright) #adds a Vertical Box Layout for the topright frame #splits the window in two splitter1 = QSplitter(Qt.Horizontal) splitter1.addWidget(p1) splitter1.addWidget(topright) hbox.addWidget(splitter1) self.setLayout(hbox) # --- initialisation of the topright's widgets ------------------ lbl0 = QLabel(topright) lbl0.setText("Number of photon per seconds") lbl0.adjustSize() self.lcd = QLCDNumber(self) self.lcd.setDigitCount(8) lbl1 = QLabel(topright) lbl1.setText("Size of the acquisition (Ncyc)") lbl1.adjustSize() self.qle = QLineEdit(topright) self.qle.textChanged[str].connect(self.onChanged) self.lbl2 = QLabel(topright) self.lbl2.setText("Estimated Time : ") self.lbl2.adjustSize() self.lbl3 = QLabel(topright) self.lbl3.setText("Size of the acquisition : ") self.lbl3.adjustSize() btn = QPushButton("Acquisition", topright) btn.clicked.connect(self.acquisition) self.pbar = QProgressBar(topright) self.stat_lbl = QLabel(topright) self.stat_lbl.setText("Status : waiting for acquisition") self.stat_lbl.adjustSize() self.fixedScale = False self.btn2 = QPushButton("Fix scale", topright) self.btn2.setCheckable(True) self.btn2.clicked.connect(self.fixScale) self.timeSpan = 5 self.slider = QSlider(Qt.Horizontal, topright) self.slider.setRange(1, 100) self.slider.setInvertedAppearance(True) self.slider.setSingleStep(1) self.slider.setSliderPosition(5) self.slider.valueChanged[int].connect(self.updateTimeScale) self.lbl4 = QLabel(topright) self.lbl4.setText("Time span : 5 s") self.lbl4.adjustSize() self.paused = False btn3 = QPushButton("Pause", topright) btn3.setCheckable(True) btn3.clicked[bool].connect(self.pause) # --- adding to the Vertical Box Layout------------------------- vbox.addWidget(lbl0) vbox.addWidget(self.lcd) vbox.addWidget(lbl1) vbox.addWidget(self.qle) vbox.addWidget(self.lbl2) vbox.addWidget(self.lbl3) vbox.addWidget(btn) vbox.addWidget(self.pbar) vbox.addWidget(self.btn2) vbox.addWidget(self.slider) vbox.addWidget(self.lbl4) vbox.addWidget(btn3) vbox.addWidget(self.stat_lbl) topright.setLayout(vbox) # starting the com thread self.conn = sp.Connection(auto_restart=True).connect(HOST, PORT) self.conn.sendData(b'GIVEDATA') #asks the server to give to chunks of data in advance self.conn.sendData(b'GIVEDATA') # setting the tracer self.timer = QBasicTimer() self.t = np.linspace(0, 0, N_tracer) self.y = np.zeros(N_tracer) self.data = np.zeros(N_tracer) self.curve = p1.plot(pen='y') self.curve.setData(self.t, self.y) p1.setLabel('left', text='Number of photons per {} ms'.format( int(4e-3*BUF))) p1.setLabel('bottom', text='Time', units='s') self.viewBox = p1.getViewBox() self.setGeometry(0, 0, 1200, 600) splitter1.setSizes([1100-150, 150]) self.setWindowTitle('Photon Counting GUI') #self.show() self.showMaximized() self.timer.start(T_timer, self) def onChanged(self, text): """ Provides a guess of the time which the acquisition would take. """ self.lbl2.setText("Estimated Time : "+str(int(eval(text)*BUF*4e-6))+" s") self.lbl2.adjustSize() self.lbl3.setText("Weight of the acquisition : "+str(int(eval(text)*BUF/1000))+" kB") self.lbl3.adjustSize() def pause(self, pressed): if pressed : self.paused = True else : self.paused = False def nbPhoton(self, data, old_data): return (data[0] - old_data) + sum(data[1:]-data[:-1]) def acquisition(self): """ This function handles the acquisition mode. It first stops the timer so that no data is lost to it. Then it retrieves the data from the data_q as fast as possible until it has retrieved Ncyc packets (of size BUF). Then it saves it in an .npy file and finally it restarts the timer. """ Ncyc = int(eval(self.qle.text())) print(Ncyc) self.stat_lbl.setText("Status : acquiring") self.stat_lbl.adjustSize() self.timer.stop() Nstore = BUF*Ncyc store = np.zeros(Nstore,dtype=np.ubyte) for i in range(Ncyc): self.conn.sendData(b'GIVEDATA') store[i*BUF:(i+1)*BUF] = np.frombuffer(self.conn.getData(),dtype=np.ubyte) self.pbar.setValue(int(i/Ncyc*100)) QApplication.processEvents() self.pbar.setValue(100) self.stat_lbl.setText("Status : acquisition complete\n data saved") self.stat_lbl.adjustSize() np.save("data-{}".format(str(datetime.now()).split(".")[0]), store) self.timer.start(T_timer, self) def fixScale(self): if self.fixedScale : self.btn2.setText("Fix scale") else : self.btn2.setText("Unfix scale") self.fixedScale = not self.fixedScale def updateTimeScale(self, value): self.timeSpan = value self.lbl4.setText("Time span : {} s".format(value)) self.lbl4.adjustSize() def timerEvent(self, e): """ Handles the tracer continuous display. It shifts the time and y arrays and it retrieves the new data. It also updates the LCD dispaly. This function is called every T_timer milliseconds. """ self.t[0:-1] = self.t[1:] self.t[-1] = time() - self.tInit old_data = self.data[-1] self.y[0:-1] = self.y[1:] if self.conn.isDataAvailable(): #retrieves the new number of photons self.data = np.frombuffer(self.conn.getData(),dtype=np.ubyte) self.y[-1] = self.nbPhoton(self.data, old_data) self.lcd.display(int(self.y[-1]/(4e-6*BUF))) self.conn.sendData(b'GIVEDATA') #asks for more data else : #makes a constant approximation to ensure fluidity self.y[-1] = self.y[-2] #print(self.y[-1]) if not self.paused : self.curve.setData(self.t, self.y) self.viewBox.setXRange(self.t[-1]-self.timeSpan, self.t[-1]) if not self.fixedScale: i = 0 while self.t[i] < self.t[-1]-self.timeSpan: i += 1 self.viewBox.setYRange(0, max(1,max(self.y[max(0,i-15):]))) def closeEvent(self, event): """ Properly closes the threads and shutting down the server if asked. """ reply = QMessageBox.question(self, 'Message', "Do you want to shutdown the server ?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) self.timer.stop() try : if reply == QMessageBox.Yes: # connects to the server to send the shutdown signal self.conn.sendData('KTHXBYE!'.encode('ascii')) self.conn.disableRestart() sleep(0.2) self.conn.close() print("closing success") except : pass event.accept() #let the process die
class TetrixBoard(QFrame): BoardWidth = 10 BoardHeight = 22 scoreChanged = pyqtSignal(int) levelChanged = pyqtSignal(int) linesRemovedChanged = pyqtSignal(int) def __init__(self, parent=None): super(TetrixBoard, self).__init__(parent) self.timer = QBasicTimer() self.nextPieceLabel = None self.isWaitingAfterLine = False self.curPiece = TetrixPiece() self.nextPiece = TetrixPiece() self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.numPiecesDropped = 0 self.score = 0 self.level = 0 self.board = None self.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() self.nextPiece.setRandomShape() def shapeAt(self, x, y): return self.board[(y * TetrixBoard.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * TetrixBoard.BoardWidth) + x] = shape def timeoutTime(self): return 1000 / (1 + self.level) def squareWidth(self): return self.contentsRect().width() / TetrixBoard.BoardWidth def squareHeight(self): return self.contentsRect().height() / TetrixBoard.BoardHeight def setNextPieceLabel(self, label): self.nextPieceLabel = label def sizeHint(self): return QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2, TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2) def minimumSizeHint(self): return QSize(TetrixBoard.BoardWidth * 5 + self.frameWidth() * 2, TetrixBoard.BoardHeight * 5 + self.frameWidth() * 2) def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.numPiecesDropped = 0 self.score = 0 self.level = 1 self.clearBoard() self.linesRemovedChanged.emit(self.numLinesRemoved) self.scoreChanged.emit(self.score) self.levelChanged.emit(self.level) self.newPiece() self.timer.start(self.timeoutTime(), self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() else: self.timer.start(self.timeoutTime(), self) self.update() def paintEvent(self, event): super(TetrixBoard, self).paintEvent(event) painter = QPainter(self) rect = self.contentsRect() if self.isPaused: painter.drawText(rect, Qt.AlignCenter, "Pause") return boardTop = rect.bottom() - TetrixBoard.BoardHeight * self.squareHeight() for i in range(TetrixBoard.BoardHeight): for j in range(TetrixBoard.BoardWidth): shape = self.shapeAt(j, TetrixBoard.BoardHeight - i - 1) if shape != NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare(painter, rect.left() + x * self.squareWidth(), boardTop + (TetrixBoard.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): if not self.isStarted or self.isPaused or self.curPiece.shape() == NoShape: super(TetrixBoard, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(TetrixBoard, self).keyPressEvent(event) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() self.timer.start(self.timeoutTime(), self) else: self.oneLineDown() else: super(TetrixBoard, self).timerEvent(event) def clearBoard(self): self.board = [NoShape for i in range(TetrixBoard.BoardHeight * TetrixBoard.BoardWidth)] def dropDown(self): dropHeight = 0 newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 dropHeight += 1 self.pieceDropped(dropHeight) def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped(0) def pieceDropped(self, dropHeight): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.numPiecesDropped += 1 if self.numPiecesDropped % 25 == 0: self.level += 1 self.timer.start(self.timeoutTime(), self) self.levelChanged.emit(self.level) self.score += dropHeight + 7 self.scoreChanged.emit(self.score) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 for i in range(TetrixBoard.BoardHeight - 1, -1, -1): lineIsFull = True for j in range(TetrixBoard.BoardWidth): if self.shapeAt(j, i) == NoShape: lineIsFull = False break if lineIsFull: numFullLines += 1 for k in range(TetrixBoard.BoardHeight - 1): for j in range(TetrixBoard.BoardWidth): self.setShapeAt(j, k, self.shapeAt(j, k + 1)) for j in range(TetrixBoard.BoardWidth): self.setShapeAt(j, TetrixBoard.BoardHeight - 1, NoShape) if numFullLines > 0: self.numLinesRemoved += numFullLines self.score += 10 * numFullLines self.linesRemovedChanged.emit(self.numLinesRemoved) self.scoreChanged.emit(self.score) self.timer.start(500, self) self.isWaitingAfterLine = True self.curPiece.setShape(NoShape) self.update() def newPiece(self): self.curPiece = copy.deepcopy(self.nextPiece) self.nextPiece.setRandomShape() self.showNextPiece() self.curX = TetrixBoard.BoardWidth // 2 + 1 self.curY = TetrixBoard.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(NoShape) self.timer.stop() self.isStarted = False def showNextPiece(self): if self.nextPieceLabel is None: return dx = self.nextPiece.maxX() - self.nextPiece.minX() + 1 dy = self.nextPiece.maxY() - self.nextPiece.minY() + 1 pixmap = QPixmap(dx * self.squareWidth(), dy * self.squareHeight()) painter = QPainter(pixmap) painter.fillRect(pixmap.rect(), self.nextPieceLabel.palette().window()) for i in range(4): x = self.nextPiece.x(i) - self.nextPiece.minX() y = self.nextPiece.y(i) - self.nextPiece.minY() self.drawSquare(painter, x * self.squareWidth(), y * self.squareHeight(), self.nextPiece.shape()) painter.end() self.nextPieceLabel.setPixmap(pixmap) def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= TetrixBoard.BoardWidth or y < 0 or y >= TetrixBoard.BoardHeight: return False if self.shapeAt(x, y) != NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Tetris(QMainWindow): def __init__(self): super().__init__() self.isStarted = False self.isPaused = False self.nextMove = None self.lastShape = Shape.shapeNone self.initUI() def initUI(self): self.gridSize = 22 self.speed = 500 self.timer = QBasicTimer() self.setFocusPolicy(Qt.StrongFocus) hLayout = QHBoxLayout() self.tboard = Board(self, self.gridSize) hLayout.addWidget(self.tboard) self.sidePanel = SidePanel(self, self.gridSize) hLayout.addWidget(self.sidePanel) self.statusbar = self.statusBar() self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage) self.start() self.center() self.setWindowTitle('Tetris') self.show() self.setFixedSize(self.tboard.width() + self.sidePanel.width(), self.sidePanel.height() + self.statusbar.height()) def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2) def start(self): if self.isPaused: return self.isStarted = True self.tboard.score = 0 BOARD_DATA.clear() self.tboard.msg2Statusbar.emit(str(self.tboard.score)) BOARD_DATA.createNewPiece() self.timer.start(self.speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.tboard.msg2Statusbar.emit("paused") else: self.timer.start(self.speed, self) self.updateWindow() def updateWindow(self): self.tboard.updateData() self.sidePanel.updateData() self.update() def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if TETRIS_AI and not self.nextMove: self.nextMove = TETRIS_AI.nextMove() if self.nextMove: k = 0 while BOARD_DATA.currentDirection != self.nextMove[0] and k < 4: BOARD_DATA.rotateRight() k += 1 k = 0 while BOARD_DATA.currentX != self.nextMove[1] and k < 5: if BOARD_DATA.currentX > self.nextMove[1]: BOARD_DATA.moveLeft() elif BOARD_DATA.currentX < self.nextMove[1]: BOARD_DATA.moveRight() k += 1 # lines = BOARD_DATA.dropDown() lines = BOARD_DATA.moveDown() self.tboard.score += lines if self.lastShape != BOARD_DATA.currentShape: self.nextMove = None self.lastShape = BOARD_DATA.currentShape self.updateWindow() else: super(Tetris, self).timerEvent(event) def keyPressEvent(self, event): if not self.isStarted or BOARD_DATA.currentShape == Shape.shapeNone: super(Tetris, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: BOARD_DATA.moveLeft() elif key == Qt.Key_Right: BOARD_DATA.moveRight() elif key == Qt.Key_Up: BOARD_DATA.rotateLeft() elif key == Qt.Key_Space: self.tboard.score += BOARD_DATA.dropDown() else: super(Tetris, self).keyPressEvent(event) self.updateWindow()
class ReversiWindow(QMainWindow): def __init__(self, board_size, game_mode, game_difficulty_level, game_time_for_move): super().__init__() self.images = {} self.init_ui(board_size, game_mode, game_difficulty_level, game_time_for_move) def init_ui(self, board_size, game_mode, game_difficulty_level, game_time_for_move): self.game = Game(board_size, mode=game_mode, difficulty_level=game_difficulty_level, is_console_game=False, time_for_move=game_time_for_move) self.game_was_saved = False self.time_for_move = game_time_for_move self.count = self.time_for_move self.timer = QBasicTimer() self.move_timer = QTimer() self.ai_thread = AIThread(self) self.ai_thread.finished.connect(self.ai_finish) self.ai_finished = True self.load_images() self.add_toolbar() self.font_size = 10 self.resize(board_size * s.IMG_SIZE, (board_size * s.IMG_SIZE + self.toolbar.height() + 10 + self.font_size)) self.center() self.setWindowTitle('Reversi') self.show() self.timer.start(1, self) self.move_timer.timeout.connect(self.count_down) self.move_timer.start(1000) def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) def add_toolbar(self): self.toolbar = self.addToolBar('') self.add_toolbar_action(self.toolbar, 'Save', 'save.png', self.save, 'Ctrl+S') self.add_toolbar_action(self.toolbar, 'Undo', 'undo.png', self.undo, 'Ctrl+Z') self.add_toolbar_action(self.toolbar, 'Redo', 'redo.png', self.redo) self.toolbar.setMovable(False) def add_toolbar_action(self, toolbar, name, image, function, shortcut=None): action = QAction(QIcon(QPixmap(self.images[image])), name, self) if shortcut is not None: action.setShortcut(shortcut) action.triggered.connect(function) toolbar.addAction(action) def save(self): if self.game.game_state == Game.States.human: with open('saved_game.pickle', 'wb') as f: pickle.dump(self.game, f, protocol=pickle.HIGHEST_PROTOCOL) self.game_was_saved = True def undo(self): if self.game.game_state == Game.States.human: self.reset_count() self.game.undo() def redo(self): if self.game.game_state == Game.States.human: self.reset_count() self.game.redo() def draw_cell(self, painter, cell): if cell.state == s.BLACK: image = self.images['black.png'] elif cell.state == s.WHITE: image = self.images['white.png'] elif (cell.get_coordinates() in self.game.mover.next_possible_moves and self.game.game_state != Game.States.ai): image = self.images['possible_move.png'] else: image = self.images['empty.png'] painter.drawImage( cell.y*s.IMG_SIZE, cell.x*s.IMG_SIZE + self.toolbar.height() + self.font_size, image) def draw_text(self, painter, font_size): painter.setPen(QColor(Qt.black)) painter.setFont(QFont('Decorative', font_size)) painter.drawText(QPoint(10, self.toolbar.height() + font_size), 'Time left for move: {}'.format(self.count)) def reset_count(self): if not self.ai_thread.isRunning(): self.count = self.time_for_move def count_down(self): if self.count != 0: self.count -= 1 else: if not self.ai_thread.isRunning(): self.game.pass_move() self.reset_count() self.update() def ai_finish(self): self.update() self.reset_count() self.ai_finished = True def load_images(self): images_path = os.path.join(os.getcwd(), 'images') for image in os.listdir(images_path): self.images[image] = QImage(os.path.join(images_path, image)) def mousePressEvent(self, QMouseEvent): if self.game.game_state == Game.States.human: position = QMouseEvent.pos() position.setY( position.y() - self.toolbar.height() - self.font_size) self.game.next_move(position) if self.game.game_state == Game.States.ai: self.reset_count() self.update() def timerEvent(self, event): if self.game.is_over(): self.timer.stop() self.move_timer.stop() self.show_end_of_game_dialog() else: if self.game.game_state == Game.States.ai and self.ai_finished: self.ai_finished = False self.ai_thread.start() self.update() def paintEvent(self, event): with painter(self) as p: for cell in self.game.mover.board.cells(): self.draw_cell(p, cell) self.draw_text(p, self.font_size) def show_end_of_game_dialog(self): message_box = QMessageBox() message_box.setText('The game is over! {}'.format (self.game.get_winner_message())) message_box.exec_() if self.game_was_saved: self.ask_question( 'Do you want to play from your last saved position?', message_box) self.check_answer(message_box.exec_(), self.load_saved_game, self.play_again_action) else: self.play_again_action() def play_again_action(self): message_box = QMessageBox() message_box.setText('Do you want to play again?') self.ask_question('', message_box) self.check_answer(message_box.exec_(), self.restart, self.close) def restart(self): self.game_was_saved = False self.game.restart() self.timer.start(1, self) self.move_timer.start(1000) def load_saved_game(self): with open('saved_game.pickle', 'rb') as f: self.game = pickle.load(f) self.timer.start(1, self) def ask_question(self, question, message_box): message_box.setInformativeText(question) message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) def check_answer(self, clicked_button, yes_action, no_action): if clicked_button == QMessageBox.Yes: yes_action() elif clicked_button == QMessageBox.No: no_action() self.update()
class ScrollArea(QAbstractScrollArea): """A scroll area that supports kinetic scrolling and other features. Instance attributes: kineticscrolling (True): whether the wheel and pgup/pgdn keys etc use kinetic scrolling scrollupdatespersec (50): how many scroll updates to draw per second (50 is recommended). """ kineticscrolling = True scrollupdatespersec = 50 def __init__(self, parent=None, **kwds): super().__init__(parent, **kwds) self._scroller = None self._scrollTimer = QBasicTimer() def wheelEvent(self, ev): if self.kineticscrolling: self.kineticAddDelta(-ev.angleDelta()) else: super().wheelEvent(ev) def keyPressEvent(self, ev): """Kinetic cursor movements.""" hbar = self.horizontalScrollBar() vbar = self.verticalScrollBar() # add Home and End, even in non-kinetic mode scroll = self.kineticScrollBy if self.kineticscrolling else self.scrollBy if ev.key() == Qt.Key_Home: scroll(QPoint(0, -vbar.value())) elif ev.key() == Qt.Key_End: scroll(QPoint(0, vbar.maximum() - vbar.value())) elif self.kineticscrolling: # make arrow keys and PgUp and PgDn kinetic if ev.key() == Qt.Key_PageDown: self.kineticAddDelta(QPoint(0, vbar.pageStep())) elif ev.key() == Qt.Key_PageUp: self.kineticAddDelta(QPoint(0, -vbar.pageStep())) elif ev.key() == Qt.Key_Down: self.kineticAddDelta(QPoint(0, vbar.singleStep())) elif ev.key() == Qt.Key_Up: self.kineticAddDelta(QPoint(0, -vbar.singleStep())) elif ev.key() == Qt.Key_Left: self.kineticAddDelta(QPoint(-hbar.singleStep(), 0)) elif ev.key() == Qt.Key_Right: self.kineticAddDelta(QPoint(hbar.singleStep(), 0)) else: super().keyPressEvent(ev) else: super().keyPressEvent(ev) def scrollOffset(self): """Return the current scroll offset.""" x = self.horizontalScrollBar().value() y = self.verticalScrollBar().value() return QPoint(x, y) def canScrollBy(self, diff): """Does not scroll, but return the actual distance the View would scroll. diff is a QPoint instance. """ hbar = self.horizontalScrollBar() vbar = self.verticalScrollBar() x = min(max(0, hbar.value() + diff.x()), hbar.maximum()) y = min(max(0, vbar.value() + diff.y()), vbar.maximum()) return QPoint(x - hbar.value(), y - vbar.value()) def scrollForDragging(self, pos): """Slowly scroll the View if pos is close to the edge of the viewport. Can be used while dragging things. """ viewport = self.viewport().rect() dx = pos.x() - viewport.left() - 12 if dx >= 0: dx = max(0, pos.x() - viewport.right() + 12) dy = pos.y() - viewport.top() - 12 if dy >= 0: dy = max(0, pos.y() - viewport.bottom() + 12) self.steadyScroll(QPoint(dx*10, dy*10)) def scrollTo(self, pos): """Scroll the View to get pos (QPoint) in the top left corner (if possible). Returns the actual distance moved. """ return self.scrollBy(pos - self.scrollOffset()) def scrollBy(self, diff): """Scroll the View diff pixels (QPoint) in x and y direction. Returns the actual distance moved. """ hbar = self.horizontalScrollBar() vbar = self.verticalScrollBar() x = hbar.value() hbar.setValue(hbar.value() + diff.x()) x = hbar.value() - x y = vbar.value() vbar.setValue(vbar.value() + diff.y()) y = vbar.value() - y return QPoint(x, y) def kineticScrollTo(self, pos): """Scroll the View to get pos (QPoint) in the top left corner (if possible). Returns the actual distance the scroll area will move. """ return self.kineticScrollBy(pos - self.scrollOffset()) def kineticScrollBy(self, diff): """Scroll the View diff pixels (QPoint) in x and y direction. Returns the actual distance the scroll area will move. """ ret = self.canScrollBy(diff) if diff: scroller = KineticScroller() scroller.scrollBy(diff) self.startScrolling(scroller) return ret def kineticAddDelta(self, diff): """Add diff (QPoint) to an existing kinetic scroll. If no scroll is active, a new one is started (like kineticScrollBy). """ if isinstance(self._scroller, KineticScroller): self._scroller.scrollBy(self._scroller.remainingDistance() + diff) else: self.kineticScrollBy(diff) def steadyScroll(self, diff): """Start steadily scrolling diff (QPoint) pixels per second. Stops automatically when the end is reached. """ if diff: self.startScrolling(SteadyScroller(diff, self.scrollupdatespersec)) else: self.stopScrolling() def startScrolling(self, scroller): """Begin a scrolling operation using the specified scroller.""" self._scroller = scroller if not self._scrollTimer.isActive(): self._scrollTimer.start(1000 / self.scrollupdatespersec, self) def stopScrolling(self): """Stop scrolling.""" if self._scroller: self._scrollTimer.stop() self._scroller = None def isScrolling(self): """Return True if a scrolling movement is active.""" return bool(self._scroller) def timerEvent(self, ev): """Called by the _scrollTimer.""" diff = self._scroller.step() # when scrolling slowly, it might be that no redraw is needed if diff: # change the scrollbars, but check how far they really moved. if not self.scrollBy(diff) or self._scroller.finished(): self.stopScrolling()
class GameWindow(QMainWindow): EXIT_CODE_CHANGE_MODE = -123 IMAGE_SIZE = 50 SHIFT = 1 BOT_SPEED = 1 FONT = QFont("times", 20) TIMER_INTERVAL = 100 def __init__(self, *args): super().__init__() self.ICON = QIcon('images/Icon.png') if len(args) < 4: raise ValueError is_new_game = args[0] if is_new_game: if len(args) != 7: raise ValueError self.__game = Game(args[0], args[1], args[2], args[3], args[4]) self.is_online = args[5] self.socket = args[6] else: load_data = args[1].splitlines( ) if args[2] else self.get_file_content(args[1]) self.__game = Game(args[0], load_data) self.is_online = args[2] self.socket = args[4] self.me_first = args[3] self.is_game_over = False self.connection_lost = False self.__turn_thread = None self.end_game_timer = QBasicTimer() self.end_game_timer.start(self.TIMER_INTERVAL, self) self.WIDTH = (self.__game.size + self.SHIFT) * self.IMAGE_SIZE + self.IMAGE_SIZE * 12 self.HEIGHT = (self.__game.size + self.SHIFT * 2) * self.IMAGE_SIZE + 20 self.__log_name = None self.start_logging() self.checkers = copy.deepcopy(self.__game.checkers) self.turn = self.__game.is_white_turn self.score = copy.deepcopy(self.__game.score) self.init_ui() self.show() if self.__game.PLAYER_IS_WHITE and self.__game.bot_active and not self.__game.is_white_turn: self.bot_thread = BotThread(self, self.BOT_SPEED, self.__game) self.bot_thread.start() elif self.is_online and (self.me_first == self.__game.is_white_turn): self.online_thread = OnlineThread(self.__game, self, None, True) self.online_thread.start() else: self.highlight_buttons() def init_ui(self): self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint | Qt.WindowTitleHint) self.set_geometry() self.setWindowIcon(self.ICON) self.setWindowTitle('Reversi') self.setStyleSheet('background: LightBlue;') self.__controls = [] self.__checker_buttons = self.get_checker_buttons() self.__pass_button = self.create_button( 'Pass', (self.__game.size + self.SHIFT) * self.IMAGE_SIZE + 10, (self.SHIFT + self.__game.size - 1) * self.IMAGE_SIZE - 25, lambda: self.make_turn(self.__pass_button)) self.__save_button = self.create_button( 'Save', self.WIDTH - self.IMAGE_SIZE * 7 - 20, 10, self.save) self.__settings_button = self.create_button( 'Settings', self.WIDTH - self.IMAGE_SIZE * 5 - 20, 10, self.settings) self.__restart_button = self.create_button( 'Restart', self.WIDTH - self.IMAGE_SIZE * 3 - 10, 10, partial(self.restart, True)) self.__quit_button = self.create_button( 'Quit', self.WIDTH - self.IMAGE_SIZE - 20, 10, partial(self.quit, True)) @staticmethod def get_file_content(file_name): with open(file_name, 'r') as file: return file.read().splitlines() def copy_game_items(self): self.checkers = copy.deepcopy(self.__game.checkers) self.turn = self.__game.is_white_turn self.score = copy.deepcopy(self.__game.score) def start_logging(self): if not os.path.exists('logs') or not os.path.isdir('logs'): os.mkdir('logs') logs = os.listdir('logs') if len(logs) == 100: os.remove('logs/' + logs[0]) self.__log_name = 'logs/' + datetime.now().strftime( '%Y-%m-%d_%H-%M-%S') + '.txt' game_info = 'Player VS ' difficulty = Game.BOT_DIFFICULTIES[self.__game.BOT_DIFFICULTY] game_info += f'{difficulty} Bot' if self.__game.bot_active else 'Player' game_info += ' (Board size: {0}x{0})'.format(self.__game.size) self.log(game_info) def get_checker_buttons(self): buttons = {} for cell in self.__game.game_map: if cell.coordinates not in self.__game.occupied_coordinates: button = QPushButton('', self) coordinates = cell.coordinates.to_image_coordinates( self.IMAGE_SIZE, self.SHIFT) button.setGeometry(coordinates.x, coordinates.y, self.IMAGE_SIZE, self.IMAGE_SIZE) button.clicked.connect(partial(self.make_turn, button)) button.setStyleSheet("background: transparent;") button.hide() buttons[cell.coordinates.to_tuple()] = button return buttons def create_button(self, name, x, y, action): button = QPushButton(name, self) button.setGeometry(x, y, self.IMAGE_SIZE, self.IMAGE_SIZE) button.clicked.connect(action) button.setStyleSheet("background: transparent; color: transparent;") self.__controls.append(button) return button def set_geometry(self): self.resize(self.WIDTH, self.HEIGHT) qt_rectangle = self.frameGeometry() center_point = QDesktopWidget().availableGeometry().center() qt_rectangle.moveCenter(center_point) self.move(qt_rectangle.topLeft()) self.move(self.x(), self.y() - 15) def save(self): folder = 'online' if self.is_online else 'offline' name = QFileDialog.getSaveFileName(self, 'Save', f'saves/{folder}', 'Save Files (*.save)')[0] if name == '': return False full_name = name if len( name) > 3 and name[-5:] == '.save' else name + '.save' with open(full_name, 'w') as file: text = self.__game.get_save() file.write(text) return True def ask_for_save(self): message = QMessageBox() message.move(self.x() + (self.width() - message.width()) / 2, self.y() + (self.height() - message.height()) / 2) choice = message.question( message, 'Save game?', 'This will finish current game\nWould you like to save yor game?', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, QMessageBox.Cancel) success = choice != QMessageBox.Cancel if choice == QMessageBox.Yes: success = self.save() return success def highlight_buttons(self): for cell in self.__game.game_map: if self.__game.check_turn( cell.coordinates ) and cell.coordinates not in self.__game.occupied_coordinates: cell.highlight() button = self.get_button(cell.coordinates) if button is not None: button.show() self.update() def hide_buttons(self): for cell in self.__game.game_map: cell.normalize() button = self.get_button(cell.coordinates) if button is not None and not button.isHidden(): button.hide() self.update() def log(self, info): if self.__log_name is None: return with open(self.__log_name, 'a') as log_file: log_file.write(f'{datetime.now().strftime("%X")} {info}\n') def settings(self): if not self.ask_for_save(): return qApp.exit(GameWindow.EXIT_CODE_CHANGE_MODE) def restart(self, to_ask): if to_ask and not self.ask_for_save(): return bot_active = self.__game.bot_active size = self.__game.size player_first = self.__game.BOT_IS_WHITE bot_difficulty = self.__game.BOT_DIFFICULTY is_online = self.is_online socket = self.socket self.close() self.destroy() GameWindow(True, size, bot_active, player_first, bot_difficulty, is_online, socket) def quit(self, to_ask): if to_ask and not self.ask_for_save(): return qApp.exit() def timerEvent(self, event): if self.is_game_over or self.connection_lost: self.game_over() def game_over(self): self.end_game_timer.stop() white_won = self.__game.score[Game.WHITE] > self.__game.score[ Game.BLACK] log_color = Game.WHITE if white_won else Game.BLACK if self.__game.bot_active: player, bot = self.get_player_bot_colors() player_won = self.__game.score[player] > self.__game.score[bot] winner = Game.YOU if player_won else Game.BOT log_winner = Game.PLAYER if player_won else Game.BOT else: winner = log_color log_winner = Game.PLAYER is_draw = self.__game.score[Game.WHITE] == self.__game.score[ Game.BLACK] if self.connection_lost: message = 'connection lost' self.log(message) else: message = 'Draw!' if is_draw else '{} won!'.format(winner) self.log('Draw' if is_draw else f'{log_winner} ({log_color}) won') self.create_game_over_window(message) def create_game_over_window(self, message): game_over_window = QMessageBox() game_over_window.setFont(QFont("times", 12)) game_over_window.setWindowIcon(self.ICON) game_over_window.setWindowTitle('Game Over') game_over_window.setText(message) restart = game_over_window.addButton('Restart', QMessageBox.AcceptRole) if self.connection_lost: restart.setEnabled(False) game_over_window.addButton('Quit', QMessageBox.RejectRole) game_over_window.exec() if game_over_window.clickedButton() == restart: self.restart(False) else: self.quit(False) def make_turn(self, button): self.update() if not self.is_online: self.offline_turn(button) else: self.online_turn(button) if self.is_game_over or self.connection_lost: self.game_over() def offline_turn(self, button): self.__turn_thread = TurnThread(self, self.IMAGE_SIZE, self.SHIFT, self.BOT_SPEED, self.__game, self.__pass_button, button) self.__turn_thread.start() def online_turn(self, button): if button == self.__pass_button: coordinates = None else: coordinates = Point(button.x(), button.y()).to_cell_coordinates( self.IMAGE_SIZE, self.SHIFT) self.__turn_thread = OnlineThread(self.__game, self, coordinates) self.__turn_thread.start() def remove_button(self, coordinates): coordinates = coordinates.to_tuple() self.__checker_buttons[coordinates].hide() self.__checker_buttons.pop(coordinates) def get_button(self, coordinates): coordinates = coordinates.to_tuple() if coordinates not in self.__checker_buttons: return None return self.__checker_buttons[coordinates] def get_player_bot_colors(self): if self.__game.PLAYER_IS_WHITE: player = Game.WHITE bot = Game.BLACK else: player = Game.BLACK bot = Game.WHITE return player, bot def paintEvent(self, event): painter = QPainter() painter.begin(self) self.draw_cells(painter) self.draw_signature(painter) self.draw_controls(painter) self.draw_checkers(painter) self.draw_turn(painter) self.draw_score(painter) if self.__game.bot_active: self.draw_bot(painter) painter.end() def draw_controls(self, painter): painter.setFont(self.FONT) for button in self.__controls: painter.drawImage( button.x(), button.y(), QImage(f'images/{button.text()}.png').scaled( self.IMAGE_SIZE, self.IMAGE_SIZE)) painter.drawText(button.x() - self.IMAGE_SIZE / 2, button.y(), self.IMAGE_SIZE * 2, self.IMAGE_SIZE + 30, Qt.AlignCenter | Qt.AlignBottom, button.text()) def draw_bot(self, painter): painter.setFont(self.FONT) difficulty = self.__game.BOT_DIFFICULTIES[self.__game.BOT_DIFFICULTY] painter.drawText((self.SHIFT + 1) * self.IMAGE_SIZE + 10, self.HEIGHT - 10, f'Bot difficulty: {difficulty}') painter.drawImage( self.SHIFT * self.IMAGE_SIZE, self.HEIGHT - self.IMAGE_SIZE - 10, QImage(f'images/{difficulty}.png').scaled(self.IMAGE_SIZE, self.IMAGE_SIZE)) def draw_signature(self, painter): painter.drawText(self.WIDTH - 125, self.HEIGHT - 10, 'Made by Artemiy Izakov') def draw_score(self, painter): painter.setFont(self.FONT) score_table = self.score if self.__game.bot_active else self.__game.score x = (self.__game.size + self.SHIFT) * self.IMAGE_SIZE + 10 y = self.SHIFT * self.IMAGE_SIZE + 20 painter.drawText(x, y, 'Score:') shift = self.IMAGE_SIZE y += 3 painter.drawImage( x, y, Checker.WHITE.scaled(self.IMAGE_SIZE, self.IMAGE_SIZE)) painter.drawImage( x, y + shift, Checker.BLACK.scaled(self.IMAGE_SIZE, self.IMAGE_SIZE)) if not self.__game.bot_active: for color, score in score_table.items(): painter.drawText(x + self.IMAGE_SIZE, y + shift - 15, '{}: {}'.format(color, score)) shift *= 2 else: player, bot = self.get_player_bot_colors() if self.__game.PLAYER_IS_WHITE: painter.drawText(x + self.IMAGE_SIZE, y + shift - 15, f'{Game.YOU}: {score_table[player]}') painter.drawText(x + self.IMAGE_SIZE, y + shift * 2 - 15, f'{Game.BOT}: {score_table[bot]}') else: painter.drawText(x + self.IMAGE_SIZE, y + shift - 15, f'{Game.BOT}: {score_table[bot]}') painter.drawText(x + self.IMAGE_SIZE, y + shift * 2 - 15, f'{Game.YOU}: {score_table[player]}') def draw_turn(self, painter): painter.setFont(self.FONT) is_white_turn = self.turn if self.__game.bot_active else self.__game.is_white_turn if not self.__game.bot_active: if self.is_online: turn = Game.YOU + "r" if self.me_first != is_white_turn else 'Second Player\'s' else: turn = 'First Player\'s' if not is_white_turn else 'Second Player\'s' else: turn = Game.YOU + "r" if is_white_turn == self.__game.PLAYER_IS_WHITE else Game.BOT + "'s" text = fr"{turn} turn" painter.drawText((self.SHIFT + 1) * self.IMAGE_SIZE, 35, text) image = Checker.WHITE if is_white_turn else Checker.BLACK painter.drawImage(self.SHIFT * self.IMAGE_SIZE, 0, image.scaled(self.IMAGE_SIZE, self.IMAGE_SIZE)) def draw_cells(self, painter): for cell in self.__game.game_map: self.draw(cell.image, cell.coordinates, painter) def draw_checkers(self, painter): checkers = self.checkers if self.__game.bot_active else self.__game.checkers for checker in checkers: self.draw(checker.image, checker.coordinates, painter) def draw(self, image, coordinates, painter): image_coordinates = coordinates.to_image_coordinates( self.IMAGE_SIZE, 1) x = image_coordinates.x y = image_coordinates.y painter.drawImage(x, y, image.scaled(self.IMAGE_SIZE, self.IMAGE_SIZE))
class Board(QFrame): """ Main board drawing ambulatory room + animation """ emitText = pyqtSignal(str) refreshRate = 300 board_width = 720 board_height = 560 graph_width = int(board_width / 80) graph_height = int(board_height / 80) tile_size = 80 player_size = 80 move_speed = 20 debug_mode = False right_foot = False player_x = 0 player_y = 160 is_operating = False inference_method = "Regułowe" pathFinding = "aStar" def __init__(self, parent): super().__init__(parent) self.parent = parent # self.initBoard() self.loadPixmaps() self.use_this_pixmap = self.nurse_pixmap # setting logical value for information about animation state self.isStopped = False self.isActive = False self.symptoms = [] # creating empty list of points of size board_width x board_height self.board = [ [ '' for x in range(self.board_width) ] for y in range(self.board_height) ] # creating list of static map objects # PIXMAPs are declared in function self.loadPixmaps() self.objects = { Object("curtain1", (0, 0), (80, 160), 7), Object("bed1", (80, 0), (80, 160), 4), Object("curtain2", (240, 0), (80, 160), 7), Object("bed2", (320, 0), (80, 160), 4), Object("curtain3", (480, 0), (80, 160), 7), Object("bed3", (560, 0), (80, 160), 5), # Object("table_top", (640, 240), (80, 80), 8, 90), Object("table", (640, 400), (80, 80), 9, 90), Object("curtain4", (0, 240), (160, 80), 7, 90), Object("bed4", (0, 320), (160, 80), 6, 270), Object("curtain5", (0, 480), (160, 80), 7, 90), # Object } for obj in self.objects: if obj.getName() == 'bed3' or obj.getName() == 'bed4': obj.changePixmap(4) """ Creating graph to get paths """ self.graph = GridWithWeights(self.graph_width, self.graph_height) self.graph.setWalls(*self.objects) self.path = [] # drawing static objects on map # self.fillBoard(80, 0, 40, 80, 'bed') # creating timer self.timer = QBasicTimer() def diagnose(self): self.is_operating = True get_symptoms_disease_relation_from_rows() if self.inference_method == 'Regułowe': diseases_list = [] symptom_list = [] name = str(randint(0, 1000000)) while (True): self.emitText.emit("Nurse: Co Ci dolega?") while not self.symptoms: time.sleep(0.1) if (self.symptoms): symptom_list.append(self.symptoms) symp = check_knowledge(dict, self.symptoms) print(dict) if (check_knowledge(dict, self.symptoms)): result = check_knowledge(dict, self.symptoms) self.emitText.emit("masz %s ?" % result[0]) self.emitText.emit("Jeśli tak to cierpisz na %s" % result[1]) break diseases_list = Diagnosis.perform_diagnosis(name, self.symptoms) if (len(diseases_list) == 1): break else: self.emitText.emit("--Liczba możliwych chorób to: %s--" % len(diseases_list)) self.symptoms = [] if (diseases_list): self.emitText.emit("%s cierpi na: %s" % (name, diseases_list[0])) key = str(diseases_list[0]) dict.setdefault(key, []) dict.update({key: symptom_list}) self.getPatientOufOf(self.current_bed) self.is_operating = False self.symptoms = [] @pyqtSlot(str) def inferenceEmitted(self, method): self.inference_method = method @pyqtSlot(str) def pathMethod(self, method): if method == "A Star": self.pathFinding = "aStar" elif method == "Dijkstra": self.pathFinding = "dijkstra" @pyqtSlot() def newPatient(self): emptyBeds = self.getEmptyBeds() if emptyBeds: index = randint(0, len(emptyBeds) - 1) self.putPatientInto(emptyBeds[index].getName()) else: self.emitText.emit('Brak wolnych lóżek') @pyqtSlot(str) def textEmitted(self, symptoms): self.symptoms = SymptomLoader.scanInput(symptoms) def loadPixmaps(self): base_dir = os.path.dirname(os.path.abspath(__file__)) base_dir = base_dir[:-4] # tiles = QImage(base_dir + r'/images/40_kafelki.gif') # tiles = QImage(base_dir + r'/images/podloga80x80.png') # tiles = QImage(base_dir + r'/images/podloga1_80x80.png') # tiles = QImage(base_dir + r'/images/podloga2_80x80.png') # tiles = QImage(base_dir + r'/images/podloga3_80x80.png') tiles = QImage(base_dir + r'/images/podloga4_80x80.png') # tiles = QImage(base_dir + r'/images/kafelki.gif') self.tiles_brush = QBrush(tiles) """ self.nurse_pixmap = QPixmap(base_dir + r'/images/nurse_standing40x40.png') """ self.nurse_pixmap = QPixmap(base_dir + r'/images/nurse_standing80x80.png') self.nurse_pixmap_base = self.nurse_pixmap """ self.nurse_left_pixmap = QPixmap(base_dir + r'/images/nurse_left40x40.png') """ self.nurse_left_pixmap = QPixmap(base_dir + r'/images/nurse_left80x80.png') self.nurse_left_pixmap_base = self.nurse_left_pixmap """ self.nurse_right_pixmap = QPixmap(base_dir + r'/images/nurse_right40x40.png') """ self.nurse_right_pixmap = QPixmap(base_dir + r'/images/nurse_right80x80.png') # self.nurse_pixmap = QPixmap(base_dir + # r'/images/nurse_standing40x40.png') # self.nurse_pixmap = QPixmap(base_dir + # r'/images/nurse_standing80x80.png') self.nurse_pixmap = QPixmap(base_dir + r'/images/pigula_koczek80x80.png') self.nurse_pixmap_base = self.nurse_pixmap # self.nurse_left_pixmap = QPixmap(base_dir + # r'/images/nurse_left40x40.png') # self.nurse_left_pixmap = QPixmap(base_dir + # r'/images/nurse_left80x80.png') self.nurse_left_pixmap = QPixmap(base_dir + r'/images/pigula_koczek_lewa80x80.png') self.nurse_left_pixmap_base = self.nurse_left_pixmap # self.nurse_right_pixmap = QPixmap(base_dir + # r'/images/nurse_right40x40.png') # self.nurse_right_pixmap = QPixmap(base_dir + # r'/images/nurse_right80x80.png') self.nurse_right_pixmap = QPixmap(base_dir + r'/images/pigula_koczek_prawa80x80.png') self.nurse_right_pixmap_base = self.nurse_right_pixmap """ self.empty_bed_pixmap = QPixmap(base_dir + r'/images/lozko40x80.gif') """ self.empty_bed_pixmap = QPixmap(base_dir + r'/images/lozko80x160.gif') """ self.girl_alarm_pixmap = QPixmap(base_dir + r'/images/girlAlarm40x80.gif') """ self.girl_alarm_pixmap = QPixmap(base_dir + r'/images/girlAlarm80x160.gif') # self.empty_bed_pixmap = QPixmap(base_dir + # r'/images/lozko40x80.gif') # self.empty_bed_pixmap = QPixmap(base_dir + # r'/images/lozko80x160.gif') self.empty_bed_pixmap = QPixmap(base_dir + r'/images/lozko7_80x160.png') """ self.girl_sleeping_pixmap = QPixmap(base_dir + r'/images/girlSleeping40x80.gif') """ self.girl_sleeping_pixmap = QPixmap(base_dir + r'/images/girlSleeping80x160.gif') # self.girl_sleeping_pixmap = QPixmap(base_dir + # r'/images/girlSleeping40x80.gif') # self.girl_sleeping_pixmap = QPixmap(base_dir + # r'/images/girlSleeping80x160.gif') self.girl_sleeping_pixmap = QPixmap(base_dir + r'/images/lozko7_asleep_80x160.png') # self.table_top_pixmap = QPixmap(base_dir + r'/images/blat40x40.png') self.table_top_pixmap = QPixmap(base_dir + r'/images/blat80x80.png') # self.table_pixmap = QPixmap(base_dir + r'/images/szafka40x40.png') self.table_pixmap = QPixmap(base_dir + r'/images/szafka80x80.png') """ self.curtain_pixmap = QPixmap(base_dir + r'/images/CurtainOnly40x80.gif') self.curtain_pixmap = QPixmap(base_dir + r'/images/CurtainOnly40x160.gif') """ self.curtain_pixmap = QPixmap(base_dir + r'/images/CurtainOnly80x160.gif') # creating dictionary of brushes! self.pixmaps = { 1: self.nurse_pixmap, 2: self.nurse_left_pixmap, 3: self.nurse_right_pixmap, 4: self.empty_bed_pixmap, 5: self.girl_alarm_pixmap, 6: self.girl_sleeping_pixmap, 7: self.curtain_pixmap, 8: self.table_top_pixmap, 9: self.table_pixmap } @pyqtSlot() def start(self): """ Function responsible for preparing animation when start button has been pressed """ if self.isActive: return if self.isStopped: self.isStopped = False self.isActive = True self.timer.start(self.refreshRate, self) @pyqtSlot() def stop(self): """ Function responsible for stoping animation when stop button pressed """ if not self.isActive: return self.isStopped = True self.isActive = False self.timer.stop() self.update() @pyqtSlot(str) def move(self, direction): """ Function responsible for moving main character up. """ self.rotatePlayer(direction) self.fillRealBoard(self.player_x, self.player_y, self.player_size, self.player_size, '') if direction == 'up' and not self.collision(direction): self.makeStep(direction, -self.move_speed) elif direction == 'right' and not self.collision(direction): self.makeStep(direction, self.move_speed) elif direction == 'down' and not self.collision(direction): self.makeStep(direction, self.move_speed) elif direction == 'left' and not self.collision(direction): self.makeStep(direction, -self.move_speed) self.fillRealBoard(self.player_x, self.player_y, self.player_size, self.player_size, 'player') def makeStep(self, direction, distance): # print('distance: ' + str(distance) + '\t 1/4th: ' + str(distance/4)) # determining size of first step (can't be float) half_of_distance = int(distance / 2) # determinig which foot now if self.right_foot: foot_pixmap = self.nurse_left_pixmap else: foot_pixmap = self.nurse_right_pixmap # next time it will be another foot self.right_foot = not self.right_foot if direction in ['up', 'down']: # changing POS_Y self.player_y += half_of_distance self.use_this_pixmap = foot_pixmap self.repaint() time.sleep(0.05) self.player_y += half_of_distance self.use_this_pixmap = self.nurse_pixmap self.repaint() elif direction in ['left', 'right']: # changing POS_X self.player_x += half_of_distance self.use_this_pixmap = foot_pixmap self.repaint() time.sleep(0.05) self.player_x += half_of_distance self.use_this_pixmap = self.nurse_pixmap self.repaint() @pyqtSlot() def debug(self): """ PyQt slot for signal to change map-drawing-mode debug - black background & red objects normal - normal :P """ self.debug_mode = not self.debug_mode def getEmptyBeds(self): emptyBeds = [] for obj in self.objects: if ((obj.getName() == 'bed1' or obj.getName() == 'bed2' or obj.getName() == 'bed3' or obj.getName() == 'bed4') and (obj.getPixmap() is 4)): emptyBeds.append(obj) return emptyBeds def getTakenBeds(self): takenBeds = [] for obj in self.objects: if ((obj.getName() == 'bed1' or obj.getName() == 'bed2' or obj.getName() == 'bed3' or obj.getName() == 'bed4') and (obj.getPixmap() is not 4)): takenBeds.append(obj) return takenBeds def putSleepingPatientInto(self, bed_name): for obj in self.objects: if obj.getName() == bed_name and obj.getPixmap() != 6: obj.changePixmap(6) def putPatientInto(self, bed_name): for obj in self.objects: if obj.getName() == bed_name and obj.getPixmap() != 5: obj.changePixmap(5) def getPatientOufOf(self, bed_name): for obj in self.objects: if obj.getName() == bed_name and obj.getPixmap() != 4: obj.changePixmap(4) def rotatePlayer(self, direction): """ Function responsible for rotating players icon. """ rotation = QTransform() if direction == 'up': rotation.rotate(0) elif direction == 'right': rotation.rotate(90) elif direction == 'down': rotation.rotate(180) elif direction == 'left': rotation.rotate(270) self.use_this_pixmap = \ self.nurse_pixmap_base.transformed(rotation) self.nurse_pixmap = \ self.nurse_pixmap_base.transformed(rotation) self.nurse_left_pixmap = \ self.nurse_left_pixmap_base.transformed(rotation) self.nurse_right_pixmap = \ self.nurse_right_pixmap_base.transformed(rotation) """ self.player_left_brush = QBrush(self.player_left_base.transformed(rotation)) self.player_right_brush = QBrush(self.player_right_base.transformed(rotation)) self.player_brush = QBrush(self.player_image_base.transformed(rotation)) """ def collision(self, direction): """ Main function responsible for collision detection. """ # These -/+ 1 comes from the fact, that we aren't checking # corners but pixels diagonally to the inside of player icon # @@@@@@@@@@@@ # @*@@@@@@@@*@ # @@@@@@@@@@@@ # @@@@@@@@@@@@ # @@@@@@@@@@@@ # @*@@@@@@@@*@ # @@@@@@@@@@@@ # (x1, y1) - TOP LEFT # (x2, y2) - TOP RIGHT if direction == 'up': x1 = self.player_x + 1 y1 = self.player_y - self.move_speed + 1 x2 = self.player_x + self.player_size - 1 y2 = y1 # (x1, y1) - TOP RIGHT # (x2, y2) - BOTTOM RIGHT elif direction == 'right': x1 = self.player_x + self.player_size + self.move_speed - 1 y1 = self.player_y + 1 x2 = x1 y2 = self.player_y + self.player_size - 1 # (x1, y1) - BOTTOM LEFT # (x2, y2) - BOTTOM RIGHT elif direction == 'down': x1 = self.player_x + 1 y1 = self.player_y + self.player_size + self.move_speed - 1 x2 = self.player_x + self.player_size - 1 y2 = y1 # (x1, y1) - TOP LEFT # (x2, y2) - BOTTOM LEFT elif direction == 'left': x1 = self.player_x - self.move_speed + 1 y1 = self.player_y + 1 x2 = x1 y2 = self.player_y + self.player_size - 1 try: # no collision if value is "" (empty string) if self.board[y1][x1] or self.board[y2][x2]: print("Collision! There is: {0} or \ {1}".format(self.board[y1][x1], self.board[y2][x2])) return True elif direction == 'up' and y1 < 0: return True elif direction == 'right' and x1 > self.board_width: return True elif direction == 'down' and y1 > self.board_height: return True elif direction == 'left' and x1 < 0: return True else: return False except IndexError: return True def paintEvent(self, event): painter = QPainter(self) if self.debug_mode: self.drawRealBoard(painter) else: self.drawBoard(painter) self.drawPlayer(painter) self.update() def timerEvent(self, event): """ Overwritten function of timer event """ if event.timerId() == self.timer.timerId(): takenBeds = self.getTakenBeds() if not self.is_operating and takenBeds: self.goToPatient(takenBeds) else: super(Board, self).timerEvent(event) def goToPatient(self, takenBeds): if takenBeds: index = randint(0, len(takenBeds) - 1) x, y = takenBeds[index].getPosition() sizeX, sizeY = takenBeds[index].getSize() pointX = int(x / 80) pointY = int(y / 80) if takenBeds[index].getName() == 'bed4': pointY = int(pointY + sizeY / 80) else: pointX = int(pointX + sizeX / 80) self.current_bed = takenBeds[index].getName() playerX = int(self.player_x / 80) playerY = int(self.player_y / 80) if self.pathFinding == "aStar": cameFrom, costSoFar = self.aStarSearch(self.graph, (playerX, playerY), (pointX, pointY)) elif self.pathFinding == "dijkstra": cameFrom, costSoFar = self.dijkstraSearch(self.graph, (playerX, playerY), (pointX, pointY)) self.path = self.reconstructPath(cameFrom, (playerX, playerY), (pointX, pointY)) if playerX is pointX and playerY is pointY: self.is_operating = True diagnoseThread = threading.Thread(target=self.diagnose) diagnoseThread.start() else: self.movePlayer() def movePlayer(self): pathToMove = self.path[1:] for nextPointX, nextPointY in pathToMove: nextPointX = nextPointX * 80 nextPointY = nextPointY * 80 if self.player_x < nextPointX: while self.player_x < nextPointX: self.move('right') elif self.player_x > nextPointX: while self.player_x > nextPointX: self.move('left') elif self.player_y < nextPointY: while self.player_y < nextPointY: self.move('down') elif self.player_y > nextPointY: while self.player_y > nextPointY: self.move('up') def drawBoard(self, painter): """ Main function for QPainter """ # drawing tiles painter.setBrush(self.tiles_brush) painter.drawRect( 0, 0, self.board_width, self.board_height ) self.drawObjects(painter) def drawObjects(self, painter): """ Drawing objects like bed or curtain on map. """ # reminder: # obj = [(pos_x, pos_y), (width, height), PIXMAP, ROTATION_ANGLE] for obj in self.objects: if obj.getAngle() != 0: rotation = QTransform() rotation.rotate(obj.getAngle()) pixmap = self.pixmaps[obj.getPixmap()].transformed(rotation) else: pixmap = self.pixmaps[obj.getPixmap()] state = obj.getState() painter.drawPixmap( state[0], # pos_x state[1], # pos_y state[2], # width state[3], # height pixmap ) # Drawing path - delete when not needed for (x, y) in self.path: painter.setPen(Qt.red) painter.drawRect(x * 80, y * 80, 80, 80) self.fillRealBoard( state[0], # pos_x state[1], # pos_y state[2], # width state[3], # height obj.getName() ) def fillRealBoard(self, start_x, start_y, width, height, content): for y in range(start_y, start_y + height): for x in range(start_x, start_x + width): self.board[y][x] = content """ print('filling board from {0} to {1} and \ from {2} to {3} with {4}'.format(start_x, width, start_y, height, content)) """ def drawRealBoard(self, painter): """ Only for debug, prints self.board pixel by pixel """ for y in range(self.board_height): for x in range(self.board_width): if self.board[y][x] != '': print(str(x) + 'x' + str(y) + ' - ' + str(self.board[y][x])) painter.setPen(Qt.red) painter.drawRect(x, y, 1, 1) else: painter.setPen(Qt.black) painter.drawRect(x, y, 1, 1) self.update() def drawPlayer(self, painter): painter.drawPixmap( self.player_x, self.player_y, self.player_size, self.player_size, self.use_this_pixmap ) def heuristic(self, a, b): (x1, y1) = a (x2, y2) = b return abs(x1 - x2) + abs(y1 - y2) def dijkstraSearch(self, graph, start, goal): """ Algorytm Dijkstry """ steps = PriorityQueue() steps.put(start, 0) cameFrom = {} costSoFar = {} cameFrom[start] = None costSoFar[start] = 0 # dopoki cos w liscie krokow while not steps.empty(): # pozyskaj miejsce, w ktorym jestes current = steps.get() # jesli dotarles do celu, to przerwij if current == goal: break # dla kazdego z sasiadow for next in graph.neighbours(current): # oblicz nowy koszt dojscia (dotychczasowy + do sasiada) newCost = costSoFar[current] + graph.cost(current, next) # jezeli koszt nie istnial wczesniej # lub jest nizszy niz poprzednik # to umiesc go w liscie kosztow do nastepnego kroku if next not in costSoFar or newCost < costSoFar[next]: costSoFar[next] = newCost # jako priorytet ustaw koszt priority = newCost steps.put(next, priority) cameFrom[next] = current # zwroc koszt dojscia i liste krokow (lista od konca) return cameFrom, costSoFar def aStarSearch(self, graph, start, goal): frontier = PriorityQueue() frontier.put(start, 0) came_from = {} cost_so_far = {} came_from[start] = None cost_so_far[start] = 0 while not frontier.empty(): current = frontier.get() if current == goal: break for next in graph.neighbours(current): new_cost = cost_so_far[current] + graph.cost(current, next) if next not in cost_so_far or new_cost < cost_so_far[next]: cost_so_far[next] = new_cost priority = new_cost + self.heuristic(goal, next) frontier.put(next, priority) came_from[next] = current return came_from, cost_so_far def reconstructPath(self, came_from, start, goal): current = goal path = [current] while current != start: current = came_from[current] path.append(current) path.reverse() return path def draw_tile(self, graph, id, style, width): r = "." if 'number' in style and id in style['number']: r = "%d" % style['number'][id] if ('point_to' in style and style['point_to'].get(id, None) is not None): (x1, y1) = id (x2, y2) = style['point_to'][id] if x2 == x1 + 1: r = "\u2192" if x2 == x1 - 1: r = "\u2190" if y2 == y1 + 1: r = "\u2193" if y2 == y1 - 1: r = "\u2191" if 'start' in style and id == style['start']: r = "A" if 'goal' in style and id == style['goal']: r = "Z" if 'path' in style and id in style['path']: r = "@" if id in graph.walls: r = "#" * width return r def draw_grid(self, graph, width=2, **style): for y in range(graph.height): for x in range(graph.width): print("%%-%ds" % width % self.draw_tile(graph, (x, y), style, width), end="") print() @pyqtSlot(str) def goTo(self, position): x, y = position.split() pointX = int(int(x) / 80) pointY = int(int(y) / 80) playerX = int(self.player_x / 80) playerY = int(self.player_y / 80) if self.pathFinding == "aStar": cameFrom, costSoFar = self.aStarSearch(self.graph, (playerX, playerY), (pointX, pointY)) elif self.pathFinding == "dijkstra": cameFrom, costSoFar = self.dijkstraSearch(self.graph, (playerX, playerY), (pointX, pointY)) self.path = self.reconstructPath(cameFrom, (playerX, playerY), (pointX, pointY)) self.movePlayer()
class GUIBasic(QWidget): def __init__(self): super().__init__() self.model = None def init_ui(self): self.resize(1200, 680) self.pic_list = ['maze7_1', 'maze7_2', 'maze7_3', 'maze10_1', 'maze10_2', 'maze10_3', 'maze11_1'] self.timer = QBasicTimer() widget1 = QWidget(parent=self) widget1.setGeometry(QRect(30, 50, 800, 500)) table_area = QGroupBox(parent=widget1) # 图形显示区域 table_area.setGeometry(QRect(widget1.x(), widget1.y(), widget1.width(), widget1.height())) self.Plot = DrawUI(width=3, height=3, dpi=100) gridlayout1 = QGridLayout(table_area) # 继承容器groupBox gridlayout1.addWidget(self.Plot, 0, 1) pic_choose_label = QLabel(self) pic_choose_label.move(table_area.x() + table_area.width(), table_area.y() + 80) pic_choose_label.setText("Choose Maze:") pic_choose_label.setFont(QFont("Fixed", 10)) self.pic_choose_combo = QComboBox(self) self.pic_choose_combo.move(pic_choose_label.geometry().x() + pic_choose_label.geometry().width() + 30, pic_choose_label.geometry().y() - 8) self.pic_choose_combo.resize(100, self.pic_choose_combo.geometry().height()) self.pic_choose_combo.addItems(self.pic_list) self.pic_choose_combo.currentIndexChanged.connect(self.pic_change) self.pic_choose_combo.setFont(QFont("Fixed", 10)) self.pic_change() middle_x = ( pic_choose_label.geometry().x() + self.pic_choose_combo.geometry().x() + self.pic_choose_combo.geometry().width()) / 2 self.playing_index = -1 self.problem_solving = False self.solve_problem_button = QPushButton(parent=self) self.solve_problem_button.setText("Train Now") self.solve_problem_button.move(pic_choose_label.geometry().x() + pic_choose_label.geometry().width() + 30, self.pic_choose_combo.y() + self.pic_choose_combo.height() + 100) self.solve_problem_button.pressed.connect(self.solve_button_pressed) self.solve_problem_button.setFont(QFont("Fixed", 10)) self.solve_test = QLabel(parent=self) # 解答过程中的信息显示 self.solve_test.setText("Training...") self.solve_test.resize(400, self.solve_test.height()) self.solve_test.setFont(QFont("Fixed", 9)) self.solve_test.move(table_area.x() + table_area.width() - 20, self.solve_problem_button.geometry().y() + self.solve_problem_button.geometry().height() + 20) self.solve_test.setHidden(True) speed_choose_label = QLabel(self) speed_choose_label.move(table_area.x() + table_area.width(), self.solve_test.geometry().y() + 40) speed_choose_label.setText("Play Speed:") speed_choose_label.setFont(QFont("Fixed", 10)) self.play_speed_combo = QComboBox(self) self.play_speed_combo.move(speed_choose_label.geometry().x() + speed_choose_label.geometry().width() + 30, speed_choose_label.geometry().y() - 2) self.play_speed_combo.addItems(["High", "Middle", "Low"]) self.play_speed_combo.setFont(QFont("Fixed", 10)) play_button = QPushButton(self) play_button.setText("Play Result Now!") play_button.move(pic_choose_label.geometry().x() + pic_choose_label.geometry().width() + 30, self.play_speed_combo.geometry().y() + self.play_speed_combo.geometry().height() + 40) play_button.pressed.connect(self.play_button_pressed) play_button.setFont(QFont("Fixed", 10)) def pic_change(self): self.timer.stop() current_text = self.pic_choose_combo.currentText() maze = Mazes[current_text] my_maze = Maze(maze_map=np.array(maze), period=2) self.model = QTableModel(my_maze) # try: # self.model.load_table('./Saved_QTable/' + current_text + '.npy') # except: # QMessageBox.information(self, "提示", "没找到Q表保存文件", QMessageBox.Ok | QMessageBox.Close, # QMessageBox.Close) self.model.play_game((0, 0), 0) self.Plot.draw_root(self.model.my_maze, (0, 0), 1, 0, False) self.Plot.draw_qtable(qtable_model=self.model, time_=self.model.my_maze.period - 1 if self.model.my_maze.period != 0 else 0, fire_flag=True) def play_button_pressed(self): if self.model == None: QMessageBox.information(self, "Tip", "Please choose the Maze first.", QMessageBox.Ok | QMessageBox.Close, QMessageBox.Close) return self.model.play_game((0, 0), 0) speed_text = self.play_speed_combo.currentText() self.playing_index = 0 if speed_text == "High": self.timer.start(100, self) elif speed_text == "Middle": self.timer.start(500, self) else: self.timer.start(1500, self) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): period = self.model.my_maze.period if period != 0 and (self.playing_index % period) >= period / 2: fire_flag = True else: fire_flag = False self.Plot.draw_qtable(self.model, self.playing_index % period if period != 0 else 0, fire_flag) self.Plot.draw_root(self.model.my_maze, (0, 0), self.playing_index, period, fire_flag) self.playing_index = self.playing_index + 1 if self.playing_index >= len(self.model.my_maze.visited) + 2: self.playing_index = 0 # print("up",self.playing_index) else: super(GUIBasic, self).timerEvent(event) def solve_button_pressed(self): if self.problem_solving: return if type(self.model) == type(None): QMessageBox.information(self, "Tip", "Please choose the Maze first.", QMessageBox.Ok | QMessageBox.Close, QMessageBox.Close) return self.problem_solving = True self.playing_index = -1 self.solve_test.setHidden(False) self.timer.stop() self.repaint() start_time = time.time() # path = "tangrams\\" + self.parent().pic_choose_combo.currentText() + ".png" self.model.train(output_line=self.solve_test, main_ui=self) end_time = time.time() QMessageBox.information(self, "Tip", "Training finished,spend:%.3f s" % (end_time - start_time), QMessageBox.Ok | QMessageBox.Close, QMessageBox.Close) self.Plot.draw_qtable(qtable_model=self.model, time_=self.model.my_maze.period - 1 if self.model.my_maze.period != 0 else 0, fire_flag=True) self.problem_solving = False self.solve_test.setHidden(True)
class Board(QFrame): msg2Statusbar = pyqtSignal(str) BoardWidth = 10 BoardHeight = 22 Speed = 300 def __init__(self, parent): super().__init__(parent) self.initBoard() def initBoard(self): self.timer = QBasicTimer() self.isWaitingAfterLine = False self.curX = 0 self.curY = 0 self.numLinesRemoved = 0 self.board = [] self.setFocusPolicy(Qt.StrongFocus) self.isStarted = False self.isPaused = False self.clearBoard() def shapeAt(self, x, y): return self.board[(y * Board.BoardWidth) + x] def setShapeAt(self, x, y, shape): self.board[(y * Board.BoardWidth) + x] = shape def squareWidth(self): return self.contentsRect().width() // Board.BoardWidth def squareHeight(self): return self.contentsRect().height() // Board.BoardHeight def start(self): if self.isPaused: return self.isStarted = True self.isWaitingAfterLine = False self.numLinesRemoved = 0 self.clearBoard() self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.newPiece() self.timer.start(Board.Speed, self) def pause(self): if not self.isStarted: return self.isPaused = not self.isPaused if self.isPaused: self.timer.stop() self.msg2Statusbar.emit("paused") else: self.timer.start(Board.Speed, self) self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.update() def paintEvent(self, event): painter = QPainter(self) rect = self.contentsRect() boardTop = rect.bottom() - Board.BoardHeight * self.squareHeight() for i in range(Board.BoardHeight): for j in range(Board.BoardWidth): shape = self.shapeAt(j, Board.BoardHeight - i - 1) if shape != Tetrominoe.NoShape: self.drawSquare(painter, rect.left() + j * self.squareWidth(), boardTop + i * self.squareHeight(), shape) if self.curPiece.shape() != Tetrominoe.NoShape: for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.drawSquare(painter, rect.left() + x * self.squareWidth(), boardTop + (Board.BoardHeight - y - 1) * self.squareHeight(), self.curPiece.shape()) def keyPressEvent(self, event): if not self.isStarted or self.curPiece.shape() == Tetrominoe.NoShape: super(Board, self).keyPressEvent(event) return key = event.key() if key == Qt.Key_P: self.pause() return if self.isPaused: return elif key == Qt.Key_Left: self.tryMove(self.curPiece, self.curX - 1, self.curY) elif key == Qt.Key_Right: self.tryMove(self.curPiece, self.curX + 1, self.curY) elif key == Qt.Key_Down: self.tryMove(self.curPiece.rotateRight(), self.curX, self.curY) elif key == Qt.Key_Up: self.tryMove(self.curPiece.rotateLeft(), self.curX, self.curY) elif key == Qt.Key_Space: self.dropDown() elif key == Qt.Key_D: self.oneLineDown() else: super(Board, self).keyPressEvent(event) def timerEvent(self, event): if event.timerId() == self.timer.timerId(): if self.isWaitingAfterLine: self.isWaitingAfterLine = False self.newPiece() else: self.oneLineDown() else: super(Board, self).timerEvent(event) def clearBoard(self): for i in range(Board.BoardHeight * Board.BoardWidth): self.board.append(Tetrominoe.NoShape) def dropDown(self): newY = self.curY while newY > 0: if not self.tryMove(self.curPiece, self.curX, newY - 1): break newY -= 1 self.pieceDropped() def oneLineDown(self): if not self.tryMove(self.curPiece, self.curX, self.curY - 1): self.pieceDropped() def pieceDropped(self): for i in range(4): x = self.curX + self.curPiece.x(i) y = self.curY - self.curPiece.y(i) self.setShapeAt(x, y, self.curPiece.shape()) self.removeFullLines() if not self.isWaitingAfterLine: self.newPiece() def removeFullLines(self): numFullLines = 0 rowsToRemove = [] for i in range(Board.BoardHeight): n = 0 for j in range(Board.BoardWidth): if not self.shapeAt(j, i) == Tetrominoe.NoShape: n = n + 1 if n == 10: rowsToRemove.append(i) rowsToRemove.reverse() for m in rowsToRemove: for k in range(m, Board.BoardHeight): for l in range(Board.BoardWidth): self.setShapeAt(l, k, self.shapeAt(l, k + 1)) numFullLines = numFullLines + len(rowsToRemove) if numFullLines > 0: self.numLinesRemoved = self.numLinesRemoved + numFullLines self.msg2Statusbar.emit(str(self.numLinesRemoved)) self.isWaitingAfterLine = True self.curPiece.setShape(Tetrominoe.NoShape) self.update() def newPiece(self): self.curPiece = Shape() self.curPiece.setRandomShape() self.curX = Board.BoardWidth // 2 + 1 self.curY = Board.BoardHeight - 1 + self.curPiece.minY() if not self.tryMove(self.curPiece, self.curX, self.curY): self.curPiece.setShape(Tetrominoe.NoShape) self.timer.stop() self.isStarted = False self.msg2Statusbar.emit("Game over") def tryMove(self, newPiece, newX, newY): for i in range(4): x = newX + newPiece.x(i) y = newY - newPiece.y(i) if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight: return False if self.shapeAt(x, y) != Tetrominoe.NoShape: return False self.curPiece = newPiece self.curX = newX self.curY = newY self.update() return True def drawSquare(self, painter, x, y, shape): colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.lighter()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.darker()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
class Application(QMainWindow): def __init__(self, caption, w, h, offset, tex, levels, music, bonuses, modes): """ Initialize Game Application """ self.modes = modes self.mode = modes[0] super().__init__() self.caption = caption self.size = (w, h) self.setFixedSize(w, h) self.pressed_keys = { 'K_RIGHT': False, 'K_LEFT': False, 'K_A': False, 'K_D': False } self.levels = levels self.level = levels[0] self.frame_delta = 16 self.timer = QBasicTimer() self.offset = offset self.level_window = LevelWindow(self) self.header = HeaderWindow(self) self.tex = tex self.drawer = Drawer(self.level_window, self.header, tex.balls, tex.others, self.level.mode, bonuses) self.mute = False self.music = music self.help = HelpWindow(w / 1.5, h / 2) self.level_select = LevelSelectWindow(self) self.main_menu = MenuWindow(self, self.level.mode) self.score_window = ScoreWindow(self) self.show() self.main_menu.show() self.update_title() self.music.play_bg() self.save = None self.load_save() def mute_music(self): """ Mute / unmute ingame sounds """ if self.mute: self.music.unmute() self.main_menu.mute.setText(' 🔊') self.music.play_bg() self.mute = False else: self.music.mute() self.main_menu.mute.setText(' 🔇') self.mute = True def save_levels(self): """ Saves current highscores in files """ save_levels(self.levels) def switch_modes(self): """ Changes mode to next one """ index = self.modes.index(self.mode) index = (index + 1) % len(self.modes) self.mode = self.modes[index] self.music.switch(self.mode, self.mute) for i in range(len(self.levels)): self.levels[i].ball_amount = self.levels[i].types[self.mode] self.levels[i].mode = self.mode self.levels[i].p.mode = self.mode self.levels[i].p.refill_balls() self.drawer.mode = self.mode def got_to_main(self): """ Closes level-select menu and opening Main one """ if not self.mute: self.music.play_bg() self.level_select.hide() self.score_window.hide() self.main_menu.show() def save_current_game(self): """ Saves current level condition in save.pickle """ with open('save.pickle', 'wb') as f: pickle.dump(self.level, f) def load_save(self): """ Loads saved game if it exists """ with open('save.pickle', 'rb') as f: self.save = pickle.load(f) if self.save is not None: self.main_menu.switch_play_mode() self.level = self.save for i in range(len(self.levels)): if self.levels[i].caption == self.save.caption: self.levels[i] = self.save return def start(self, level_id): """ Prepare level environment and then start the GAME level_id used to choose, which level we want to run """ self.level = self.levels[level_id] self.drawer.mode = self.mode self.level.score = 0 self.tex.scale_balls(self.level.r) self.show() self.drawer.init_level(self.size[0], self.size[1], self.offset, self.level.tex_name) self.level_window.show() self.level_window.lower() self.header.show() self.level.p.refill_balls() self.timer.start(self.frame_delta, self) def resume(self): """ Resume current level """ self.tex.scale_balls(self.level.r) self.drawer.init_level(self.size[0], self.size[1], self.offset, self.level.tex_name) self.drawer.mode = self.level.mode for ball in self.level.balls: if ball.status == 1: ball.status = 0 elif ball.status == 3: ball.status = 4 for bull in self.level.p.bullets: if bull[0].status == 1: bull[0].status = 0 elif bull[0].status == 3: bull[0].status = 4 self.level.p.first.status = 0 self.level.p.second.status = 0 self.drawer.labels.clear() self.level_window.show() self.level_window.lower() self.header.show() self.main_menu.hide() self.level_select.hide() self.timer.start(self.frame_delta, self) def restart(self): """ Restarts current game """ if not self.mute: self.music.play_bg() self.finish_game() level_id = self.levels.index(self.level) self.start(level_id) def finish_game(self): """ Stops the game and clean all visual trash, which is left from previous game. """ self.timer.stop() self.level.amount = self.level.ball_count self.level_window.deleteLater() self.level_window = LevelWindow(self) self.drawer.labels.clear() self.drawer.parent = self.level_window self.drawer.bg = None self.level.balls.clear() self.level.p.bullets.clear() def timerEvent(self, event): """ Running every frame and update game and drawing condition """ if self.level.finished: self.update_title() self.timer.stop() self.score_window.update_highscores(self.level.highscores) self.music.stop_bg() if not self.mute: if self.level.won: self.music.win() else: self.music.loose() self.score_window.update_title(self.level.won) self.score_window.show() self.main_menu.reset_save() if not self.main_menu.cont.isHidden(): self.main_menu.switch_play_mode() self.level.finished = False self.level.score = 0 self.level.won = False return self.keyHoldEvent() self.level.update(self.frame_delta / 1000) if self.mute: self.level.music_queue.clear() else: self.music.handle_events(self.level.music_queue) self.level.music_queue.clear() self.drawer.update_header(self.level.caption, self.level.score) self.update_title() self.drawer.draw_frame(self.level) self.level.clear_trash() def update_title(self): """ Updates game title """ win_cond = '' if self.level.finished: if self.level.won: win_cond = ' YOU WON! ' else: win_cond = ' YOU LOST! GAME IS OVER... ' title = '{0} {1}'.format(self.caption, win_cond) self.setWindowTitle(title) def mousePressEvent(self, event): """ Handles mouse press events """ if event.button() == Qt.LeftButton: pos = (event.x(), event.y() - self.offset) angle = engine.get_angle(self.level.p.pos, pos) self.level.p.set_rotation(math.pi * 2 - angle) if not self.level_window.isHidden() and \ len(self.level.come_back) == 0: self.level.p.shoot() if not self.mute: self.music.shoot() def closeEvent(self, event): """ Handles app closing event """ self.save_levels() if not self.level_window.isHidden(): self.save_current_game() self.help.hide() print('Зочем закрыл? Открой абратна,' + 'а то Стасян уже выехал за тобой!))0)') def keyPressEvent(self, event): """ Handles key pressing events """ key = event.key() if key == Qt.Key_Left: self.pressed_keys['K_LEFT'] = True elif key == Qt.Key_A: self.pressed_keys['K_A'] = True elif key == Qt.Key_Right: self.pressed_keys['K_RIGHT'] = True elif key == Qt.Key_D: self.pressed_keys['K_D'] = True elif key == Qt.Key_Escape: self.score_window.hide() if not self.level_window.isHidden(): self.save_current_game() self.save = self.level self.main_menu.switch_play_mode() self.timer.stop() self.level_window.deleteLater() self.level_window = LevelWindow(self) self.drawer.labels.clear() self.drawer.parent = self.level_window self.drawer.bg = None self.level_window.hide() self.main_menu.show() elif not self.level_select.isHidden(): self.level_select.hide() self.main_menu.show() elif not self.main_menu.isHidden(): self.save_levels() self.help.hide() sys.exit() elif key == Qt.Key_Space or key == Qt.Key_Up: if not self.level_window.isHidden() and \ len(self.level.come_back) == 0: self.level.p.shoot() if not self.mute: self.music.shoot() elif key == Qt.Key_X or key == Qt.Key_Down: if not self.level_window.isHidden(): self.level.p.swap() if not self.mute: self.music.swap() def keyReleaseEvent(self, event): """ Handles key releasing events """ key = event.key() if key == Qt.Key_Left: self.pressed_keys['K_LEFT'] = False elif key == Qt.Key_A: self.pressed_keys['K_A'] = False elif key == Qt.Key_Right: self.pressed_keys['K_RIGHT'] = False elif key == Qt.Key_D: self.pressed_keys['K_D'] = False def keyHoldEvent(self): """ Handles holding keys events """ if self.pressed_keys['K_RIGHT'] or self.pressed_keys['K_D']: self.level.p.rotate(-self.level.rot) elif self.pressed_keys['K_LEFT'] or self.pressed_keys['K_A']: self.level.p.rotate(self.level.rot)
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # checkbox cb = QCheckBox('show title', self) cb.move(20, 20) cb.toggle() cb.stateChanged.connect(self.changeTitle) # toggle button self.col = QColor(0, 0, 0) redb = QPushButton('red', self) redb.setCheckable(True) redb.move(20, 40) redb.clicked[bool].connect(self.setColor) greenb = QPushButton('green', self) greenb.setCheckable(True) greenb.move(20, 60) greenb.clicked[bool].connect(self.setColor) blueb = QPushButton('blue', self) blueb.setCheckable(True) blueb.move(20, 80) blueb.clicked[bool].connect(self.setColor) self.square = QFrame(self) self.square.setGeometry(150, 20, 100, 100) self.square.setStyleSheet('QWidget {background-color: %s}' % self.col.name()) # slider sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) sld.setGeometry(20, 160, 100, 20) sld.valueChanged[int].connect(self.changeValue) self.label = QLabel('0', self) self.label.setGeometry(140, 155, 80, 30) # progressbar self.pbar = QProgressBar(self) self.pbar.setGeometry(20, 200, 200, 25) self.btn = QPushButton('start', self) self.btn.move(20, 230) self.btn.clicked.connect(self.doAction) self.timer = QBasicTimer() self.step = 0 # calendar cal = QCalendarWidget(self) cal.setGridVisible(True) cal.move(20, 300) cal.clicked[QDate].connect(self.showDate) self.lbl = QLabel(self) date = cal.selectedDate() self.lbl.setText(date.toString()) self.lbl.move(20, 280) self.setGeometry(300, 300, 400, 550) self.setWindowTitle('widgets') self.show() def showDate(self, date): self.lbl.setText(date.toString()) def timerEvent(self, e): if self.step >= 100: self.timer.stop() self.btn.setText('finished') return self.step = self.step + 1 self.pbar.setValue(self.step) def doAction(self): if self.timer.isActive(): self.timer.stop() else: self.timer.start(100, self) self.btn.setText('stop') def changeValue(self, value): self.label.setText(str(value)) def setColor(self, pressed): source = self.sender() if pressed: val = 255 else: val = 0 if source.text() == 'red': self.col.setRed(val) elif source.text() == 'green': self.col.setGreen(val) else: self.col.setBlue(val) self.square.setStyleSheet('QFrame {background-color: %s}' % self.col.name()) def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('widgets') else: self.setWindowTitle('')
class HAdjustmentBar(QWidget): valueChanged = pyqtSignal(int) def __init__(self, parent=None): super(HAdjustmentBar, self).__init__(parent) self.value = 50 self.step = 1 self.hi_value = 100 self.low_value = 50 self.timer_value = 100 self.texttemplate = 'Value = %s' self.timer = QBasicTimer() self.showToggleButton = True self.showSettingMenu = True self.bar = LabeledBar() #self.bar.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) # black magic class patching # so calling these functions actually calls the self.bar's functions. self.minimum = self.bar.minimum self.maximum = self.bar.maximum def buildWidget(self): layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) SettingMenu = QMenu() exitButton = QAction(QIcon('exit24.png'), 'Set As High', self) exitButton.triggered.connect(self.setHigh) SettingMenu.addAction(exitButton) setlowButton = QAction(QIcon('exit24.png'), 'Set As Low', self) setlowButton.triggered.connect(self.setLow) SettingMenu.addAction(setlowButton) self.tb_down = QToolButton() self.tb_down.pressed.connect(self.on_click_down) self.tb_down.released.connect(self.on_released) self.tb_down.setArrowType(Qt.LeftArrow) self.tb_up = QToolButton() self.tb_up.pressed.connect(self.on_click_up) self.tb_up.released.connect(self.on_released) self.tb_up.setArrowType(Qt.RightArrow) if self.showToggleButton: tb_set = QToolButton() tb_set.clicked.connect(self.on_click_set_value) tb_set.setText('<>') if self.showSettingMenu: tb_set.setMenu(SettingMenu) tb_set.setPopupMode(QToolButton.DelayedPopup) layout.addWidget(self.tb_down) layout.addWidget(self.bar) layout.addWidget(self.tb_up) if self.showToggleButton: layout.addWidget(tb_set) layout.setSpacing(0) def on_click_up(self): self.timer.start(self.timer_value, self) self.value += self.step self._setValue() def on_click_down(self): self.timer.start(self.timer_value, self) self.value -= self.step self._setValue() def on_released(self): self.timer.stop() def on_click_set_value(self): if self.value == self.hi_value: self.value = self.low_value else: self.value = self.hi_value self._setValue() def timerEvent(self, e): if self.value < self.maximum() and self.value > self.minimum(): if self.tb_down.isDown(): self.value -= self.step else: self.value += self.step self._setValue() else: self.timer.stop() def _setValue(self): if self.value < self.minimum(): self.value = self.minimum() if self.value > self.maximum(): self.value = self.maximum() self.valueChanged.emit(self.value) def setValue(self, value): if value < self.minimum(): value = self.minimum() if value > self.maximum(): value = self.maximum() self.value = int(value) tmpl = lambda s: self.texttemplate % s try: self.bar.text = tmpl(int(value)) except: self.bar.text = self.texttemplate self.bar.setValue(int(value)) self.bar.update() def setHigh(self): self.hi_value = self.value def setLow(self): self.low_value = self.value def setMaximum(self, data): if data < self.hi_value: self.hi_value = data self.bar.setMaximum(data) def setMinimum(self, data): if data > self.low_value: self.low_value = data self.bar.setMinimum(data) def setStep(self, data): self.step = data