Compare commits
5 Commits
157b7e3c90
...
44cb7a697b
Author | SHA1 | Date |
---|---|---|
|
44cb7a697b | |
|
d815281abc | |
|
9ce1ae0ff7 | |
|
de5af7cb44 | |
|
b7eba38f0f |
|
@ -1,9 +1,9 @@
|
|||
# About
|
||||
This is just a Sudoku program written in python using the PyQt5 library. It's supposed to be a learning experience
|
||||
about the graphics system of PyQt. The goal(?) is to make it as animated as possible.
|
||||
This is just a Sudoku program written in python using the PySide2 library. It's supposed to be a learning experience
|
||||
about the graphics system of PyQt.
|
||||
|
||||
## Requirements
|
||||
Requires `Python 3`, `PyQt5`, and `Numpy`.
|
||||
Requires `Python 3`, `PySide2`, and `Numpy`.
|
||||
|
||||
Use the requirements.txt to install the dependencies.
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@ def generate_completed_grid(n):
|
|||
|
||||
def generate_dig_sequence(difficulty):
|
||||
if difficulty <= 1:
|
||||
# Random Digging
|
||||
random_number = list(range(81))
|
||||
while len(random_number) > 0:
|
||||
yield random_number.pop(random.randint(0, len(random_number)-1))
|
||||
elif difficulty == 2:
|
||||
# Skip one cell
|
||||
current = 0
|
||||
while current < 162:
|
||||
actual = current % 81
|
||||
|
@ -57,6 +59,7 @@ def generate_dig_sequence(difficulty):
|
|||
yield (row+1) * 9 - 1 - (actual % 9) % 81
|
||||
current += 2
|
||||
elif difficulty == 3:
|
||||
# S wandering
|
||||
current = 0
|
||||
while current < 81:
|
||||
row = int(current / 9)
|
||||
|
@ -66,6 +69,7 @@ def generate_dig_sequence(difficulty):
|
|||
yield (row+1) * 9 - 1 - (current % 9)
|
||||
current += 1
|
||||
elif difficulty == 4:
|
||||
# Left-to-right, top-to-bottom
|
||||
current = 0
|
||||
while current < 81:
|
||||
yield current
|
||||
|
|
|
@ -3,7 +3,7 @@ of the boards."""
|
|||
|
||||
from PySide2.QtGui import QPen
|
||||
from PySide2.QtWidgets import QSizePolicy, QGraphicsWidget
|
||||
from PySide2.QtCore import (QAbstractAnimation, Qt, QLineF, QPropertyAnimation, Property, Signal, QSizeF, QRectF)
|
||||
from PySide2.QtCore import (QAbstractAnimation, Qt, QLineF, QPropertyAnimation, Property, Signal, QSizeF, QRectF, QTimer)
|
||||
|
||||
from . import sudoku_graphics as sdk_grap
|
||||
from . import menu_graphics as menu_grap
|
||||
|
@ -147,7 +147,7 @@ class GameBoard(BoxBoard):
|
|||
self.numring = sdk_grap.NumberRing(parent=self)
|
||||
self.playmenu = sdk_grap.PlayMenu(parent=self)
|
||||
|
||||
self.gamegrid.setFocus(Qt.MouseFocusReason)
|
||||
#self.gamegrid.setFocus(Qt.MouseFocusReason)
|
||||
self.show_grid(False)
|
||||
self.show_playmenu(False)
|
||||
|
||||
|
@ -161,6 +161,10 @@ class GameBoard(BoxBoard):
|
|||
self.anim.finished.connect(lambda: self.show_playmenu(True))
|
||||
self.toggle_anim(True)
|
||||
|
||||
self.refocus_timer = QTimer()
|
||||
self.refocus_timer.timeout.connect(self.game_refocus)
|
||||
self.refocus_timer.setSingleShot(True)
|
||||
|
||||
def show_number_ring(self, x=0, y=0, scribbling=False):
|
||||
"""Display the Number Ring if it is not visible, while setting the focus to it
|
||||
|
||||
|
@ -174,6 +178,7 @@ class GameBoard(BoxBoard):
|
|||
True to set Scribble mode, False otherwise
|
||||
"""
|
||||
if not self.numring.isVisible():
|
||||
self.game_unfocus()
|
||||
self.numring.setPos(x, y)
|
||||
self.numring.setVisible(True)
|
||||
self.numring.setFocus()
|
||||
|
@ -201,9 +206,17 @@ class GameBoard(BoxBoard):
|
|||
"""Enable the grid and give it grid focus
|
||||
"""
|
||||
self.gamegrid.set_disabled(False)
|
||||
self.gamegrid.setFocus()
|
||||
#self.gamegrid.setFocus()
|
||||
self.gamegrid.scribbling = self.numring.scribbling # To update the grid scribbling mode
|
||||
|
||||
def game_unfocus(self):
|
||||
"""Enable the grid and give it grid focus
|
||||
"""
|
||||
self.gamegrid.set_disabled(True)
|
||||
#self.gamegrid.setFocus()
|
||||
#self.gamegrid.scribbling = self.numring.scribbling # To update the grid scribbling mode
|
||||
|
||||
|
||||
def show_grid(self, state):
|
||||
"""Show the grid, if it is not; Hide the grid, if it is.
|
||||
Note: Animation only plays when showing the grid.
|
||||
|
|
|
@ -64,6 +64,7 @@ class AnimBox(QGraphicsObject):
|
|||
|
||||
self.line_order = [self.up, self.right, self.down, self.left]
|
||||
|
||||
self.accepted_buttons = Qt.LeftButton
|
||||
self.set_freeze(False)
|
||||
|
||||
self.length = 0
|
||||
|
@ -85,7 +86,7 @@ class AnimBox(QGraphicsObject):
|
|||
self.setAcceptedMouseButtons(Qt.NoButton)
|
||||
self.setAcceptHoverEvents(False)
|
||||
else:
|
||||
self.setAcceptedMouseButtons(Qt.LeftButton)
|
||||
self.setAcceptedMouseButtons(self.accepted_buttons)
|
||||
self.setAcceptHoverEvents(True)
|
||||
|
||||
def toggle_anim(self, toggling):
|
||||
|
@ -201,7 +202,7 @@ class RingButton(AnimBox):
|
|||
buttonClicked: Signal(str)
|
||||
Emitted when it is clicked. Sends the text of the button
|
||||
"""
|
||||
buttonClicked = Signal(str)
|
||||
buttonClicked = Signal(str, int)
|
||||
|
||||
# Initialisation
|
||||
def __init__(self, x, y, width, height, text, parent=None):
|
||||
|
@ -216,6 +217,7 @@ class RingButton(AnimBox):
|
|||
super().__init__(x, y, width, height, parent=parent)
|
||||
self.text = text
|
||||
self.transparent = False
|
||||
self.accepted_buttons = self.accepted_buttons | Qt.RightButton
|
||||
|
||||
def set_transparent(self, state):
|
||||
"""Make the button transparent
|
||||
|
@ -252,7 +254,7 @@ class RingButton(AnimBox):
|
|||
"""
|
||||
event.accept()
|
||||
self.toggle_anim(False)
|
||||
self.buttonClicked.emit(self.text)
|
||||
self.buttonClicked.emit(self.text, event.button())
|
||||
|
||||
|
||||
class MenuButton(AnimBox):
|
||||
|
|
|
@ -84,23 +84,19 @@ class TimerDisplayer(QGraphicsWidget):
|
|||
|
||||
|
||||
class DifficultyDisplayer(QGraphicsWidget):
|
||||
<<<<<<< HEAD
|
||||
notFocus = Signal()
|
||||
difficultySelected = Signal(str)
|
||||
=======
|
||||
"""Display the current difficulty. Clicking on it displays the difficulty menu.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
notFocus: pyqtSignal
|
||||
notFocus: Signal
|
||||
Emitted when it loses focus
|
||||
|
||||
difficultySelected = pyqtSignal(str)
|
||||
difficultySelected = Signal(str)
|
||||
Emitted when a difficulty is selected. Emits the selected difficulty
|
||||
"""
|
||||
notFocus = pyqtSignal()
|
||||
difficultySelected = pyqtSignal(str)
|
||||
>>>>>>> Document menu_graphics
|
||||
notFocus = Signal()
|
||||
difficultySelected = Signal(str)
|
||||
menuClicked = Signal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Create the box and the text.
|
||||
|
@ -119,6 +115,7 @@ class DifficultyDisplayer(QGraphicsWidget):
|
|||
self.diff_menu = DifficultyMenu(self.width, self.height, self)
|
||||
self.diff_menu.setY(-self.diff_menu.height)
|
||||
self.diff_menu.setVisible(False)
|
||||
self.diff_menu.menuClicked.connect(self.menuClicked.emit)
|
||||
|
||||
self.box_pen = QPen()
|
||||
self.box_pen.setColor(Qt.white)
|
||||
|
@ -167,6 +164,7 @@ class DifficultyDisplayer(QGraphicsWidget):
|
|||
if not self.diff_menu.isVisible():
|
||||
self.diff_menu.setFocus()
|
||||
self.diff_menu.setVisible(True)
|
||||
#self.clicked.emit()
|
||||
else:
|
||||
self.diff_menu.setVisible(False)
|
||||
self.notFocus.emit()
|
||||
|
@ -247,7 +245,7 @@ class DifficultyMenu(QGraphicsWidget):
|
|||
return QRectF(0, 0, self.width, self.height)
|
||||
|
||||
def clicked_on(self, string):
|
||||
"""Emits the menuCLicked signal with the selected difficulty, when one of the buttons is pressed.
|
||||
"""Emits the menuClicked signal with the selected difficulty, when one of the buttons is pressed.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
|
|
@ -192,7 +192,7 @@ class SudokuGrid(BaseSudokuItem):
|
|||
|
||||
self.setAcceptHoverEvents(True)
|
||||
self.setAcceptedMouseButtons(Qt.LeftButton)
|
||||
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
||||
#self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
||||
self.set_disabled(False)
|
||||
|
||||
# Set up the animation
|
||||
|
@ -326,18 +326,19 @@ class SudokuGrid(BaseSudokuItem):
|
|||
|
||||
if not self.sudoku_grid.get_cell_status(self.mouse_h, self.mouse_w) == sdk.FIXED:
|
||||
self.buttonClicked.emit(w, h, self.scribbling)
|
||||
self.set_disabled(True)
|
||||
else:
|
||||
self.buttonClicked.emit(0, 0, self.scribbling)
|
||||
|
||||
def focusInEvent(self, event):
|
||||
#def focusInEvent(self, event):
|
||||
"""Reimplemented from QGraphicsObject. Unfreeze the grid on focus
|
||||
"""
|
||||
self.set_disabled(False)
|
||||
#self.set_disabled(False)
|
||||
|
||||
def focusOutEvent(self, event):
|
||||
#def focusOutEvent(self, event):
|
||||
"""Reimplemented from QGraphicsObject. Freeze the grid when out of focus
|
||||
"""
|
||||
self.set_disabled(True)
|
||||
#self.set_disabled(True)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
"""Reimplemented from QGraphicsObject. Check if scribble key is held, toggling on scribbling mode.
|
||||
|
@ -465,7 +466,7 @@ class NumberRing(BaseSudokuItem):
|
|||
"""
|
||||
pass
|
||||
|
||||
def send_button_press(self, val):
|
||||
def send_button_press(self, val, btn):
|
||||
"""Emits the keyPressed signal if any of the buttons is pressed, and attempts to close the ring
|
||||
|
||||
Parameters
|
||||
|
@ -473,8 +474,10 @@ class NumberRing(BaseSudokuItem):
|
|||
val : str
|
||||
The digit to be emitted
|
||||
"""
|
||||
self.keyPressed.emit(val, self.scribbling)
|
||||
self.close_menu()
|
||||
scribble = btn == 2
|
||||
self.keyPressed.emit(val, scribble)
|
||||
if not scribble:
|
||||
self.close_menu()
|
||||
|
||||
def freeze_buttons(self, freeze):
|
||||
"""Freezes the button
|
||||
|
|
3
main.py
3
main.py
|
@ -43,7 +43,8 @@ class SudokuWindow(QGraphicsView):
|
|||
self.gameboard.gridDrawn.connect(lambda: self.menuboard.show_children(True))
|
||||
self.gameboard.newGameSelected.connect(self.menuboard.set_difficulty_text)
|
||||
self.gameboard.sudokuDone.connect(self.menuboard.finish_the_game)
|
||||
self.menuboard.diff_display.notFocus.connect(self.gameboard.game_refocus)
|
||||
self.menuboard.diff_display.menuClicked.connect(self.gameboard.game_unfocus)
|
||||
self.menuboard.diff_display.notFocus.connect(lambda: self.gameboard.refocus_timer.start(10))
|
||||
self.menuboard.diff_display.difficultySelected.connect(self.gameboard.new_game)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
|
|
Loading…
Reference in New Issue