예제 #1
0
파일: snek.py 프로젝트: Eliyss/python-snek
class Grid(QFrame):
    snekSpeed
    snekDirection
    gridSize
    gridLength = 11

    def __init__(self):
        super().__init__(parent)
        self.initGrid()
    
    def initGrid(self):
        self.grid = []
        self.timer = QBasicTimer()
        self.resetGrid()
        self.leSnekHasArrived()
        self.ateApple = False
        self.snekHeadX = 5
        self.snekHeadY = 4
        self.appleX = 0
        self.appleY = 0
        self.xVelocity = 0
        self.yVelocity = 0
        self.snekLength = 2
        self.snekTailX = 4
        self.snekTailY = 4
        self.snekTrailX = []
        self.snekTrailY = []

    
    def resetGrid(self):
        for i in range(gridLength):
            self.grid.append(0)
    
    def leSnekHasArrived(self):
        grid[gridLength*gridLength//2] = 1
        leSnek = Snek()
    
    def timerEvent(self, event):
        if event.timerId() = self.timer.timerId():
            self.headX += self.xVelocity
            self.headT += self.yVelocity
            

            if snekHeadX in snekTrail[]

            if self.ateApple:
                self.ateApple = False
                self.spawnApple()
        else:
예제 #2
0
class Barrel():
    def __init__(self, a, b, red, green, blue, size, speed):
        self.i = a
        self.j = b
        # self.type = QGraphicsEllipseItem(self.i*size, self.j*size, size, size)
        # self.type.setBrush(QColor(red, green, blue))
        self.type = QGraphicsPixmapItem(QPixmap('./GResource/barrel.gif'))
        self.type.setX(self.i * size)
        self.type.setY(self.j * size)
        self.spawnTimer = QBasicTimer()
        self.speed = speed
        self.movementTimer = QBasicTimer()
        self.isBarrelThrown = False
        self.spawnID = self.spawnTimer.timerId()
        self.mvmID = self.movementTimer.timerId()
예제 #3
0
class VideoCapture(QObject):
    """
    Class for capturing video from web camera using opencv

    It used an timer function to emit a Qt slot that contains image data.

    Class interested in processing this image will need to connect the slot.
    """

    # slot for emitting a frame captured from camera
    got_image_data_from_camera = pyqtSignal(np.ndarray)

    def __init__(self, camera_port=0, parent=None):
        super().__init__(parent)
        self.camera = cv2.VideoCapture(camera_port)
        self.timer = QBasicTimer()

    def start(self):
        self.timer.start(0, self)

    def stop(self):
        self.timer.stop()

    def timerEvent(self, event):
        if (event.timerId() != self.timer.timerId()):
            log.warning("Failed to setup timer for video capture")
            return

        read, data = self.camera.read()
        if read:
            self.got_image_data_from_camera.emit(data)
예제 #4
0
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()
예제 #5
0
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()
예제 #6
0
class ScaleFrame(QFrame):
    def __init__(self, parent):
        super(ScaleFrame, self).__init__(parent)
        self.parent = parent
        print('ScaleFrame: my parent is',self.parent)
        self.initFrame()

    def initFrame(self):
        self.commaweight = ''

        self.timer = QBasicTimer()
        self.myscale = Scale(10202)

        self.lbl_weight = QLabel(self)
        self.lbl_weight.setObjectName('lbl_weight')
        self.lbl_weight.setText("0.000")
        self.lbl_weight.resize(500, 100)
        self.lbl_weight.move(50, 50)

        lbl_unit = QLabel(self)
        lbl_unit.setObjectName('lbl_unit')
        lbl_unit.setText("kg")
        lbl_unit.resize(100, 120)
        lbl_unit.move(350, 40)

        self.setObjectName('ScaleFrame')
        self.setStyleSheet("""
            #ScaleFrame {
                background-color: #cfcfcf;
            }
            .QLabel#lbl_weight {
                font-size:100pt;
                color: #ff0000;
            }
            .QLabel#lbl_unit {
                font-size:100pt;
                color: #000000;
            }
            .QLabel {
                font-size:22pt;
                color: #000000;
            }
        """)
        self.start_timer()

    def start_timer(self):
        self.timer.start(100, self)

    def timerEvent(self, event):
        '''handles timer event'''
        if event.timerId() == self.timer.timerId():
            time_last_received, weight = self.myscale.return_last_weight()
            self.window().statusbar.showMessage(F"Last received: {time_last_received}")
            self.commaweight = str(F"{weight:.2f}").replace('.',',') # HACK HACK
            self.lbl_weight.setText(F"{weight:.3f}")
        else:
            super(Board, self).timerEvent(event)
예제 #7
0
파일: main.py 프로젝트: zz5414/tetrix_pyqt
class TetrisBoard(QFrame):
    msg_to_statusbar = pyqtSignal(str)

    Speed = 300
    BoardWidth = 10
    BoardHeight = 22



    def __init__(self, parent):
        super().__init__(parent)

        # member variable
        self.timer = QBasicTimer()

        self._test_int = 1

    def start(self):
        self.msg_to_statusbar.emit("Hello World")
        self.timer.start(TetrisBoard.Speed, self)

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.msg_to_statusbar.emit(str(self._test_int))
            self._test_int += 1
            self.update()
        else:
            super(TetrisBoard, self).timerEvent(event)

    def paintEvent(self, event):
        painter = QPainter(self)
        rect = self.contentsRect()

        #가장 아랫부분까지 채울 수 있도록 정해진 크기만큼 height를 가지도록 윗부분을 자른다.(특정 윗부분을 사용하지 않겠다는 의미)
        boardTop = rect.height() - TetrisBoard.BoardHeight * self.squareHeight()

        for h_index in range(TetrisBoard.BoardHeight):
            for w_index in range(TetrisBoard.BoardWidth):
                import random
                shape = random.randint(1, 7)
                colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
                              0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]
                x = rect.left() + w_index * self.squareWidth()
                y = boardTop + h_index * self.squareHeight()
                painter.fillRect(x, y, self.squareWidth(), self.squareHeight(), QColor(colorTable[shape]))



    def squareWidth(self):
        '''returns the width of one square'''
        # print(self.contentsRect().width(), TetrisBoard.BoardWidth, self.contentsRect().width() // TetrisBoard.BoardWidth)
        return self.contentsRect().width() // TetrisBoard.BoardWidth

    def squareHeight(self):
        '''returns the height of one square'''
        # print(self.contentsRect().height(), TetrisBoard.BoardHeight, self.contentsRect().height() // TetrisBoard.BoardHeight)
        return self.contentsRect().height() // TetrisBoard.BoardHeight
예제 #8
0
class Canvas( QFrame ):
    def __init__( self, parent = None):
        super().__init__( parent )
        self.setFocusPolicy( Qt.StrongFocus )
        self.model = Model( FIELD_WIDTH, FIELD_HEIGHT, TILE_SIZE )
        self.timer = QBasicTimer()
        self.timer.start( TIMER_DELAY, self )

    def keyPressEvent( self, event ):
        key = event.key()
        if key == Qt.Key_Space:
            self.model.reset()
            self.parent().setWindowTitle(TITLE_OF_PROGRAM)
            self.update()
        elif key == Qt.Key_Left or key == Qt.Key_A:
            self.model.try_to_slide_in_direction( Directions.LEFT )
        elif key == Qt.Key_Up or key == Qt.Key_W:
            self.model.try_to_slide_in_direction( Directions.UP )
        elif key == Qt.Key_Right or key == Qt.Key_D:
            self.model.try_to_slide_in_direction( Directions.RIGHT )
        elif key == Qt.Key_Down or key == Qt.Key_S:
            self.model.try_to_slide_in_direction( Directions.DOWN )

    def mouseReleaseEvent( self, event ):
        x = int(event.x() / TILE_SIZE) * TILE_SIZE
        y = int(event.y() / TILE_SIZE) * TILE_SIZE
        self.model.try_to_slide( x, y )

    def timerEvent( self, event ):
        if event.timerId() == self.timer.timerId():
            self.model.tick()
            self.parent().setWindowTitle(TITLE_OF_PROGRAM + ": "+ str(self.model.move_count))
            self.update()

    def paintEvent( self, event ):
        painter = QPainter( self )
        color = QColor("#e74c3c")
        font = QFont( "Arial" )
        font.setPointSize( 40 )
        painter.setFont( font )
        for tile in self.model.grid:
            if( tile.value != 0):
                painter.setBrush( color )
                painter.fillRect( tile.x + 2, tile.y + 2, TILE_SIZE - 2, TILE_SIZE - 2, color)
                painter.setPen(QPen( QColor( 0, 0, 0 ), 5))
                painter.drawText( QRectF( tile.x, tile.y, TILE_SIZE, TILE_SIZE ), Qt.AlignCenter | Qt.AlignTop ,
                  str(tile.value))
        if( self.model.is_game_over ):
            font = QFont( "Arial" )
            font.setPointSize( 80 )
            painter.setPen( QPen( QColor( 0, 190, 0 ), 20 ) )
            painter.drawText( QRectF( 0, 0, FIELD_WIDTH * TILE_SIZE, FIELD_HEIGHT * TILE_SIZE ), Qt.AlignCenter | Qt.AlignTop ,
              str("Puzzle solved!"))
예제 #9
0
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)
예제 #10
0
class OceanVisualizator(QWidget):
    def __init__(self, interval, ocean, window_height=1000, window_width=1000):
        super().__init__()
        self.ocean = ocean
        self.window_width = window_width
        self.window_height = window_height
        self.cell_width = self.window_width / self.ocean.width
        self.cell_heigth = self.window_height / self.ocean.height

        self.timer = QBasicTimer()
        self.init_ui()
        self.timer.start(interval * 1000, self)

    def init_ui(self):
        self.setGeometry(0, 0, self.window_width, self.window_height)
        self.setWindowTitle("Ocean visualization")
        self.show()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)

        for y in range(self.ocean.height):
            for x in range(self.ocean.width):
                if type(ocean.field[y][x]) != EmptyCell:
                    if type(ocean.field[y][x]) == Obstacle:
                        painter.fillRect(x * self.cell_width,
                                         y * self.cell_heigth, self.cell_width,
                                         self.cell_heigth,
                                         PyQt5.QtCore.Qt.black)
                    elif type(ocean.field[y][x]) == Victim:
                        painter.setBrush(PyQt5.QtCore.Qt.green)
                        painter.drawEllipse(x * self.cell_width,
                                            y * self.cell_heigth,
                                            self.cell_width, self.cell_heigth)
                    elif type(ocean.field[y][x]) == Predator:
                        color = QColor(255, 0, 0)
                        live_rate = ((ocean.field[y][x].full_health -
                                      ocean.field[y][x].health) * 200 /
                                     ocean.field[y][x].full_health)
                        painter.setBrush(QBrush(color.darker(100 + live_rate)))
                        painter.drawEllipse(x * self.cell_width,
                                            y * self.cell_heigth,
                                            self.cell_width, self.cell_heigth)

        painter.end()

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.ocean.make_turn()
            self.update()
예제 #11
0
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)
예제 #12
0
class CameraRecord(QWidget):

    image_data = pyqtSignal(np.ndarray)

    def __init__(self, camera_port=0):
        super().__init__()
        self.camera = cv2.VideoCapture(camera_port)
        self.timer = QBasicTimer()
        self.timer.start(0, self)

    def timerEvent(self, QTimerEvent):
        if QTimerEvent.timerId() != self.timer.timerId():
            return
        read, data = self.camera.read()
        if read:
            self.image_data.emit(data)
예제 #13
0
파일: wiggly.py 프로젝트: skinkie/Scripts
class WigglyWidget(QWidget):
    def __init__(self, parent=None):
        super(WigglyWidget, self).__init__(parent)

        self.setBackgroundRole(QPalette.Midlight)
        self.setAutoFillBackground(True)

        newFont = self.font()
        newFont.setPointSize(newFont.pointSize() + 20)
        self.setFont(newFont)

        self.timer = QBasicTimer()
        self.text = ''

        self.step = 0
        self.timer.start(60, self)

    def paintEvent(self, event):
        sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100,
                     -92, -71, -38)

        metrics = QFontMetrics(self.font())
        x = (self.width() - metrics.width(self.text)) / 2
        y = (self.height() + metrics.ascent() - metrics.descent()) / 2
        color = QColor()

        painter = QPainter(self)

        for i, ch in enumerate(self.text):
            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)
            x += metrics.width(ch)

    def setText(self, newText):
        self.text = newText

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.step += 1
            self.update()
        else:
            super(WigglyWidget, self).timerEvent(event)
