Editing questions works

This commit is contained in:
Sebastian Lohff 2013-11-18 17:47:03 +01:00
parent 280544c66d
commit 4376d4e6e3
3 changed files with 210 additions and 25 deletions

61
game.py
View File

@ -3,7 +3,8 @@ from __future__ import print_function
from PySide import QtCore, QtGui from PySide import QtCore, QtGui
from player import Player from player import Player
from windows import QuestionWindow from windows import QuestionWindow, EditAnswersWindow
from gamestate import QuestionAnswers
class SeopardyGame(QtGui.QWidget): class SeopardyGame(QtGui.QWidget):
def __init__(self, questions, gamestate, parent=None): def __init__(self, questions, gamestate, parent=None):
@ -11,7 +12,7 @@ class SeopardyGame(QtGui.QWidget):
self.questions = questions self.questions = questions
self.gamestate = gamestate self.gamestate = gamestate
self.players = [Player.gen_player(i) for i in range(1, 4)] self.players = [Player.gen_player(i, parent=self) for i in range(1, 4)]
self._inOtherWindow = False self._inOtherWindow = False
self._createGui() self._createGui()
@ -57,28 +58,59 @@ class SeopardyGame(QtGui.QWidget):
self.setLayout(layout) self.setLayout(layout)
#def event(self, e): def event(self, e):
# print("Event", e) if e.type() == QtCore.QEvent.KeyPress and e.key() == QtCore.Qt.Key_Left:
# super(SeopardyGame, self).event(e) print("Key!!!", e.key())
return super(SeopardyGame, self).event(e)
def keyPressEvent(self, e): def keyPressEvent(self, e):
print("Mainwindow", e)
print("current widget", e.key(), self.focusWidget())
if e.key() == QtCore.Qt.Key_Escape: if e.key() == QtCore.Qt.Key_Escape:
self.close() self.close()
elif e.key() == QtCore.Qt.Key_E: elif e.key() == QtCore.Qt.Key_E:
if self._inOtherWindow: if self._inOtherWindow:
return return
# find current question
section = None
qno = None
found = False
for secno, section in enumerate(self.questions.get_sections(), 0):
for qno in range(1, 6):
btn = self.board.itemAtPosition(qno, secno).widget()
if btn == self.focusWidget():
found = True
break
if found:
break
if not found:
return
self.edit_question_answers(section, qno)
def edit_question_answers(self, section, number):
self._inOtherWindow = True self._inOtherWindow = True
#editResultsWin = EditResultsWindow()
#editResultsWin.exec_() answers = self.gamestate.get_answers(section, number)
if answers is None:
answers = QuestionAnswers(section, number)
editAnswersWin = EditAnswersWindow(self.players, answers, self)
editAnswersWin.exec_()
self._inOtherWindow = False self._inOtherWindow = False
oldAnswers = self.gamestate.get_answers(section, number)
newAnswers = editAnswersWin.get_new_answers()
if oldAnswers:
self._set_player_points(oldAnswers, rollback=True)
self._set_player_points(newAnswers)
self.gamestate.set_answers(section, number, newAnswers)
self._restyle_button(section, number, newAnswers)
def go_to_question(self, section, number): def go_to_question(self, section, number):
if self._inOtherWindow: if self._inOtherWindow:
return return
self._inOtherWindow = True self._inOtherWindow = True
print("question window", section, number)
answers = self.gamestate.get_answers(section, number) answers = self.gamestate.get_answers(section, number)
qwin = QuestionWindow(self.players, section, number, self.questions.get_question(section, number), answers, self) qwin = QuestionWindow(self.players, section, number, self.questions.get_question(section, number), answers, self)
@ -104,15 +136,20 @@ class SeopardyGame(QtGui.QWidget):
prefix *= -1 prefix *= -1
if not correct: if not correct:
prefix *= -1 prefix *= -1
player.add_points(answers.points()*prefix) player.add_points(answers.points()*prefix, commit=not rollback)
def _restyle_button(self, sec, qno, answers): def _restyle_button(self, sec, qno, answers):
secno = self.questions.get_number_from_section(sec) secno = self.questions.get_number_from_section(sec)
btn = self.board.itemAtPosition(qno, secno-1).widget() btn = self.board.itemAtPosition(qno, secno-1).widget()
print("btn", btn, type(btn))
btnstr = "" btnstr = ""
btncolor = None btncolor = None
if not answers.is_answered():
btn.setText(str(answers.points()))
btn.setStyleSheet("QPushButton { font-size: 60px; }")
return
# restrict number of tries shown # restrict number of tries shown
numTries = 4 if answers.got_answered() else 3 numTries = 4 if answers.got_answered() else 3
tries = answers.get_tries() tries = answers.get_tries()

View File

