Compare commits

...

5 Commits

Author SHA1 Message Date
En Yi 44cb7a697b Update README 2022-07-09 14:14:20 +08:00
En Yi d815281abc Extra fixes after rebasing 2022-07-09 14:10:16 +08:00
En Yi 9ce1ae0ff7 Fix focusing issue of game board 2022-07-09 13:42:24 +08:00
En Yi de5af7cb44 Allow right-clicking for scribbling 2022-07-09 13:37:25 +08:00
En Yi b7eba38f0f Comment on dig sequence 2022-07-09 13:36:26 +08:00
7 changed files with 49 additions and 28 deletions

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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):

View File

@ -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
----------

View File

@ -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

View File

@ -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):