예제 #14
0
class CaptureVideo(QObject):
    # Signals
    image_data = pyqtSignal(ndarray)

    # Initialize class
    def __init__(self, camera_port=0):
        super().__init__()
        self.camera = cv2.VideoCapture(camera_port)
        self.timer = QBasicTimer()
        self.timer.start(1, self)  # Period in miliseconds

    # Update video frame
    def timerEvent(self, event):
        if (event.timerId() != self.timer.timerId()):
            return
        read, frame = self.camera.read()
        if read:
            self.image_data.emit(frame)
예제 #15
0
파일: ex2.py 프로젝트: olanuza/testing
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 400, 25)

        self.startbtn = QPushButton('Start', self)
        self.startbtn.move(30, 80)
        self.startbtn.clicked.connect(self.pushStart)

        self.stopbtn = QPushButton('Stop', self)
        self.stopbtn.move(320, 80)
        self.stopbtn.clicked.connect(self.pushStop)

        self.setGeometry(300, 300, 430, 170)
        self.setWindowTitle('This is a 5s timer. Press stop to abort')
        self.show()

    def timerEvent(self, e):

        if self.step >= 100:

            self.timer.stop()
            self.killTimer(self.timer.timerId())
            return

        self.step = self.step + 1
        self.pbar.setValue(self.step)

    def pushStart(self):
        self.timer = QBasicTimer()
        self.step = 0
        self.timer.start(50, self)

    def pushStop(self):
        self.timer.stop()
        self.pbar.setValue(0)
        self.killTimer(self.timer.timerId())
예제 #16
0
class WigglyWidget(QWidget):
    def __init__(self, parent=None):
        super(WigglyWidget, self).__init__(parent)

        self.setBackgroundRole(QPalette.Midlight)
        self.setAutoFillBackground(True)

        newFont = self.font()
        newFont.setPointSize(newFont.pointSize() + 20)
        self.setFont(newFont)

        self.timer = QBasicTimer()
        self.text = ''

        self.step = 0;
        self.timer.start(60, self)   

    def paintEvent(self, event):
        sineTable = (0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38)

        metrics = QFontMetrics(self.font())
        x = (self.width() - metrics.width(self.text)) / 2
        y = (self.height() + metrics.ascent() - metrics.descent()) / 2
        color = QColor()

        painter = QPainter(self)

        for i, ch in enumerate(self.text):
            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)
            x += metrics.width(ch)

    def setText(self, newText):
        self.text = newText

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.step += 1
            self.update()
        else:
            super(WigglyWidget, self).timerEvent(event)
예제 #17
0
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):

        if e.timerId() == self.timer.timerId():
            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(10, self)
            self.btn.setText('Stop')
예제 #18
0
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.rot = 0
        self.timer = QBasicTimer()
        self.timer.start(500, self)

        self.setGeometry(300, 300, 430, 240)
        self.setWindowTitle('Soulmate')
        self.show()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        self.drawDonut(painter)
        painter.end()

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.rot += 1
            self.repaint()
        else:
            super(Example, self).timerEvent(event)

    def drawDonut(self, painter):
        brush = QBrush(QColor('#535353'))
        painter.setPen(QPen(brush, 0.5))
        painter.setRenderHint(QPainter.Antialiasing)

        h = self.height()
        w = self.width()

        painter.translate(QPoint(w / 2, h / 2))

        for r in range(0, self.rot, 1):
            painter.rotate(float(r))
            painter.drawEllipse(-125, -40, 250, 80)
예제 #19
0
파일: MainWindow.py 프로젝트: zwdnet/liquid
class LiquidBox(QWidget):
    # 模拟流体力学程序,盛着液体的盒子
    def __init__(self):
        super().__init__()
        self.speed = 100  #重绘速度1s
        self.WindowSize = 50
        self.timer = QBasicTimer()
        self.sim = sm.Stimulator(self.WindowSize)
        self.initUI()

    def initUI(self):
        self.setGeometry(200, 200, 600, 600)
        self.setFixedSize(400, 400)
        self.setWindowTitle("流体力学模拟程序")
        self.timer.start(self.speed, self)
        self.show()

    #处理计时器消息
    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.update()
        else:
            super().timerEvent(event)

    #处理重绘消息
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        self.Draw(qp)
        qp.end()

    #具体绘图函数
    def Draw(self, qp):
        qp.setPen(Qt.blue)
        points = self.sim.step()
        for i in range(len(points)):
            qp.drawPoint(int(points[i][0]), int(points[i][1]))
예제 #20
0
class LiquidBox(QWidget):
    # 模拟流体力学程序,盛着液体的盒子
    def __init__(self):
        super().__init__()
        self.speed = 100  #重绘速度1s
        self.WindowSize = 50
        self.timer = QBasicTimer()
        self.sim = sm.Stimulator(self.WindowSize)
        self.initUI()

    def initUI(self):
        self.setGeometry(200, 200, 600, 600)
        self.setFixedSize(400, 400)
        self.setWindowTitle("流体力学模拟程序")
        self.timer.start(self.speed, self)
        self.show()

    #处理计时器消息
    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.update()
        else:
            super().timerEvent(event)

    #处理重绘消息
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        self.Draw(qp)
        qp.end()

    #具体绘图函数
    def Draw(self, qp):
        qp.setPen(Qt.blue)
        points = self.sim.step()
        for i in range(len(points)):
            qp.drawPoint(int(points[i][0]), int(points[i][1]))
예제 #21
0
class Board(QFrame):
    # 俄罗斯方块的一切逻辑操作在这里(旋转控制/满层消除/gameover判断/定时器判断/图形渲染)
    msg2status_bar = pyqtSignal(str)

    def __init__(self, parent):
        super(Board, self).__init__(parent)

        self.is_paused = False  # 是否被暂停
        self.num_lines_removed = 0  # 被删除的行数
        self.game_start = True
        self.waiting_new_shape = False

        self.cur_x = 0
        self.cur_y = 0
        self.cur_shape = None

        self.setFocusPolicy(Qt.StrongFocus)  # 界面没有按钮时,设置聚焦
        self.timer = QBasicTimer()
        self.boards = []
        self.clear_board()

    def clear_board(self):
        self.boards = [0 for i in range(WIDTH_GRID * HEIGHT_GRID)]

    def start(self):
        self.new_shape()
        self.timer.start(SPEED, self)

    def paintEvent(self, e):
        self.draw_shape()

    def new_shape(self):
        # 新建 shape
        self.cur_x = WIDTH_GRID // 2
        self.cur_y = 0
        self.cur_shape = Shape()
        self.cur_shape.set_random_shape()
        self.cur_shape.set_shape_coors(self.cur_shape.shape_type)

        if not self.move_shape(self.cur_shape, 0, 1):
            self.timer.stop()
            self.msg2status_bar.emit('Game Over!')
            self.game_start = False
            if self.cur_shape_has_repeat():
                self.cur_shape = Shape()
        self.update()

    def cur_shape_has_repeat(self):
        for i in range(len(self.cur_shape.coors)):
            x = self.cur_shape.get_x(i)
            y = self.cur_shape.get_y(i)
            if self.get_shape_in_boards(x, y) != ShapeType.No_shape:
                return True
        return False

    def timerEvent(self, e):
        if e.timerId() == self.timer.timerId():
            # time.sleep(1)
            if self.waiting_new_shape:
                self.waiting_new_shape = False
                self.set_shape_in_boards()
                self.remove_full_lines()
            else:
                self.shape_down1line(0, 1)
        else:
            return super(Board, self).timerEvent(e)

    def shape_down1line(self, x_offset, y_offset):
        # shape 往下移动一行
        res = self.move_shape(self.cur_shape, x_offset, y_offset)
        # if res is False:
        #     self.set_shape_in_boards()
        #     self.remove_full_lines()
        return res

    def shape_drop_down(self):
        # 直接移动到底部
        while self.shape_down1line(0, 1):
            pass

    def shape_pause(self):
        if self.is_paused:
            self.timer.start(SPEED, self)
            self.msg2status_bar.emit("分数:" + str(self.num_lines_removed))
        else:
            self.timer.stop()
            self.msg2status_bar.emit("暂停")

        self.is_paused = not self.is_paused
        self.update()

    def keyPressEvent(self, event):
        key = event.key()

        if not self.game_start:
            return super(Board, self).keyPressEvent(event)
        if self.is_paused and key != Qt.Key_P:
            return super(Board, self).keyPressEvent(event)

        if key == Qt.Key_Up:
            # 上:左转
            self.move_shape(self.cur_shape.rotate_left(), 0, 0)
        elif key == Qt.Key_Down:
            # 下:右转
            self.move_shape(self.cur_shape.rotate_right(), 0, 0)
        elif key == Qt.Key_Left:
            # 左移
            self.shape_down1line(-1, 0)
        elif key == Qt.Key_Right:
            # 右移
            self.shape_down1line(1, 0)
        elif key == Qt.Key_P:
            # 暂停
            self.shape_pause()
        elif key == Qt.Key_Space:
            # 空格:直接下到最后一行
            self.shape_drop_down()
        else:
            return super(Board, self).keyPressEvent(event)

    def move_shape(self, shape, x_offset, y_offset):
        for i in range(len(shape.coors)):
            x = shape.get_x(i) + self.cur_x
            y = -shape.get_y(i) + self.cur_y

            if x + x_offset < 0 or x + x_offset >= WIDTH_GRID or y > HEIGHT_GRID - 1:
                # 设定不能超出边界
                return None
            if y < 0:
                continue

            if y == HEIGHT_GRID - 1 or self.boards[self.get_index_in_boards(
                    x, y + 1)] != ShapeType.No_shape:
                # 接触到了下边界 或 如果 x y 这个坐标在 boards 中不是空形状,返回 False
                self.waiting_new_shape = True
                return False

        self.cur_x += x_offset
        self.cur_y += y_offset
        self.cur_shape = shape
        self.update()
        return True

    def remove_full_lines(self):
        # 删除所有满行
        lines = list(
            set([
                self.cur_y - self.cur_shape.get_y(i)
                for i in range(len(self.cur_shape.coors))
            ]))
        remove_lines = []

        for line in lines:
            for i in range(line * WIDTH_GRID, line * WIDTH_GRID + WIDTH_GRID):
                if self.boards[i] == ShapeType.No_shape:
                    break
            else:
                remove_lines.append(line)

        if remove_lines:
            remove_lines.sort()
            for remove_line in remove_lines:
                while remove_line > 0:
                    for i in range(remove_line * WIDTH_GRID,
                                   remove_line * WIDTH_GRID + WIDTH_GRID):
                        self.boards[i] = self.boards[i - WIDTH_GRID]
                    remove_line -= 1

        if len(remove_lines) > 0:
            self.num_lines_removed += len(remove_lines)
            self.msg2status_bar.emit("分数:" + str(self.num_lines_removed))

        self.new_shape()

    def get_shape_in_boards(self, x, y):
        return self.boards[self.get_index_in_boards(x, y)]

    def set_shape_in_boards(self):
        for i in range(len(self.cur_shape.coors)):
            x = self.cur_shape.get_x(i) + self.cur_x
            y = -self.cur_shape.get_y(i) + self.cur_y
            if y < 0 or x < 0:
                continue
            self.set_boards_shape_type(x, y, self.cur_shape.shape_type)

    def set_boards_shape_type(self, x, y, shape_type):
        count = self.get_index_in_boards(x, y)
        self.boards[count] = shape_type

    @classmethod
    def get_index_in_boards(cls, x, y):
        return y * WIDTH_GRID + x

    def draw_shape(self):
        qp = QPainter()
        qp.begin(self)

        for i in range(len(self.cur_shape.coors)):
            if self.cur_shape.shape_type == ShapeType.No_shape:
                break
            self.painter_square(qp, self.cur_x + self.cur_shape.get_x(i),
                                self.cur_y - self.cur_shape.get_y(i), 1, 1,
                                self.cur_shape.shape_type)

        for i in range(WIDTH_GRID):
            for j in range(HEIGHT_GRID):
                shape_type = self.get_shape_in_boards(i, j)
                if shape_type != ShapeType.No_shape:
                    self.painter_square(qp, i, j, 1, 1, shape_type)

        qp.end()

    def every_square_per_width(self):
        return self.contentsRect().width() // WIDTH_GRID

    def every_square_per_height(self):
        return self.contentsRect().height() // HEIGHT_GRID

    def painter_square(self, qp, x, y, width, height, shape_type):
        # 根据长宽和起始地点画框
        x *= self.every_square_per_width()
        y *= self.every_square_per_height()
        width *= self.every_square_per_width()
        height *= self.every_square_per_height()

        color = QColor(ShapeType.Shape_Colors[shape_type])
        qp.fillRect(x + 1, y + 1, width - 1, height - 2, color)

        qp.setPen(color.lighter())
        qp.drawLine(x, y, x + width - 1, y)
        qp.drawLine(x, y, x, y + height - 1)
        qp.setPen(color.darker())
        qp.drawLine(x + width - 1, y + 1, x + width - 1, y + height - 1)
        qp.drawLine(x + 1, y + height - 1, x + width - 1, y + height - 1)