@ -17,15 +17,15 @@ class Player(QtGui.QWidget):
self.color = color self.color = color
self.points = points self.points = points
self.setup_gui() self._setup_gui()
def setup_gui(self): def _setup_gui(self):
self.layout = QtGui.QVBoxLayout() self.layout = QtGui.QVBoxLayout()
self.name_label = QtGui.QLabel(self.name) self.name_label = QtGui.QLabel(self.name, self)
self.name_label.setStyleSheet("QLabel { font-size: 40px; background-color: %s; color: white; }" % (self.color.name(),)) self.name_label.setStyleSheet("QLabel { font-size: 40px; background-color: %s; color: white; }" % (self.color.name(),))
self.layout.addWidget(self.name_label) self.layout.addWidget(self.name_label)
self.points_label = QtGui.QLabel(str(self.points)) self.points_label = QtGui.QLabel(str(self.points), self)
self.points_label.setStyleSheet("QLabel { font-size: 40px;}") self.points_label.setStyleSheet("QLabel { font-size: 40px;}")
self.layout.addWidget(self.points_label, alignment=QtCore.Qt.AlignRight) self.layout.addWidget(self.points_label, alignment=QtCore.Qt.AlignRight)
@ -35,14 +35,15 @@ class Player(QtGui.QWidget):
self.name = new_name self.name = new_name
self.name_label.set_text(new_name) self.name_label.set_text(new_name)
def add_points(self, amount): def add_points(self, amount, commit=True):
self.points += amount self.points += amount
self.points_label.setText(str(self.points)) if commit:
self.points_label.setText(str(self.points))
@classmethod @classmethod
def gen_player(clazz, num): def gen_player(clazz, num, parent=None):
if num > len(clazz.DEFAULT_PLAYERS): if num > len(clazz.DEFAULT_PLAYERS):
raise ValueError("You tried to generate too many players") raise ValueError("You tried to generate too many players")
return clazz(*clazz.DEFAULT_PLAYERS[num-1]) return clazz(*clazz.DEFAULT_PLAYERS[num-1], parent=parent)

View File

@ -1,8 +1,10 @@
from PySide import QtGui, QtCore from PySide import QtGui, QtCore
from gamestate import QuestionAnswers import copy
from gamestate import QuestionAnswers
from player import Player
#class QuestionWindow(QtGui.QWidget):
class QuestionWindow(QtGui.QDialog): class QuestionWindow(QtGui.QDialog):
def __init__(self, players, section, qnumber, question, answers=None, parent=None): def __init__(self, players, section, qnumber, question, answers=None, parent=None):
super(QuestionWindow, self).__init__(parent) super(QuestionWindow, self).__init__(parent)
@ -40,7 +42,6 @@ class QuestionWindow(QtGui.QDialog):
qlabel = None qlabel = None
if self.question["Type"] == "Text": if self.question["Type"] == "Text":
qlabel = self._mkQuestionLabel(self.question["Question"]) qlabel = self._mkQuestionLabel(self.question["Question"])
print(self.question["Question"])
elif self.question["Type"] == "Music": elif self.question["Type"] == "Music":
qlabel = self._mkQuestionLabel("Listen...") qlabel = self._mkQuestionLabel("Listen...")
elif self.question["Type"] == "Image": elif self.question["Type"] == "Image":
@ -57,7 +58,6 @@ class QuestionWindow(QtGui.QDialog):
self.setLayout(self.layout) self.setLayout(self.layout)
def keyPressEvent(self, e): def keyPressEvent(self, e):
print("question", e, e.key())
if e.key() == QtCore.Qt.Key_Escape: if e.key() == QtCore.Qt.Key_Escape:
if not self.answers.is_answered(): if not self.answers.is_answered():
self.answers.nobody_knew() self.answers.nobody_knew()
@ -67,7 +67,6 @@ class QuestionWindow(QtGui.QDialog):
qawin = QuestionAnswerWindow(player, self) qawin = QuestionAnswerWindow(player, self)
res = qawin.exec_() res = qawin.exec_()
if res == QuestionAnswerWindow.CORRECT: if res == QuestionAnswerWindow.CORRECT:
print("Done!")
self.answers.add_try(player, correct=True) self.answers.add_try(player, correct=True)
self.accept() self.accept()
elif res == QuestionAnswerWindow.WRONG: elif res == QuestionAnswerWindow.WRONG:
@ -111,3 +110,151 @@ class QuestionAnswerWindow(QtGui.QDialog):
self.layout.addLayout(btnbox) self.layout.addLayout(btnbox)
self.setLayout(self.layout) self.setLayout(self.layout)
class EditAnswersWindow(QtGui.QDialog):
def __init__(self, players, answers, parent=None):
super(EditAnswersWindow, self).__init__(parent)
self._players = players
self._answers = answers
self._nobody = not answers.got_answered()
if self._answers:
self._tries = copy.copy(self._answers.get_tries())
else:
self._tries = []
self._setupGui()
self.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
def get_new_answers(self):
qa = QuestionAnswers(self._answers.section, self._answers.qnumber)
rightPlayer = None
for player, correct in self._tries:
if correct:
rightPlayer = player
else:
qa.add_try(player, correct)
if rightPlayer:
qa.add_try(rightPlayer, True)
elif self._nobody:
qa.nobody_knew()
return qa
def _setupGui(self):
self.layout = QtGui.QVBoxLayout()
self.qlabel = QtGui.QLabel("Questions")
self.qlabel.setStyleSheet("QLabel { font-size: 30px; }")
self.layout.addWidget(self.qlabel, alignment=QtCore.Qt.AlignCenter)
self.answerlayout = QtGui.QVBoxLayout()
self._resetAllButtons()
self.layout.addLayout(self.answerlayout)
self.xlabel = QtGui.QLabel("+/- right/wrong, d delete, a add, arrows change player")
self.xlabel.setStyleSheet("QLabel { font-size: 15px; }")
self.layout.addWidget(self.xlabel)
self.setLayout(self.layout)
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_Escape:
self.close()
else:
currFocus = self._getCurrFocus()
if currFocus is None and e.key() != QtCore.Qt.Key_A:
return
nothingDone = False
if e.key() == QtCore.Qt.Key_Plus:
self._nobody = False
for i, (player, correct) in enumerate(self._tries):
self._tries[i] = (player, i==currFocus)
if currFocus == len(self._tries):
self._nobody = True
elif e.key() == QtCore.Qt.Key_Minus:
if currFocus == len(self._tries):
if len(self._tries) == 0:
self._nobody = False
else:
self._tries[currFocus] = (self._tries[currFocus][0], False)
elif e.key() == QtCore.Qt.Key_A:
self._tries.append((self._players[0], False))
self._makeNobodyConsistent()
currFocus = len(self._tries) - 1
elif e.key() == QtCore.Qt.Key_D and currFocus < len(self._tries):
del self._tries[currFocus]
elif e.key() == QtCore.Qt.Key_Left and currFocus < len(self._players):
playlen = len(self._players)
prevPlayer = self._players[(self._players.index(self._tries[currFocus][0])-1+playlen)%playlen]
self._tries[currFocus] = (prevPlayer, self._tries[currFocus][1])
elif e.key() == QtCore.Qt.Key_Right and currFocus < len(self._tries):
playlen = len(self._players)
nextPlayer = self._players[(self._players.index(self._tries[currFocus][0])+1+playlen)%playlen]
self._tries[currFocus] = (nextPlayer, self._tries[currFocus][1])
else:
super(EditAnswersWindow, self).keyPressEvent(e)
nothingDone = True
if not nothingDone:
self._resetAllButtons()
self.updateGeometry()
# reset focus
print("setting focus to", min(currFocus, self.answerlayout.count()), self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().text(), self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().hasFocus())
self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().setFocus(QtCore.Qt.FocusReason.NoFocusReason)
print("setting focus to", min(currFocus, self.answerlayout.count()), self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().text(), self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().hasFocus())
print(self.focusWidget())
if self.focusWidget():
print("widget", self.focusWidget().text())
def _makeNobodyConsistent(self):
if len(self._tries) > 0:
someoneKnew = any([c for p, c in self._tries])
self._nobody = not someoneKnew
def _getCurrFocus(self):
if self.focusWidget() is not None:
for i in range(self.answerlayout.count()):
if self.answerlayout.itemAt(i).widget() == self.focusWidget():
return i
return None
def _resetAllButtons(self):
print("resetting all buttons")
f = self.answerlayout.takeAt(0)
while f is not None:
f.widget().deleteLater()
f = self.answerlayout.takeAt(0)
# add buttons
for player, correct in self._tries:
print("building button for", player)
self._addAnswerButton(player, correct)
# add the nobody button
print("adding the nobody button")
self._addAnswerButton(Player("nobody", QtGui.QColor(128, 128, 128)), self._nobody)
def _addAnswerButton(self, player, correct=False):
prefix = "+" if correct else "-"
btn = QtGui.QPushButton("\n%s%s\n" % (prefix, player.name), self)
btn.setStyleSheet("QPushButton { background-color: %s; color: white; font-size: 20px; border: none; }" % (player.color.name(),))
btn.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
self.answerlayout.addWidget(btn)
class KeyGrabber(QtCore.QObject):
def __init__(self, keys, parent, *args, **kwargs):
super(KeyGrabber, self).__init__(parent, *args, **kwargs)
self._keys = keys
self._parent = parent
def eventFilter(self, obj, e):
if e.type() == QtCore.QEvent.KeyPress:
if e.key() in self._keys:
self._parent.keyPressEvent(e)
return True
return QtCore.QObject.eventFilter(self, obj, e)