예제 #22
0
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()
예제 #23
0
class DownloadManager(QDialog, Ui_DownloadManager):
    """
    Class implementing the download manager.
    
    @signal downloadsCountChanged() emitted to indicate a change of the
        count of download items
    """
    RemoveNever = 0
    RemoveExit = 1
    RemoveSuccessFullDownload = 2

    UpdateTimerTimeout = 1000

    downloadsCountChanged = pyqtSignal()

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        """
        super(DownloadManager, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(Qt.Window)

        self.__winTaskbarButton = None

        self.__saveTimer = AutoSaver(self, self.save)

        self.__model = DownloadModel(self)
        self.__manager = WebBrowserWindow.networkManager()

        self.__iconProvider = None
        self.__downloads = []
        self.__downloadDirectory = ""
        self.__loaded = False

        self.__rowHeightMultiplier = 1.1

        self.setDownloadDirectory(Preferences.getUI("DownloadPath"))

        self.downloadsView.setShowGrid(False)
        self.downloadsView.verticalHeader().hide()
        self.downloadsView.horizontalHeader().hide()
        self.downloadsView.setAlternatingRowColors(True)
        self.downloadsView.horizontalHeader().setStretchLastSection(True)
        self.downloadsView.setModel(self.__model)
        self.downloadsView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.downloadsView.customContextMenuRequested.connect(
            self.__customContextMenuRequested)

        self.__clearShortcut = QShortcut(QKeySequence("Ctrl+L"), self)
        self.__clearShortcut.activated.connect(self.on_cleanupButton_clicked)

        self.__load()

        self.__updateTimer = QBasicTimer()

    def __customContextMenuRequested(self, pos):
        """
        Private slot to handle the context menu request for the bookmarks tree.
        
        @param pos position the context menu was requested (QPoint)
        """
        menu = QMenu()

        selectedRowsCount = len(
            self.downloadsView.selectionModel().selectedRows())

        if selectedRowsCount == 1:
            row = self.downloadsView.selectionModel().selectedRows()[0].row()
            itm = self.__downloads[row]
            if itm.downloadedSuccessfully():
                menu.addAction(UI.PixmapCache.getIcon("open.png"),
                               self.tr("Open"), self.__contextMenuOpen)
            elif itm.downloading():
                menu.addAction(UI.PixmapCache.getIcon("stopLoading.png"),
                               self.tr("Cancel"), self.__contextMenuCancel)
                menu.addSeparator()
            menu.addAction(self.tr("Open Containing Folder"),
                           self.__contextMenuOpenFolder)
            menu.addSeparator()
            menu.addAction(self.tr("Go to Download Page"),
                           self.__contextMenuGotoPage)
            menu.addAction(self.tr("Copy Download Link"),
                           self.__contextMenuCopyLink)
            menu.addSeparator()
        menu.addAction(self.tr("Select All"), self.__contextMenuSelectAll)
        if (selectedRowsCount > 1
                or (selectedRowsCount == 1
                    and not self.__downloads[self.downloadsView.selectionModel(
                    ).selectedRows()[0].row()].downloading())):
            menu.addSeparator()
            menu.addAction(self.tr("Remove From List"),
                           self.__contextMenuRemoveSelected)

        menu.exec_(QCursor.pos())

    def shutdown(self):
        """
        Public method to stop the download manager.
        """
        self.save()
        self.close()

    def activeDownloadsCount(self):
        """
        Public method to get the number of active downloads.
        
        @return number of active downloads (integer)
        """
        count = 0

        for download in self.__downloads:
            if download.downloading():
                count += 1
        return count

    def allowQuit(self):
        """
        Public method to check, if it is ok to quit.
        
        @return flag indicating allowance to quit (boolean)
        """
        if self.activeDownloadsCount() > 0:
            res = E5MessageBox.yesNo(
                self,
                self.tr(""),
                self.tr(
                    """There are %n downloads in progress.\n"""
                    """Do you want to quit anyway?""", "",
                    self.activeDownloadsCount()),
                icon=E5MessageBox.Warning)
            if not res:
                self.show()
                return False

        self.close()
        return True

    def __testWebBrowserView(self, view, url):
        """
        Private method to test a web browser view against an URL.
        
        @param view reference to the web browser view to be tested
        @type WebBrowserView
        @param url URL to test against
        @type QUrl
        @return flag indicating, that the view is the one for the URL
        @rtype bool
        """
        if view.tabWidget().count() < 2:
            return False

        page = view.page()
        if page.history().count() != 0:
            return False

        if (not page.url().isEmpty() and page.url().host() == url.host()):
            return True

        requestedUrl = page.requestedUrl()
        if requestedUrl.isEmpty():
            requestedUrl = QUrl(view.tabWidget().urlBarForView(view).text())
        return requestedUrl.isEmpty() or requestedUrl.host() == url.host()

    def __closeDownloadTab(self, url):
        """
        Private method to close an empty tab, that was opened only for loading
        the download URL.
        
        @param url download URL
        @type QUrl
        """
        if self.__testWebBrowserView(
                WebBrowserWindow.getWindow().currentBrowser(), url):
            WebBrowserWindow.getWindow().closeCurrentBrowser()
            return

        for window in WebBrowserWindow.mainWindows():
            for browser in window.browsers():
                if self.__testWebBrowserView(browser, url):
                    window.closeBrowser(browser)
                    return

    def download(self, downloadItem):
        """
        Public method to download a file.
        
        @param downloadItem reference to the download object containing the
        download data.
        @type QWebEngineDownloadItem
        """
        url = downloadItem.url()
        if url.isEmpty():
            return

        self.__closeDownloadTab(url)

        # Safe Browsing
        from WebBrowser.SafeBrowsing.SafeBrowsingManager import (
            SafeBrowsingManager)
        if SafeBrowsingManager.isEnabled():
            threatLists = (
                WebBrowserWindow.safeBrowsingManager().lookupUrl(url)[0])
            if threatLists:
                threatMessages = (WebBrowserWindow.safeBrowsingManager().
                                  getThreatMessages(threatLists))
                res = E5MessageBox.warning(
                    WebBrowserWindow.getWindow(),
                    self.tr("Suspicuous URL detected"),
                    self.tr("<p>The URL <b>{0}</b> was found in the Safe"
                            " Browsing database.</p>{1}").format(
                                url.toString(), "".join(threatMessages)),
                    E5MessageBox.StandardButtons(E5MessageBox.Abort
                                                 | E5MessageBox.Ignore),
                    E5MessageBox.Abort)
                if res == E5MessageBox.Abort:
                    downloadItem.cancel()
                    return

        window = WebBrowserWindow.getWindow()
        if window:
            pageUrl = window.currentBrowser().url()
        else:
            pageUrl = QUrl()
        from .DownloadItem import DownloadItem
        itm = DownloadItem(downloadItem=downloadItem,
                           pageUrl=pageUrl,
                           parent=self)
        self.__addItem(itm)

        if Preferences.getWebBrowser("DownloadManagerAutoOpen"):
            self.show()
        else:
            self.__startUpdateTimer()

    def show(self):
        """
        Public slot to show the download manager dialog.
        """
        self.__startUpdateTimer()

        super(DownloadManager, self).show()
        self.activateWindow()
        self.raise_()

    def __addItem(self, itm, append=False):
        """
        Private method to add a download to the list of downloads.
        
        @param itm reference to the download item
        @type DownloadItem
        @param append flag indicating to append the item
        @type bool
        """
        itm.statusChanged.connect(lambda: self.__updateRow(itm))
        itm.downloadFinished.connect(self.__finished)

        # insert at top of window
        if append:
            row = self.downloadsCount()
        else:
            row = 0
        self.__model.beginInsertRows(QModelIndex(), row, row)
        if append:
            self.__downloads.append(itm)
        else:
            self.__downloads.insert(0, itm)
        self.__model.endInsertRows()

        self.downloadsView.setIndexWidget(self.__model.index(row, 0), itm)
        icon = self.style().standardIcon(QStyle.SP_FileIcon)
        itm.setIcon(icon)
        self.downloadsView.setRowHeight(
            row,
            itm.sizeHint().height() * self.__rowHeightMultiplier)
        # just in case the download finished before the constructor returned
        self.__updateRow(itm)
        self.changeOccurred()

        self.downloadsCountChanged.emit()

    def __updateRow(self, itm):
        """
        Private slot to update a download item.
        
        @param itm reference to the download item
        @type DownloadItem
        """
        if itm not in self.__downloads:
            return

        row = self.__downloads.index(itm)

        if self.__iconProvider is None:
            self.__iconProvider = QFileIconProvider()

        icon = self.__iconProvider.icon(QFileInfo(itm.fileName()))
        if icon.isNull():
            icon = self.style().standardIcon(QStyle.SP_FileIcon)
        itm.setIcon(icon)

        self.downloadsView.setRowHeight(
            row,
            itm.minimumSizeHint().height() * self.__rowHeightMultiplier)

        remove = False

        if (itm.downloadedSuccessfully() and self.removePolicy()
                == DownloadManager.RemoveSuccessFullDownload):
            remove = True

        if remove:
            self.__model.removeRow(row)

        self.cleanupButton.setEnabled(
            (self.downloadsCount() - self.activeDownloadsCount()) > 0)

        # record the change
        self.changeOccurred()

    def removePolicy(self):
        """
        Public method to get the remove policy.
        
        @return remove policy (integer)
        """
        return Preferences.getWebBrowser("DownloadManagerRemovePolicy")

    def setRemovePolicy(self, policy):
        """
        Public method to set the remove policy.
        
        @param policy policy to be set
            (DownloadManager.RemoveExit, DownloadManager.RemoveNever,
             DownloadManager.RemoveSuccessFullDownload)
        """
        assert policy in (DownloadManager.RemoveExit,
                          DownloadManager.RemoveNever,
                          DownloadManager.RemoveSuccessFullDownload)

        if policy == self.removePolicy():
            return

        Preferences.setWebBrowser("DownloadManagerRemovePolicy", self.policy)

    def save(self):
        """
        Public method to save the download settings.
        """
        if not self.__loaded:
            return

        Preferences.setWebBrowser("DownloadManagerSize", self.size())
        Preferences.setWebBrowser("DownloadManagerPosition", self.pos())
        if self.removePolicy() == DownloadManager.RemoveExit:
            return

        from WebBrowser.WebBrowserWindow import WebBrowserWindow
        if WebBrowserWindow.isPrivate():
            return

        downloads = []
        for download in self.__downloads:
            downloads.append(download.getData())
        Preferences.setWebBrowser("DownloadManagerDownloads", downloads)

    def __load(self):
        """
        Private method to load the download settings.
        """
        if self.__loaded:
            return

        size = Preferences.getWebBrowser("DownloadManagerSize")
        if size.isValid():
            self.resize(size)
        pos = Preferences.getWebBrowser("DownloadManagerPosition")
        self.move(pos)

        from WebBrowser.WebBrowserWindow import WebBrowserWindow
        if not WebBrowserWindow.isPrivate():
            downloads = Preferences.getWebBrowser("DownloadManagerDownloads")
            for download in downloads:
                if (not download["URL"].isEmpty()
                        and bool(download["Location"])):
                    from .DownloadItem import DownloadItem
                    itm = DownloadItem(parent=self)
                    itm.setData(download)
                    self.__addItem(itm, append=True)
            self.cleanupButton.setEnabled(
                (self.downloadsCount() - self.activeDownloadsCount()) > 0)

        self.__loaded = True

        self.downloadsCountChanged.emit()

    def closeEvent(self, evt):
        """
        Protected event handler for the close event.
        
        @param evt reference to the close event
        @type QCloseEvent
        """
        self.save()

    def cleanup(self):
        """
        Public slot to cleanup the downloads.
        """
        self.on_cleanupButton_clicked()

    @pyqtSlot()
    def on_cleanupButton_clicked(self):
        """
        Private slot to cleanup the downloads.
        """
        if self.downloadsCount() == 0:
            return

        self.__model.removeRows(0, self.downloadsCount())
        if (self.downloadsCount() == 0 and self.__iconProvider is not None):
            self.__iconProvider = None

        self.changeOccurred()

        self.downloadsCountChanged.emit()

    def __finished(self, success):
        """
        Private slot to handle a finished download.
        
        @param success flag indicating a successful download
        @type bool
        """
        if self.isVisible():
            QApplication.alert(self)

        self.downloadsCountChanged.emit()

        if self.activeDownloadsCount() == 0:
            # all active downloads are done
            if success and e5App().activeWindow() is not self:
                if WebBrowserWindow.notificationsEnabled():
                    WebBrowserWindow.showNotification(
                        UI.PixmapCache.getPixmap("downloads48.png"),
                        self.tr("Downloads finished"),
                        self.tr("All files have been downloaded."))
                if not Preferences.getWebBrowser("DownloadManagerAutoClose"):
                    self.raise_()
                    self.activateWindow()

            self.__stopUpdateTimer()
            self.infoLabel.clear()
            self.setWindowTitle(self.tr("Download Manager"))
            if Globals.isWindowsPlatform():
                self.__taskbarButton().progress().hide()

            if Preferences.getWebBrowser("DownloadManagerAutoClose"):
                self.close()

    def setDownloadDirectory(self, directory):
        """
        Public method to set the current download directory.
        
        @param directory current download directory (string)
        """
        self.__downloadDirectory = directory
        if self.__downloadDirectory != "":
            self.__downloadDirectory += "/"

    def downloadDirectory(self):
        """
        Public method to get the current download directory.
        
        @return current download directory (string)
        """
        return self.__downloadDirectory

    def downloadsCount(self):
        """
        Public method to get the number of downloads.
        
        @return number of downloads
        @rtype int
        """
        return len(self.__downloads)

    def downloads(self):
        """
        Public method to get a reference to the downloads.
        
        @return reference to the downloads (list of DownloadItem)
        """
        return self.__downloads

    def changeOccurred(self):
        """
        Public method to signal a change.
        """
        self.__saveTimer.changeOccurred()

    def __taskbarButton(self):
        """
        Private method to get a reference to the task bar button (Windows
        only).
        
        @return reference to the task bar button
        @rtype QWinTaskbarButton or None
        """
        if Globals.isWindowsPlatform():
            from PyQt5.QtWinExtras import QWinTaskbarButton
            if self.__winTaskbarButton is None:
                window = WebBrowserWindow.mainWindow()
                self.__winTaskbarButton = QWinTaskbarButton(
                    window.windowHandle())
                self.__winTaskbarButton.progress().setRange(0, 100)

        return self.__winTaskbarButton

    def timerEvent(self, evt):
        """
        Protected event handler for timer events.
        
        @param evt reference to the timer event
        @type QTimerEvent
        """
        if evt.timerId() == self.__updateTimer.timerId():
            if self.activeDownloadsCount() == 0:
                self.__stopUpdateTimer()
                self.infoLabel.clear()
                self.setWindowTitle(self.tr("Download Manager"))
                if Globals.isWindowsPlatform():
                    self.__taskbarButton().progress().hide()
            else:
                progresses = []
                for itm in self.__downloads:
                    if (itm is None or itm.downloadCanceled()
                            or not itm.downloading()):
                        continue

                    progresses.append(
                        (itm.downloadProgress(), itm.remainingTime(),
                         itm.currentSpeed()))

                if not progresses:
                    return

                remaining = 0
                progress = 0
                speed = 0.0

                for progressData in progresses:
                    if progressData[1] > remaining:
                        remaining = progressData[1]
                    progress += progressData[0]
                    speed += progressData[2]
                progress = progress / len(progresses)

                if self.isVisible():
                    self.infoLabel.setText(
                        self.tr("{0}% of %n file(s) ({1}) {2}", "",
                                len(progresses)).format(
                                    progress,
                                    speedString(speed),
                                    timeString(remaining),
                                ))
                    self.setWindowTitle(self.tr("{0}% - Download Manager"))

                if Globals.isWindowsPlatform():
                    self.__taskbarButton().progress().show()
                    self.__taskbarButton().progress().setValue(progress)

        super(DownloadManager, self).timerEvent(evt)

    def __startUpdateTimer(self):
        """
        Private slot to start the update timer.
        """
        if self.activeDownloadsCount() and not self.__updateTimer.isActive():
            self.__updateTimer.start(DownloadManager.UpdateTimerTimeout, self)

    def __stopUpdateTimer(self):
        """
        Private slot to stop the update timer.
        """
        self.__updateTimer.stop()

    ###########################################################################
    ## Context menu related methods below
    ###########################################################################

    def __currentItem(self):
        """
        Private method to get a reference to the current item.
        
        @return reference to the current item (DownloadItem)
        """
        index = self.downloadsView.currentIndex()
        if index and index.isValid():
            row = index.row()
            return self.__downloads[row]

        return None

    def __contextMenuOpen(self):
        """
        Private method to open the downloaded file.
        """
        itm = self.__currentItem()
        if itm is not None:
            itm.openFile()

    def __contextMenuOpenFolder(self):
        """
        Private method to open the folder containing the downloaded file.
        """
        itm = self.__currentItem()
        if itm is not None:
            itm.openFolder()

    def __contextMenuCancel(self):
        """
        Private method to cancel the current download.
        """
        itm = self.__currentItem()
        if itm is not None:
            itm.cancelDownload()

    def __contextMenuGotoPage(self):
        """
        Private method to open the download page.
        """
        itm = self.__currentItem()
        if itm is not None:
            url = itm.getPageUrl()
            WebBrowserWindow.mainWindow().openUrl(url, "")

    def __contextMenuCopyLink(self):
        """
        Private method to copy the download link to the clipboard.
        """
        itm = self.__currentItem()
        if itm is not None:
            url = itm.getPageUrl().toDisplayString(QUrl.FullyDecoded)
            QApplication.clipboard().setText(url)

    def __contextMenuSelectAll(self):
        """
        Private method to select all downloads.
        """
        self.downloadsView.selectAll()

    def __contextMenuRemoveSelected(self):
        """
        Private method to remove the selected downloads from the list.
        """
        self.downloadsView.removeSelected()
예제 #24
0
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()

    # метод initBoard() запускает несколько важных переменных.
    # Одна из них - self.board – это список чисел от 0 до 7. Она представляет
    # нахождение на поле различных фигур.

    def shapeAt(self, x, y):
        return self.board[(y * Board.BoardWidth) + x]

    # Метод shapeAt() генерирует вид фигуры в данном отсеке.

    def setShapeAt(self, x, y, shape):
        self.board[(y * Board.BoardWidth) + x] = shape

    def squareWidth(self):
        return self.contentsRect().width() // Board.BoardWidth

    # squareWidth() вычисляет ширину простого квадратика в пикселях и возвращает её,
    # чтобы разрешение было динамическим (если изменить размеры окошка).

    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("На паузе.")
        # Если игрок останавливает игру на паузу, выводим сообшение
        # "На паузе." также останавливаем таймер
        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)

        # Первоначально, рисуются все фигуры, которые были сброшены вниз доски.
        # Все квадратики запоминаются в списке переменных self.board. Доступ к переменной получим,
        # взяв на вооружение уже известный нам метод shapeAt().

        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)

    # С помощью метода keyPressEvent(), будем отслеживать нажатые клавиши.
    # Стоит учесть, что если достигнут допустим левый край, то при нажатии
    # кнопки ничего не произойдёт :\

    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)

    # В timerEvent (переводится как - События Таймера), либо делается новая фигурка после предыдущей упавшей вниз,
    # либо мы передвигаем падающую часть на одну линию вниз.

    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)
예제 #25
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)
예제 #26
0
class TetrisGame(QMainWindow):
	def __init__(self):
		super().__init__()
		# 是否暂停ing
		self.is_paused = False
		# 是否开始ing
		self.is_started = False
		self.initUI()
	'''界面初始化'''
	def initUI(self):
		# 块大小
		self.grid_size = 22
		# 游戏帧率
		self.fps = 100
		self.timer = QBasicTimer()
		# 焦点
		self.setFocusPolicy(Qt.StrongFocus)
		# 水平布局
		layout_horizontal = QHBoxLayout()
		self.inner_board = InnerBoard()
		self.external_board = ExternalBoard(self, self.grid_size, self.inner_board)
		layout_horizontal.addWidget(self.external_board)
		self.side_panel = SidePanel(self, self.grid_size, self.inner_board)
		layout_horizontal.addWidget(self.side_panel)
		self.status_bar = self.statusBar()
		self.external_board.score_signal[str].connect(self.status_bar.showMessage)
		self.start()
		self.center()
		self.setWindowTitle('Tetris-公众号:Charles的皮卡丘')
		self.show()
		self.setFixedSize(self.external_board.width() + self.side_panel.width(),
						  self.side_panel.height() + self.status_bar.height())
		# AI控制
		self.tetris_ai = TetrisAI(self.inner_board)
		self.next_action = None
		self.pre_tetris = tetrisShape().shape_empty
	'''游戏界面移动到屏幕中间'''
	def center(self):
		screen = QDesktopWidget().screenGeometry()
		size = self.geometry()
		self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)
	'''更新界面'''
	def updateWindow(self):
		self.external_board.updateData()
		self.side_panel.updateData()
		self.update()
	'''开始'''
	def start(self):
		if self.is_started:
			return
		self.is_started = True
		self.inner_board.createNewTetris()
		self.timer.start(self.fps, self)
	'''暂停/不暂停'''
	def pause(self):
		if not self.is_started:
			return
		self.is_paused = not self.is_paused
		if self.is_paused:
			self.timer.stop()
			self.external_board.score_signal.emit('Paused')
		else:
			self.timer.start(self.fps, self)
		self.updateWindow()
	'''计时器事件'''
	def timerEvent(self, event):
		if event.timerId() == self.timer.timerId():
			if not self.next_action:
				self.next_action = self.tetris_ai.getNextAction()
			if self.next_action:
				while self.inner_board.current_direction != self.next_action[0]:
					self.inner_board.rotateAnticlockwise()
				count = 0
				while self.inner_board.current_coord[0] != self.next_action[1] and count < 5:
					if self.inner_board.current_coord[0] > self.next_action[1]:
						self.inner_board.moveLeft()
					else:
						self.inner_board.moveRight()
					count += 1
			removed_lines = self.inner_board.moveDown()
			self.external_board.score += removed_lines
			if self.pre_tetris != self.inner_board.current_tetris:
				self.next_action = None
				self.pre_tetris = self.inner_board.current_tetris
			self.updateWindow()
		else:
			super(TetrisGame, self).timerEvent(event)
	'''按键事件'''
	def keyPressEvent(self, event):
		if not self.is_started or self.inner_board.current_tetris == tetrisShape().shape_empty:
			super(TetrisGame, self).keyPressEvent(event)
			return
		key = event.key()
		# P键暂停
		if key == Qt.Key_P:
			self.pause()
			return
		if self.is_paused:
			return
		else:
			super(TetrisGame, self).keyPressEvent(event)
		self.updateWindow()
예제 #27
0
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 = 1

        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('俄罗斯方块')
        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():
            # 如果TETRIS_AI存在,则由AI进行下一步操作
            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()
        # P键暂停
        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()
예제 #28
0
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)
예제 #29
0
파일: tetrix.py 프로젝트: Axel-Erfurt/pyqt5
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)
예제 #30
0
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()
예제 #31
0
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)
예제 #32
0
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()
예제 #33
0
class Login(QWidget, Ui_Login):
    def __init__(self):
        super(Login, self).__init__()

        self.setupUi(self)
        self.flagMove = False
        self.setWindowFlags(
            Qt.FramelessWindowHint)  # 去掉标题栏的代码,这种顶部就不会出现空白,但是不能移动,需自己处理
        self.movie = QMovie('image/login/0.gif')
        self.label_2.setMovie(self.movie)
        self.movie.start()

        # 用户头像的一系列效果设置
        self.myQPushButton = MyQPushButton(self.slot_myQPushButton,
                                           self.frameGlobal)  # 重写的QPushButton类
        self.myQPushButton.setGeometry(234, 142, 16, 16)
        self.myQPushButton.setObjectName('myQPushButton')
        self.myQPushButton.setIcon(
            QIcon('image/login/8.png'))  # 默认的icon,可以从数据库中根据条件选择

        self.labUserImg_orgin_enterEvent = self.labUserImg.enterEvent  # 鼠标移入用户头像
        self.labUserImg_orgin_leaveEvent = self.labUserImg.leaveEvent  # 鼠标离开用户头像
        self.btnAddUser_orgin_enterEvent = self.btnAddUser.enterEvent  # 鼠标移入滑出的添加账号按钮
        self.btnAddUser_orgin_leaveEvent = self.btnAddUser.leaveEvent  # 鼠标离开滑出的添加账号按钮
        self.labUserImg.enterEvent = self.labUserImg_EnterEvent  # 绑定函数
        self.btnAddUser.enterEvent = self.btnAddUser_EnterEvent
        self.btnAddUser.leaveEvent = self.btnAddUser_LeaveEvent
        self.labUserImg.leaveEvent = self.labUserImg_LeaveEvent

        self.timer = QBasicTimer()  # 鼠标离开用户头像或者添加账号按钮时的计时器
        self.flagTimer = 0  # 鼠标离开用户头像或者添加账号按钮时的计时器的初始值
        self.timerBtnAddUserMove = QBasicTimer()  # 添加账号按钮移动开始至结束的计时事件
        self.btnAddUserX = 203  # 添加账号按钮水平位置x的滑出效果初始标记(这个值原本就是它的x位置)

        # 账号输入下拉列表的设置
        self.comboUserId.setView(
            QListView())  # 先随便设置一个QListView(),使下拉列表可以设置qss样式
        self.actionLeftUserID = QAction(self.comboUserId)
        self.actionLeftUserID.setIcon(QIcon("image/login/3.png"))
        self.comboUserId.lineEdit().addAction(
            self.actionLeftUserID, QLineEdit.LeadingPosition)  # 左侧图标
        self.comboUserId.lineEdit().setPlaceholderText('账号')  # 设置默认提示语
        self.comboUserId.addItem(QIcon("image/login/02.jpg"), "1235321111")
        self.comboUserId.addItem(QIcon("image/login/03.jpg"), "3745634222")
        # self.comboUserID.setItemData(2, QPixmap('image/login/4.png'), Qt.DecorationRole)  # 数据作为图标出现
        # self.comboUserID.setItemIcon(1, QIcon("image/login/4.png"))
        # self.comboUserID.setItemDelegate()
        # self.comboUserID.setItemData(0, 0, Qt.UserRole - 1)  # 锁定第0项。参数3如果是-256,第0项显示空字符
        self.comboUserId.setCurrentIndex(-1)  # 下拉列表初始设置为空,这样不用添加一个空的下拉项了
        self.comboUserId.activated[str].connect(self.slot_comboUserID)
        self.comboUserID_orgin_focusInEvent = self.comboUserId.focusInEvent  # 账号输入下拉列表获得焦点事件
        self.comboUserId.focusInEvent = self.comboUserID_FocusInEvent  # 账号输入下拉列表获得焦点事件的函数绑定
        self.comboUserID_orgin_focusOutEvent = self.comboUserId.focusOutEvent  # 账号输入下拉列表失去焦点事件
        self.comboUserId.focusOutEvent = self.comboUserID_FocusOutEvent  # 账号输入下拉列表失去焦点事件的函数绑定
        self.comboUserID_orgin_mousePressEvent = self.comboUserId.mousePressEvent  # 账号输入下拉列表鼠标按下事件
        self.comboUserId.mousePressEvent = self.comboUserID_MousePressEvent  # 账号输入下拉列表鼠标按下事件的函数绑定
        self.flagComboUserID = False  # 点击下拉箭头需要的标记

        # 密码框的设置
        self.actionLeftPassword = QAction(self.lEditPassword)
        self.actionLeftPassword.setIcon(QIcon("image/login/1.png"))
        self.actionRightPassword = QAction(self.lEditPassword)
        self.actionRightPassword.setIcon(QIcon("image/login/17.png"))
        self.actionRightPassword.triggered.connect(
            self.slot_actionRightPassword)
        self.menuKeyBoard = MyMenu(self)

        self.lEditPassword.addAction(self.actionLeftPassword,
                                     QLineEdit.LeadingPosition)  # 左侧图标
        self.lEditPassword.addAction(self.actionRightPassword,
                                     QLineEdit.TrailingPosition)  # 右侧图标
        self.lEditPassword.setPlaceholderText('密码')
        self.lEditPassword_orgin_focusInEvent = self.lEditPassword.focusInEvent
        self.lEditPassword.focusInEvent = self.lEditPassword_FocusInEvent
        self.lEditPassword_orgin_focusOutEvent = self.lEditPassword.focusOutEvent
        self.lEditPassword.focusOutEvent = self.lEditPassword_FocusOutEvent

        # 二维码登录界面frame的设置
        self.frameQRcodeUpdata_orgin_enterEvent = self.frameQRcodeUpdata.enterEvent  # 鼠标滑入更新二维码容器
        self.frameQRcodeUpdata.enterEvent = self.frameQRcodeUpdata_EnterEvent
        self.frameQRcodeUpdata_orgin_leaveEvent = self.frameQRcodeUpdata.leaveEvent  # 鼠标离开更新二维码容器
        self.frameQRcodeUpdata.leaveEvent = self.frameQRcodeUpdata_LeaveEvent
        self.timerFrameQRcodeUpdata = QBasicTimer()
        self.flagTimerFrameQRcodeUpdata = False
        self.flagTimerFrameQRcodeUpdataX = 115
        self.btnFrameQRcodeBack.clicked.connect(
            self.slot_btnQRcode_btnFrameQRcodeBack)

        # 一些控件的信号与槽的绑定,以及隐藏初始界面不应该显示的控件
        self.btnAddUser.hide()  # 先把添加账号按钮隐藏,鼠标移入self.labUserImg时再滑出
        self.btnLoginSingle.hide()  # 单账号登录按钮在self.btnAddUser被点击时才显示
        self.frameAdduser.hide()  # 此容器内的控件在self.btnAddUser被点击时才显示
        self.frameQRcode.hide()
        self.btnSignIn.clicked.connect(lambda: QDesktopServices.openUrl(
            QUrl(("https://ssl.zc.qq.com/v3/index-chs.html"))))
        self.btnFindBack.clicked.connect(lambda: QDesktopServices.openUrl(
            QUrl((
                "https://aq.qq.com/v2/uv_aq/html/reset_pwd/pc_reset_pwd_input_account.html"
            ))))

        self.btnSetting.clicked.connect(
            lambda: self.timerError.start(10, self))  # 以后再写设置界面
        self.btnQRcode.clicked.connect(self.slot_btnQRcode_btnFrameQRcodeBack)
        # self.btnQRcode.clicked.connect(lambda :self.timerError.start(10, self))
        self.btnAddUser.clicked.connect(self.slot_btnAddUser_btnLoginSingle)
        # self.btnAddUser.clicked.connect(lambda: self.timerError.start(10, self))
        self.btnLoginSingle.clicked.connect(
            self.slot_btnAddUser_btnLoginSingle)
        self.btnCancel.clicked.connect(self.slot_btnAddUser_btnLoginSingle)
        self.btnError.clicked.connect(lambda: self.timerError.start(10, self))

        self.btnSetting.clicked.connect(self.slot_btnSetting)

        # 模拟登录需要的一些数据及设置
        self.login_test()

        # # 界面滑出效果,如果y设置为1,界面出现的位置不对,尝试让界面y=330,然后隐藏,再进行滑出试试
        # # 同timerEvent事件中,elif e.timerId() == self.timerLoginShow.timerId():一起取消注释调试
        # self.setFixedHeight(1)
        # self.timerLoginShow = QBasicTimer()
        # self.timerLoginShow.start(1, self)
        # self.login_test()
    def slot_btnSetting(self):
        print(111)

    def login_test(self):
        """此函数内是模拟已经登录过此账号,发生的界面变化"""
        # USER_ID = '165227316'
        # USER_LOGINED_ON = True
        self.comboUserId.setEditText(USER_ID)
        self.lEditPassword.setText('xxxxxxxxxxx')
        self.checkBoxAotuLogin.click()
        self.checkBoxKeepPassword.click()
        # 测试提示信息的显示。self.frameError的位置是(0,330),是看不见的,因为窗口的固定高度就是330,所以这里把窗口的
        # 固定高度加上20(self.frameError的固定高度就是20),自然就显示出来了。self.frameGlobal的固定高度是330,没有变化
        self.timerError = QBasicTimer()
        if USER_LOGINED_ON:
            self.setFixedHeight(self.height() + 20)

    def slot_actionRightPassword(self):
        """在槽内setMenu,然后显示,才可以改变menu菜单的位置。
        如果在外面setMenu就不用self.menuKeyBoard.exec()方法了,直接点击就显示了。
        """
        self.actionRightPassword.setMenu(self.menuKeyBoard)
        pos = QPoint()
        pos.setX(93)
        pos.setY(233)
        self.menuKeyBoard.exec(self.mapToGlobal(pos))

    def slot_comboUserID(self, text):
        """选择下拉项后,重新设置显示为空项,再改变lineEdit的text"""
        self.comboUserId.setCurrentIndex(-1)
        self.comboUserId.lineEdit().setText(text)

    def slot_myQPushButton(self):
        """状态功能在此设置,因这程序只是一个登录界面,所以没写状态功能"""
        sender = self.sender()
        self.myQPushButton.setIcon(sender.icon())

    def slot_btnAddUser_btnLoginSingle(self):
        if self.sender() == self.btnAddUser:
            flag = True
            self.timerError.start(10, self)  # 如果有已经登录提示,开始计时器
        else:
            flag = False
            self.setFocus()

        self.frameAdduser.setVisible(flag)
        self.btnLoginSingle.setVisible(flag)

        self.frameLogin.setHidden(flag)
        self.btnSignIn.setHidden(flag)
        self.btnQRcode.setHidden(flag)

    def slot_btnQRcode_btnFrameQRcodeBack(self):
        if self.sender() == self.btnQRcode:
            flag = True
            self.timerError.start(10, self)  # 如果有已经登录提示,开始计时器
        else:
            flag = False

        self.frameGlobal.setHidden(flag)
        self.frameQRcode.setVisible(flag)
        self.btnFrameQRcodeUrl.hide()
        self.labFrameQRcodeErrorImg.hide()

    def labUserImg_EnterEvent(self, e):
        self.btnAddUser.show()
        self.flagTimer = 0
        self.timer.stop()
        self.timerBtnAddUserMove.start(3, Qt.PreciseTimer, self)
        return self.labUserImg_orgin_enterEvent(e)

    def labUserImg_LeaveEvent(self, e):
        self.timer.start(10, Qt.PreciseTimer, self)
        return self.labUserImg_orgin_leaveEvent(e)

    def btnAddUser_EnterEvent(self, e):
        self.flagTimer = 0
        self.timer.stop()
        return self.btnAddUser_orgin_enterEvent(e)

    def btnAddUser_LeaveEvent(self, e):
        self.timer.start(10, Qt.PreciseTimer, self)
        return self.btnAddUser_orgin_leaveEvent(e)

    def comboUserID_MousePressEvent(self, e):
        """处理点击下拉箭头后,使封装的lineEdit左侧图标变成蓝色"""
        self.flagComboUserID = True
        self.actionLeftUserID.setIcon(QIcon("image/login/4.png"))
        return self.comboUserID_orgin_mousePressEvent(e)

    def comboUserID_FocusInEvent(self, e):
        """
        获得焦点:改变图标,默认字符设置为空,再改变字符尺寸变大和颜色,就不影响视觉效果了(无内容时光标变小,
        有输入时光标变大)
        """
        self.actionLeftUserID.setIcon(QIcon("image/login/4.png"))
        self.comboUserId.lineEdit().setPlaceholderText('')
        self.comboUserId.setStyleSheet('font-size:17px;color:blank;')
        return self.comboUserID_orgin_focusInEvent(e)

    def comboUserID_FocusOutEvent(self, e):
        """失去焦点:恢复图标,恢复默认字符,再恢复字符尺寸变小和颜色"""
        self.actionLeftUserID.setIcon(QIcon("image/login/3.png"))
        self.comboUserId.lineEdit().setPlaceholderText('账号')
        if self.flagComboUserID:  # 如果点击了下拉箭头
            self.actionLeftUserID.setIcon(QIcon("image/login/4.png"))
            self.flagComboUserID = False  # 恢复标记,不然会一直判断是True,封装的lineEdit失去焦点时,左侧图标还是蓝色

        text = self.comboUserId.lineEdit().text()
        if text == '':  # 这个if,else语段,是处理让默认字符“密码”和有输入以及获得焦点时的字符大小不一样
            self.comboUserId.setStyleSheet('font-size:12px;color:#838383;')
        else:
            self.comboUserId.setStyleSheet('font-size:17px;color:blank;')
        return self.comboUserID_orgin_focusOutEvent(e)

    def lEditPassword_FocusInEvent(self, e):
        """获得焦点:改变图标,默认字符设置为空,再改变字符尺寸变大和颜色,就不影响视觉效果了"""
        self.actionLeftPassword.setIcon(QIcon("image/login/2.png"))
        self.lEditPassword.setPlaceholderText('')
        self.lEditPassword.setStyleSheet('font-size:16px;color:blank;')
        return self.lEditPassword_orgin_focusInEvent(e)

    def lEditPassword_FocusOutEvent(self, e):
        """失去焦点:恢复图标,恢复默认字符,再恢复字符尺寸变小和颜色"""
        self.actionLeftPassword.setIcon(QIcon("image/login/1.png"))
        self.lEditPassword.setPlaceholderText('密码')
        text = self.lEditPassword.text()
        if text == '':
            self.lEditPassword.setStyleSheet('font-size:12px;color:#838383;')
        else:
            self.lEditPassword.setStyleSheet('font-size:16px;color:blank;')
        return self.lEditPassword_orgin_focusOutEvent(e)

    def frameQRcodeUpdata_EnterEvent(self, e):
        """鼠标滑入更新二维码容器:"""
        self.timerFrameQRcodeUpdata.start(1, self)
        self.btnFrameQRcodeUrl.show()
        return self.frameQRcodeUpdata_orgin_enterEvent(e)

    def frameQRcodeUpdata_LeaveEvent(self, e):
        """鼠标离开更新二维码容器:"""
        self.timerFrameQRcodeUpdata.start(1, self)
        self.btnFrameQRcodeUrl.hide()
        return self.frameQRcodeUpdata_orgin_leaveEvent(e)

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            self.setFocus()  # 主要处理焦点在账号和密码框内时,左键窗口的焦点位置,让输入框失去焦点
            self.flagMove = True
            self.posMove = e.globalPos() - self.pos()  # 获取鼠标相对窗口的位置
            e.accept()
        elif e.button() == Qt.RightButton:  # 如果焦点在密码框里,右键窗口的焦点位置,账号框会得到焦点并全选
            if self.lEditPassword.hasFocus():
                self.comboUserId.setFocus()
                self.comboUserId.lineEdit().selectAll()

    def mouseMoveEvent(self, e):
        if Qt.LeftButton and self.flagMove:
            self.move(e.globalPos() - self.posMove)  # 更改窗口位置
            e.accept()

    def mouseReleaseEvent(self, e):
        self.flagMove = False

    def timerEvent(self, e):
        if e.timerId() == self.timerBtnAddUserMove.timerId():
            self.btnAddUser.move(self.btnAddUserX, 102)
            self.btnAddUserX += 1
            if self.btnAddUserX >= 273:
                self.timerBtnAddUserMove.stop()
                self.btnAddUserX = 203

        elif e.timerId() == self.timer.timerId():
            if self.flagTimer >= 40:
                self.btnAddUser.hide()
                self.timer.stop()
                self.flagTimer = 0
            self.flagTimer += 1

        elif e.timerId() == self.timerError.timerId():
            if self.height() == 330:
                self.timerError.stop()
            else:
                self.setFixedHeight(self.height() - 1)

        elif e.timerId() == self.timerFrameQRcodeUpdata.timerId():
            if self.flagTimerFrameQRcodeUpdata:
                self.flagTimerFrameQRcodeUpdataX += 1
                self.btnFrameQRcodeUpdata.move(
                    self.flagTimerFrameQRcodeUpdataX,
                    self.btnFrameQRcodeUpdata.y())
                if self.flagTimerFrameQRcodeUpdataX == 115:
                    self.timerFrameQRcodeUpdata.stop()
                    self.flagTimerFrameQRcodeUpdata = False
            elif not self.flagTimerFrameQRcodeUpdata:
                self.flagTimerFrameQRcodeUpdataX -= 1
                self.btnFrameQRcodeUpdata.move(
                    self.flagTimerFrameQRcodeUpdataX,
                    self.btnFrameQRcodeUpdata.y())
                if self.flagTimerFrameQRcodeUpdataX == 20:
                    self.timerFrameQRcodeUpdata.stop()
                    self.flagTimerFrameQRcodeUpdata = True
예제 #34
0
class Board(QFrame):
    # 自定义信号,将信息展示在状态栏
    msg2Statusbar = pyqtSignal(str)

    # 定义常量值
    BoardWidth = 10  # 块的宽度
    BoardHeight = 22  # 块的长度
    Speed = 300  # 下落的速度,即timer循环刷新速度

    def __init__(self, parent):
        # noinspection PyArgumentList
        super().__init__(parent)

        self.timer = QBasicTimer()
        self.isWaitingAfterLine = False

        self.curX = 0
        self.curY = 0
        self.numLinesRemoved = 0
        self.board = []  # 0到7的数字列表,表示面板上的形状和位置

        self.setFocusPolicy(Qt.StrongFocus)
        self.isStarted = False
        self.isPaused = False
        self.clear_board()

    def shape_at(self, x, y):
        return self.board[(y * Board.BoardWidth) + x]

    def set_shape_at(self, x, y, shape):
        self.board[(y * Board.BoardWidth) + x] = shape

    # 因为界面Board大小可以动态调整,所以方块的大小也要随着改变
    def square_width(self):
        return self.contentsRect().width() // Board.BoardWidth

    def square_height(self):
        return self.contentsRect().height() // Board.BoardHeight

    def start(self):

        if self.isPaused:
            return

        self.isStarted = True
        self.isWaitingAfterLine = False
        self.numLinesRemoved = 0
        self.clear_board()

        self.msg2Statusbar.emit(str(self.numLinesRemoved))

        self.new_piece()
        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()

        board_top = rect.bottom() - Board.BoardHeight * self.square_height()

        # 首先绘制所有已经落下去的方块
        for i in range(Board.BoardHeight):
            for j in range(Board.BoardWidth):
                shape = self.shape_at(j, Board.BoardHeight - i - 1)

                if shape != Tetrominoe.NoShape:
                    self.draw_square(painter,
                                     rect.left() + j * self.square_width(),
                                     board_top + i * self.square_height(), 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.draw_square(painter, rect.left() + x * self.square_width(),
                                 board_top + (Board.BoardHeight - y - 1) * self.square_height(),
                                 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()

        # p键暂停
        if key == Qt.Key_P:
            self.pause()
            return

        if self.isPaused:
            return

        # 左右移动
        elif key == Qt.Key_Left:
            self.try_move(self.curPiece, self.curX - 1, self.curY)

        elif key == Qt.Key_Right:
            self.try_move(self.curPiece, self.curX + 1, self.curY)

        # 旋转
        elif key == Qt.Key_Down:
            self.try_move(self.curPiece.rotate_right(), self.curX, self.curY)

        elif key == Qt.Key_Up:
            self.try_move(self.curPiece.rotate_left(), self.curX, self.curY)

        # 下降到底部
        elif key == Qt.Key_Space:
            self.drop_down()

        # 加速
        elif key == Qt.Key_D:
            self.one_line_down()

        else:
            super(Board, self).keyPressEvent(event)

    def timerEvent(self, event):
        """
        时间事件
        当前一个方块降落到底部后,创建一个新的方块
        """
        if event.timerId() == self.timer.timerId():

            if self.isWaitingAfterLine:
                self.isWaitingAfterLine = False
                self.new_piece()
            else:
                self.one_line_down()

        else:
            super(Board, self).timerEvent(event)

    def clear_board(self):
        """通过设置Tetrominoe.NoShape清除面板"""
        for i in range(Board.BoardHeight * Board.BoardWidth):
            self.board.append(Tetrominoe.NoShape)

    def drop_down(self):

        new_y = self.curY

        while new_y > 0:

            if not self.try_move(self.curPiece, self.curX, new_y - 1):
                break

            new_y -= 1

        self.piece_dropped()

    def one_line_down(self):

        if not self.try_move(self.curPiece, self.curX, self.curY - 1):
            self.piece_dropped()

    def piece_dropped(self):

        for i in range(4):
            x = self.curX + self.curPiece.x(i)
            y = self.curY - self.curPiece.y(i)
            self.set_shape_at(x, y, self.curPiece.shape())

        self.remove_full_lines()

        if not self.isWaitingAfterLine:
            self.new_piece()

    def remove_full_lines(self):
        """
        如果到达底部,会调用removeFullLines()方法。
        我们会检查所有完整的线条然后删除它们。
        然后移动所有行高于当前删除整行一行。
        请注意,我们反的顺序行被删除。否则,就会出错。
        """
        num_full_lines = 0
        rows_to_remove = []

        for i in range(Board.BoardHeight):

            n = 0
            for j in range(Board.BoardWidth):
                if not self.shape_at(j, i) == Tetrominoe.NoShape:
                    n = n + 1

            if n == 10:
                rows_to_remove.append(i)

        rows_to_remove.reverse()  # 反转

        for m in rows_to_remove:

            for k in range(m, Board.BoardHeight):
                for l in range(Board.BoardWidth):
                    self.set_shape_at(l, k, self.shape_at(l, k + 1))

        num_full_lines = num_full_lines + len(rows_to_remove)

        if num_full_lines > 0:
            self.numLinesRemoved = self.numLinesRemoved + num_full_lines
            self.msg2Statusbar.emit(str(self.numLinesRemoved))

            self.isWaitingAfterLine = True
            self.curPiece.set_shape(Tetrominoe.NoShape)
            self.update()

    def new_piece(self):
        """
        通过newPiece()方法创建一个新的方块
        如果不能进入它的初始位置,游戏就结束

        """
        self.curPiece = Shape()
        self.curPiece.set_random_shape()
        self.curX = Board.BoardWidth // 2 + 1
        self.curY = Board.BoardHeight - 1 + self.curPiece.min_y()

        if not self.try_move(self.curPiece, self.curX, self.curY):
            self.curPiece.set_shape(Tetrominoe.NoShape)
            self.timer.stop()
            self.isStarted = False
            self.msg2Statusbar.emit("Game over")

    def try_move(self, new_piece, new_x, new_y):
        """
        使用tryMove()方法尝试移动方块。
        如果方块的边缘已经接触到面板边缘或者不能移动,我们返回False。
        否则我们当前块下降到一个新的位置。
        """
        for i in range(4):

            x = new_x + new_piece.x(i)
            y = new_y - new_piece.y(i)

            if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
                return False

            if self.shape_at(x, y) != Tetrominoe.NoShape:
                return False

        self.curPiece = new_piece
        self.curX = new_x
        self.curY = new_y
        self.update()

        return True

    def draw_square(self, painter, x, y, shape):

        color_table = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
                       0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00]

        color = QColor(color_table[shape])
        painter.fillRect(x + 1, y + 1, self.square_width() - 2,
                         self.square_height() - 2, color)

        painter.setPen(color.lighter())
        painter.drawLine(x, y + self.square_height() - 1, x, y)
        painter.drawLine(x, y, x + self.square_width() - 1, y)

        painter.setPen(color.darker())
        painter.drawLine(x + 1, y + self.square_height() - 1,
                         x + self.square_width() - 1, y + self.square_height() - 1)
        painter.drawLine(x + self.square_width() - 1,
                         y + self.square_height() - 1, x + self.square_width() - 1, y + 1)
예제 #35
0
파일: main.py 프로젝트: yuk1ru/pentix
class GameState(QFrame):
    """Игровая модель"""
    status_bar_msg = pyqtSignal(str)
    player_data_msg = pyqtSignal(dict)
    records_msg = pyqtSignal()

    def __init__(self, parent):
        super().__init__(parent)

        self.timer = QBasicTimer()
        self.setFocusPolicy(Qt.StrongFocus)

    def start(self):
        """Начинаем игру"""
        self.game_board = Field(20, 10)
        self.shape = Shape()
        self.shape.new_shape(self.game_board)
        self.status_bar_msg.emit(str(self.game_board.score))
        self.timer.start(525, self)

    def send_player(self):
        name = QInputDialog.getText(None, "Get player name", "Player name:")
        if name[0]:
            self.player_data_msg.emit({name[0]: self.game_board.score})

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.game_board.score += 1
            self.status_bar_msg.emit(str(self.game_board.score))
            if self.game_board.is_game_over:
                self.timer.stop()
                self.status_bar_msg.emit("Game over!")
                self.send_player()
                self.records_msg.emit()
            elif self.game_board.want_new_shape:
                self.shape.new_shape(self.game_board)
                self.update()
            else:
                self.shape.move_down(self.game_board)
                self.update()
        else:
            super(GameState, self).timerEvent(event)

    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        self.draw(qp)
        qp.end()

    def draw_block(self, qp, x, y, color):
        """Рисуем отдельный блок"""
        color = QColor(color)
        col = QColor(self.game_board.grid_color)
        qp.setPen(col)

        qp.setBrush(color)
        qp.drawRect(x, y, 20, 20)

    def draw(self, qp):
        """Рисуем карту, рисуем фигуру (по блокам)"""
        for y in range(self.game_board.rows):
            for x in range(self.game_board.columns):
                if self.game_board.grid[y][x]:
                    self.draw_block(qp, x * 20, y * 20, self.shape.shape_color)
                else:
                    self.draw_block(qp, x * 20, y * 20,
                                    self.game_board.grid_color)

        for y in range(len(self.shape.shape)):
            for x in range(len(self.shape.shape[y])):
                if self.shape.shape[y][x]:
                    self.draw_block(qp, (x + self.shape.x) * 20,
                                    (y + self.shape.y) * 20,
                                    self.shape.shape_color)

    def keyPressEvent(self, event):
        if self.game_board.is_game_over:
            super(GameState, self).keyPressEvent(event)
            return
        if event.key() == Qt.Key_Left:
            self.shape.try_move(self.game_board, self.shape.x - 1,
                                self.shape.y)
            self.update()
        elif event.key() == Qt.Key_Right:
            self.shape.try_move(self.game_board, self.shape.x + 1,
                                self.shape.y)
            self.update()
        elif event.key() == Qt.Key_Down:
            self.shape.move_down(self.game_board)
            self.update()
        elif event.key() == Qt.Key_Space:
            self.shape.drop_down(self.game_board)
            self.update()
        elif event.key() == Qt.Key_Up:
            self.shape.rotate_shape(self.game_board, self.shape.x,
                                    self.shape.y)
            self.shape.try_move(self.game_board, self.shape.x, self.shape.y)
            self.update()
        else:
            super(GameState, self).keyPressEvent(event)
예제 #36
0
class TetrisGame(QMainWindow):
    def __init__(self):
        super().__init__()
        # 정지ing
        self.is_paused = False
        # 시작ing
        self.is_started = False
        self.initUI()

    '''인터페이스 초기화'''

    def initUI(self):
        # 테트리스 크기
        self.grid_size = 22
        # 게임 프레임률
        self.fps = 100
        self.timer = QBasicTimer()
        # 초점
        self.setFocusPolicy(Qt.StrongFocus)
        # 수평 배치
        layout_horizontal = QHBoxLayout()
        self.inner_board = InnerBoard()
        self.external_board = ExternalBoard(self, self.grid_size,
                                            self.inner_board)
        layout_horizontal.addWidget(self.external_board)
        self.side_panel = SidePanel(self, self.grid_size, self.inner_board)
        layout_horizontal.addWidget(self.side_panel)
        self.status_bar = self.statusBar()
        self.external_board.score_signal[str].connect(
            self.status_bar.showMessage)
        self.start()
        self.center()
        self.setWindowTitle
        self.show()
        self.setFixedSize(
            self.external_board.width() + self.side_panel.width(),
            self.side_panel.height() + self.status_bar.height())
        # AI 제어
        self.tetris_ai = TetrisAI(self.inner_board)
        self.next_action = None
        self.pre_tetris = tetrisShape().shape_empty

    '''게임 인터페이스가 화면 가운데로 이동'''

    def center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) // 2,
                  (screen.height() - size.height()) // 2)

    '''업데이트 인터페이스'''

    def updateWindow(self):
        self.external_board.updateData()
        self.side_panel.updateData()
        self.update()

    '''시작'''

    def start(self):
        if self.is_started:
            return
        self.is_started = True
        self.inner_board.createNewTetris()
        self.timer.start(self.fps, self)

    '''일시정지/무정지'''

    def pause(self):
        if not self.is_started:
            return
        self.is_paused = not self.is_paused
        if self.is_paused:
            self.timer.stop()
            self.external_board.score_signal.emit('Paused')
        else:
            self.timer.start(self.fps, self)
        self.updateWindow()

    '''크로노그래프 사건'''

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            if not self.next_action:
                self.next_action = self.tetris_ai.getNextAction()
            if self.next_action:
                while self.inner_board.current_direction != self.next_action[0]:
                    self.inner_board.rotateAnticlockwise()
                count = 0
                while self.inner_board.current_coord[0] != self.next_action[
                        1] and count < 5:
                    if self.inner_board.current_coord[0] > self.next_action[1]:
                        self.inner_board.moveLeft()
                    else:
                        self.inner_board.moveRight()
                    count += 1
            removed_lines = self.inner_board.moveDown()
            self.external_board.score += removed_lines
            if self.pre_tetris != self.inner_board.current_tetris:
                self.next_action = None
                self.pre_tetris = self.inner_board.current_tetris
            self.updateWindow()
        else:
            super(TetrisGame, self).timerEvent(event)

    '''버튼 '''

    def keyPressEvent(self, event):
        if not self.is_started or self.inner_board.current_tetris == tetrisShape(
        ).shape_empty:
            super(TetrisGame, self).keyPressEvent(event)
            return
        key = event.key()
        # P 키 타임
        if key == Qt.Key_P:
            self.pause()
            return
        if self.is_paused:
            return
        else:
            super(TetrisGame, self).keyPressEvent(event)
        self.updateWindow()
예제 #37
0
class App(qw.QMainWindow):
    def __init__(self):
        super().__init__()
        self.block_size = 30

        # одна из фич
        self.saved_games = deque(maxlen=3)

        self.timer = QBasicTimer()
        self.status_bar = self.statusBar()

        self.cols = 15
        self.rows = 15
        self.colors_num = 5
        self.name = 'Player'
        self._default_name = True

        self.setWindowTitle('Blocks')
        # статистика
        self.last_stats = ('You', self.cols, self.rows, 0)
        self.game = Blocks(self.cols, self.rows, self.colors_num, self.name)
        self.game.start_new_game()

        self.editor = Editor()
        self.editor.butt_ok.clicked.connect(self.edit_settings_close_editor)

        self.sl_menu = None
        self.score_table = None
        self.highest = CountHighest(self.game, 2)

        new_act = qw.QAction('&New Game', self)
        new_act.setStatusTip('Start new game')
        new_act.triggered.connect(self.start_new_game)
        again_act = qw.QAction('&Play Again', self)
        again_act.setStatusTip('Start new game with the same field')
        again_act.triggered.connect(self.start_again)
        score_act = qw.QAction('&Score Table', self)
        score_act.setStatusTip('Show score table')
        score_act.setShortcut('Ctrl+T')
        score_act.triggered.connect(self.open_score_table)
        exit_act = qw.QAction('&Exit', self)
        exit_act.setShortcut('Ctrl+Q')
        exit_act.setStatusTip('Exit application')
        exit_act.triggered.connect(sys.exit)

        edit_act = qw.QAction('&Edit Settings', self)
        edit_act.setShortcut('Ctrl+E')
        edit_act.setStatusTip('Change nickname and field size')
        edit_act.triggered.connect(self.open_editor)

        save_act = qw.QAction('&Save', self)
        save_act.setShortcut('Ctrl+S')
        save_act.triggered.connect(lambda: self.status_bar.showMessage(
            self.save_game()))
        load_act = qw.QAction('&Load', self)
        load_act.setShortcut('Ctrl+L')
        load_act.triggered.connect(self.open_loader)

        count_act = qw.QAction('&Count Highest Score', self)
        count_act.setStatusTip('It is a long process, '
                               'some game features will be unavailable')
        count_act.triggered.connect(self.count_highest)
        cancel_act = qw.QAction('&Cancel Counting', self)
        cancel_act.triggered.connect(lambda: self.stop_counting())

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&Game')
        file_menu.addAction(new_act)
        file_menu.addAction(again_act)
        file_menu.addAction(score_act)
        file_menu.addAction(exit_act)
        edit_menu = menubar.addMenu('&Edit')
        edit_menu.addAction(edit_act)
        save_menu = menubar.addMenu('&Save/Load')
        save_menu.addAction(save_act)
        save_menu.addAction(load_act)
        other_menu = menubar.addMenu('&Other')
        other_menu.addAction(count_act)
        other_menu.addAction(cancel_act)

        self.acts_to_lock = (count_act, )

        self.canvas = Canvas(self.game, self.block_size, self)

        self.score_total = qw.QLCDNumber(self)
        self.score_total.display(self.game.score())
        self.score_total.setSegmentStyle(qw.QLCDNumber.Flat)
        self.score_total.setStyleSheet("""color: black; background: white;""")
        self.score_curr = qw.QLCDNumber(self)
        self.score_curr.display(Blocks.count_score(self.game.highlighted()))
        self.score_curr.setSegmentStyle(qw.QLCDNumber.Flat)
        self.score_curr.setStyleSheet("""color: black; background: white;""")
        scores_layout = qw.QHBoxLayout()
        scores_layout.addWidget(self.score_total)
        scores_layout.addWidget(self.score_curr)

        self.main_layout = qw.QVBoxLayout()
        self.main_layout.addWidget(self.canvas)
        self.main_layout.addLayout(scores_layout)

        self.centr_wid = qw.QWidget(self)
        self.centr_wid.setLayout(self.main_layout)
        self.setCentralWidget(self.centr_wid)

        self.resize_window()
        self.show()
        self.timer.start(40, self)

    def open_loader(self):
        saves = [save for save in self.saved_games]
        if saves:
            self.sl_menu = SaveLoadMenu(saves)
            [self._set_button_clicked(slot) for slot in self.sl_menu.slots]
            self.sl_menu.show()

    def _set_button_clicked(self, slot):
        slot[0].clicked.connect(lambda: self._load_game(slot[1]))

    def _load_game(self, game: Blocks):
        self.timer.stop()
        self.stop_counting()
        g = deepcopy(game)
        self.game = g
        self.canvas.game = g
        self.resize_window()
        self.timer.start(40, self)
        self.sl_menu.hide()

    def save_game(self):
        self.saved_games.append(deepcopy(self.game))
        return 'Game saved'

    def edit_settings_close_editor(self):
        self.timer.stop()
        self.stop_counting()
        settings = self.editor.get_info()
        self.editor.hide()
        self.cols, self.rows, self.colors_num = settings
        self.game.change_settings(*settings)
        self.start_new_game()
        self.setWindowTitle('Blocks ({})'.format(self.name))

    def open_editor(self):
        self.editor.pass_info(
            self.cols,
            self.rows,
            self.colors_num)
        self.editor.show()

    def open_score_table(self):
        self.score_table = ScoreTable(self.last_stats)
        self.score_table.show()

    def count_highest(self):
        self.highest = CountHighest(self.game, 2)
        self.highest.fin.connect(self.show_highest)
        [act.setDisabled(True) for act in self.acts_to_lock]
        self.highest.start()

    def show_highest(self, highest: int):
        self.stop_counting()
        self.status_bar.showMessage(
            'Possible highest score: {}'.format(highest))

    def stop_counting(self):
        self.highest.shutdown()
        [act.setDisabled(False) for act in self.acts_to_lock]

    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.update_ui()
            if self.game.gameover() is True:
                self.on_gameover()
        else:
            super(App.self).timerEvent(self, event)

    def update_ui(self):
        self.score_total.display(self.game.score())
        self.score_total.update()
        self.score_curr.display(Blocks.count_score(self.game.highlighted()))
        self.score_curr.update()
        self.canvas.update()

    def on_gameover(self):
        self.timer.stop()

        if self._default_name:
            text, ok = qw.QInputDialog.getText(
                self, 'Blocks',
                'Enter your name:', text='Player')
            self.name = text or 'Player' if ok else 'Player'
            self._default_name = False
            self.game.change_settings(
                self.game.cols(),
                self.game.rows(),
                self.game.colors_num(),
                self.name)

        self.last_stats = (
            self.game.name(),
            self.game.cols(),
            self.game.rows(),
            self.game.score())
        BlocksStatSaver.save_to_stats(self.game)
        choice = qw.QMessageBox.question(
            self, 'Game Over! (Score: {})'.format(self.game.score()),
            "Do you want to start a new game?",
            qw.QMessageBox.Yes | qw.QMessageBox.Reset | qw.QMessageBox.No)
        if choice == qw.QMessageBox.Yes:
            self.start_new_game()
        elif choice == qw.QMessageBox.Reset:
            self.start_again()
        else:
            sys.exit()

    def start_new_game(self):
        self.stop_counting()
        self.game.start_new_game()
        self.resize_window()
        self.timer.start(40, self)

    def start_again(self):
        self.stop_counting()
        self.game.start_again()
        self.resize_window()
        self.timer.start(40, self)

    def resize_window(self):
        self.cols = self.game.cols()
        self.rows = self.game.rows()
        self.name = self.game.name()
        self.colors_num = self.game.colors_num()
        self.canvas.setFixedSize(
            self.cols * self.block_size,
            self.rows * self.block_size)
        self.setFixedWidth(self.cols * self.block_size + 20)
        self.setFixedHeight(self.rows * self.block_size + 100)
        self.setWindowTitle('Blocks ({})'.format(self.name))
예제 #38
0
        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.ourScore = self.numLinesRemoved * 100
                    self.msg2Statusbar.emit(str(self.ourScore))
                    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("Игра окончена")

                    root = Tk()
                    root.geometry("400x400")
                    root.title("Игра окончена")
                    v = StringVar()
                    text1 = Label(width=50,
                                  height=2,
                                  font='Arial 12',
                                  text="Игра окончена, вы заработали " +
                                  str(self.ourScore) + " очков.")
                    text2 = Label(width=50,
                                  height=2,
                                  font='Arial 12',
                                  text="Пожалуйста укажите свое имя:")
                    mylogin = Entry(textvariable=v, width=30)
                    button1 = Button(
                        width=30,
                        height=5,
                        text="Сохранить результат",
                        font='Arial 12',
                        command=lambda: login(mylogin.get(), self.ourScore))
                    button2 = Button(width=30,
                                     height=5,
                                     text="Выйти без сохранения",
                                     font='Arial 12',
                                     command=lambda: closing())
                    text1.pack(side=TOP)
                    text2.pack(side=TOP)
                    mylogin.pack(side=TOP)
                    button1.pack(side=TOP)
                    button2.pack(side=TOP)

                    def login(username, userscore):
                        c.execute(
                            "INSERT INTO records (name,score) VALUES ('%s','%s')"
                            % (str(username), userscore))
                        conn.commit()
                        messagebox.showinfo("Сохранение",
                                            "Ваш результат успешно сохранен.")
                        c.close()
                        conn.close()
                        sys.exit()

                    def closing():
                        if messagebox.askokcancel(
                                "Выход", "Вы действительно хотите выйти?"):
                            root.destroy()
                            sys.exit()

                    root.protocol("WM_DELETE_WINDOW", closing)

                    root.mainloop()

            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)
예제 #39
0
class WidgetCode(QLabel):
    
    def __init__(self, *args, **kwargs):
        super(WidgetCode, self).__init__(*args, **kwargs)
        self._sensitive = False  # 是否大小写敏感
        self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.setBackgroundRole(QPalette.Midlight)
        self.setAutoFillBackground(True)
        # 字体
        newFont = self.font()
        newFont.setPointSize(16)
        newFont.setFamily("Kristen ITC")
        newFont.setBold(True)
        self.setFont(newFont)
        self.reset()
        # 定时器
        self.step = 0
        self.timer = QBasicTimer()
        self.timer.start(60, self)
        
    def reset(self):
        self._code = "".join(sample(WORDS, 4))  # 随机4个字符
        self.setText(self._code)
    
    def check(self, code):
        return self._code == str(code) if self._sensitive else self._code.lower() == str(code).lower()
    
    def setSensitive(self, sensitive):
        self._sensitive = sensitive
    
#     def setText(self, text):
#         text = text if (text and len(text) == 4) else "".join(sample(WORDS, 4))  # 随机4个字符
#         self._code = str(text)
#         html = "".join([FONT.format(color=COLORLIST[qrand() % 6], word=t) for t in text])
#         super(WidgetCode, self).setText(HTML.format(html=html))
    
    def mouseReleaseEvent(self, event):
        super(WidgetCode, self).mouseReleaseEvent(event)
        self.reset()
    
    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.step += 1
            return self.update()
        return super(WidgetCode, self).timerEvent(event)
    
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        # 背景白色
        painter.fillRect(event.rect(), QBrush(Qt.white))
        # 绘制边缘虚线框
        painter.setPen(Qt.DashLine)
        painter.setBrush(Qt.NoBrush)
        painter.drawRect(self.rect())
        # 随机画条线
        for _ in range(3):
            painter.setPen(QPen(QTCOLORLIST[qrand() % 5], 1, Qt.SolidLine))
            painter.setBrush(Qt.NoBrush)
            painter.drawLine(QPoint(0, qrand() % self.height()),
                             QPoint(self.width(), qrand() % self.height()))
            painter.drawLine(QPoint(qrand() % self.width(), 0),
                             QPoint(qrand() % self.width(), self.height()))
        # 绘制噪点
        painter.setPen(Qt.DotLine)
        painter.setBrush(Qt.NoBrush)
        for _ in range(self.width()):  # 绘制噪点
            painter.drawPoint(QPointF(qrand() % self.width(), qrand() % self.height()))
        # super(WidgetCode, self).paintEvent(event)  # 绘制文字
        # 绘制跳动文字
        metrics = QFontMetrics(self.font())
        x = (self.width() - metrics.width(self.text())) / 2
        y = (self.height() + metrics.ascent() - metrics.descent()) / 2
        for i, ch in enumerate(self.text()):
            index = (self.step + i) % 16
            painter.setPen(TCOLORLIST[qrand() % 6])
            painter.drawText(x, y - ((SINETABLE[index] * metrics.height()) / 400), ch)
            x += metrics.width(ch)
예제 #40
0
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)
예제 #41
0
파일: gui.py 프로젝트: sulovm/starsMaze
class Field(QWidget):

    def __init__(self, game):
        super().__init__()
        self.init_field(game)

    def init_field(self, game):
        self.game = game
        self.ways = Ways()
        self.timer = QBasicTimer()
        self.height = self.game.field.get_height()
        self.width = self.game.field.get_width()
        self.mat = self.game.field
        grid = QGridLayout()
        self.setLayout(grid)
        grid.setSpacing(1)
        self.draw()
        self.timer.start(600, self)

    def draw(self):
        """Draws the game field each time a change occurs."""
        grid = self.layout()
        width, height = self.width, self.height
        mat = self.game.field.mat

        for i in range(height):
            for j in range(width):
                tile = Tile(str(mat[i][j]))
                tile.setStyle(mat[i][j])
                grid.addWidget(tile, i, j)

        label1 = QLabel('Health: {} Energy: {} Stars: {}'.format(
            self.game.player.get_health(),
            self.game.player.get_energy(),
            self.game.player.get_stars()))
        grid.addWidget(label1, height, 0, 1, width - 1)
        label2 = QLabel('>>')
        label2.setStyleSheet("qproperty-alignment: AlignRight;")
        grid.addWidget(label2, height, width - 1, 1, width)
        if (self.game.state is not State.running):
            lev_num = ''
        else:
            lev_num = str(self.game.level)
        label3 = QLabel('{}{}'.format(self.game.state.value, lev_num))
        grid.addWidget(label3, height + 1, 0, 1, width)

    def clear(self):
        """Removes all widgets before each drawing."""
        grid = self.layout()
        width, height = self.width, self.height

        grid.itemAt(height + 1).widget().setParent(None)
        grid.itemAt(height + width - 1).widget().setParent(None)
        grid.itemAt(height).widget().setParent(None)
        for i in reversed(range(height)):
            for j in reversed(range(width)):
                grid.itemAt(i * height + j).widget().setParent(None)


    def move_current_up(self):
        """Moves the player up and draws the new field."""
        self.game.move_current_up()
        self.clear()
        self.draw()
        if self.game.state is State.won:
            self.message(1)
        if self.game.state is State.lost:
            self.message(2)

    def move_current_down(self):
        """Moves the player down, draws the new field and checks for end of level."""
        self.game.move_current_down()
        self.clear()
        self.draw()
        if self.game.x == self.height - 1 and self.game.y == self.width - 1:
            if self.game.player.enough_stars():
                self.switch_levels()
            else:
                self.message(0)
        if self.game.state is State.won:
            self.message(1)
        if self.game.state is State.lost:
            self.message(2)

    def move_current_left(self):
        """Moves the player left and draws the new field."""
        self.game.move_current_left()
        self.clear()
        self.draw()
        if self.game.state is State.won:
            self.message(1)
        if self.game.state is State.lost:
            self.message(2)

    def move_current_right(self):
        """Moves the player right, draws the new field and checks for end of level."""
        self.game.move_current_right()
        self.clear()
        self.draw()
        if self.game.x == self.height - 1 and self.game.y == self.width - 1:
            if self.game.player.enough_stars():
                self.switch_levels()
            else:
                self.message(0)
        if self.game.state is State.won:
            self.message(1)
        if self.game.state is State.lost:
            self.message(2)

    def move_x(self, place, way):
        """Specifies the direction of moving of a X."""
        letter = way[0]
        if letter == 'u':
            self.game.move_x_up(place)
        if letter == 'd':
            self.game.move_x_down(place)
        if letter == 'l':
            self.game.move_x_left(place)
        if letter == 'r':
            self.game.move_x_right(place)
        way += letter
        way.pop(0)

    def keyPressEvent(self, event):
        if self.game.state is State.paused:
            key = event.key()
            if key == Qt.Key_P:
                self.unpause()
            else:
                super(Field, self).keyPressEvent(event)
            return
        if self.game.state is not State.running:
            super(Field, self).keyPressEvent(event)
            return
        key = event.key()
        if key == Qt.Key_Up:
            self.move_current_up()
        elif key == Qt.Key_Down:
            self.move_current_down()
        elif key == Qt.Key_Left:
            self.move_current_left()
        elif key == Qt.Key_Right:
            self.move_current_right()
        elif key == Qt.Key_P:
            self.pause()
        else:
            super(Field, self).keyPressEvent(event)

    def timerEvent(self, event):
        if self.game.state is not State.running:
            super(Field, self).timerEvent(event)
            return
        lev = self.game.level - 1
        if event.timerId() == self.timer.timerId() and self.ways.ways[lev] != []:
            for moving_x in self.ways.ways[lev]:
                self.move_x(moving_x['place'], moving_x['way'])
            self.clear()
            self.draw()
            if self.game.state is State.lost:
                self.message(2)
        else:
            super(Field, self).timerEvent(event)

    def switch_levels(self):
        self.game.new_level()
        self.mat = self.game.field
        self.clear()
        self.draw()

    def pause(self):
        self.game.pause()
        self.clear()
        self.draw()

    def unpause(self):
        self.game.unpause()
        self.clear()
        self.draw()

    def message(self, text_no):
        texts = [
            "You must collect all {} stars to continue!".format(self.game.player.STARS),
            "You win! Congratulations!",
            "Game over! Good luck next time!"]
        msgBox = QMessageBox()
        msgBox.setText(texts[text_no])
        msgBox.exec_()