No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

windows.py 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. # Licensed under GPLv3
  2. # Written by Sebastian Lohff (seba@someserver.de)
  3. # http://seba-geek.de/projects/seopardy/
  4. from PySide import QtGui, QtCore
  5. import copy
  6. from gamestate import QuestionAnswers
  7. from music import MusicBox
  8. from video import VideoPlayer
  9. from player import Player, ButtonEvent, nobodyColor
  10. class QuestionWindow(QtGui.QDialog):
  11. buzzersOpen = QtCore.Signal(bool)
  12. playerGotQuestion = QtCore.Signal(int)
  13. def __init__(self, players, section, qnumber, question, answers=None, dj=None, parent=None):
  14. super(QuestionWindow, self).__init__(parent)
  15. self.players = players
  16. self.section = section
  17. self.qnumber = qnumber
  18. self.question = question
  19. self.dj = dj
  20. self._windowSetup = False
  21. self._videoPlayer = None
  22. if answers is not None:
  23. self.answers = answers
  24. else:
  25. self.answers = QuestionAnswers(self.section, self.qnumber)
  26. if not self.answers.is_answered():
  27. if not self._question_has_audio():
  28. MusicBox.play_music("questionSong")
  29. if self.dj:
  30. self.answers.set_dj_points(self.dj[1])
  31. playerNo = self.players.index(self.dj[0])+1
  32. QtCore.QCoreApplication.postEvent(self, ButtonEvent(playerNo))
  33. self._setupGui()
  34. self.setWindowTitle("Seopardy - %s - %d" % (section, qnumber*100))
  35. self._inWindow = False
  36. if self.question["Type"] == "Music":
  37. tag = "%s-%s" % (self.section, self.qnumber)
  38. MusicBox.add_music(tag, self.question["Question"])
  39. MusicBox.play_music(tag)
  40. elif self.question["Type"] == "Video":
  41. self._videoPlayer.play()
  42. def get_answers(self):
  43. return self.answers
  44. def closeEvent(self, event):
  45. if not self._inWindow:
  46. self.buzzersOpen.emit(False)
  47. MusicBox.stop_music()
  48. if self._videoPlayer:
  49. self._videoPlayer.stop()
  50. event.accept()
  51. else:
  52. event.ignore()
  53. def _mkQuestionLabel(self, text, monospaced=False):
  54. question = QtGui.QLabel(text, alignment=QtCore.Qt.AlignCenter)
  55. question.setWordWrap(True)
  56. extra = ""
  57. if monospaced:
  58. extra += "font-family: monospace;"
  59. question.setStyleSheet("QLabel { font-size: 40px; %s }" % (extra,))
  60. return question
  61. def _setupGui(self):
  62. self.layout = QtGui.QVBoxLayout()
  63. seclabel = QtGui.QLabel(self.section)
  64. seclabel.setStyleSheet("QLabel { font-size: 30px; }")
  65. self.layout.addWidget(seclabel, alignment=QtCore.Qt.AlignCenter)
  66. self.layout.addStretch()
  67. qlabel = None
  68. stretch = 0
  69. if self.question["Type"] == "Text":
  70. qlabel = self._mkQuestionLabel(self.question["Question"])
  71. elif self.question["Type"] == "Music":
  72. qlabel = self._mkQuestionLabel("Listen...")
  73. elif self.question["Type"] == "Image":
  74. qlabel = QtGui.QLabel()
  75. pixmap = QtGui.QPixmap()
  76. pixmap.loadFromData(open(self.question["Question"]).read())
  77. qlabel.setPixmap(pixmap)
  78. qlabel.setAlignment(QtCore.Qt.AlignCenter)
  79. elif self.question["Type"] == "Code":
  80. # to have this a) aligned but b) centered we "cheat" a bit with the spaces...
  81. code = self.question["Question"].split("\n")
  82. code = map(lambda x: x.replace("\t", " "), code)
  83. maxLineLen = max(map(len, code))
  84. code = map(lambda x: x + ((maxLineLen-len(x))*" "), code)
  85. qlabel = self._mkQuestionLabel("<pre>"+"\n".join(code)+"</pre>", monospaced=True)
  86. elif self.question["Type"] == "Video":
  87. self._videoPlayer = VideoPlayer(self.question["Question"], self.question["Audio"])
  88. qlabel = self._videoPlayer.get_widget()
  89. stretch = 1
  90. else:
  91. raise ValueError("%s is an unknown type for section %s question name %s" % (self.question["Type"], self.section, self.question["Name"]))
  92. self.layout.addWidget(qlabel, stretch=stretch)
  93. self.layout.addStretch()
  94. self.setLayout(self.layout)
  95. def event(self, e):
  96. if e.type() == ButtonEvent.eventType:
  97. if e.get_playerno() <= len(self.players) and not self._inWindow:
  98. done = False
  99. if self.question["Type"] == "Music":
  100. MusicBox.stop_music()
  101. elif self.question["Type"] == "Video":
  102. self._videoPlayer.pause()
  103. self._inWindow = True
  104. player = self.players[e.get_playerno()-1]
  105. qawin = QuestionAnswerWindow(player, self)
  106. self.playerGotQuestion.emit(e.get_playerno())
  107. res = qawin.exec_()
  108. if res == QuestionAnswerWindow.CORRECT:
  109. self.answers.add_try(player, correct=True)
  110. self._inWindow = False
  111. done = True
  112. self.close()
  113. elif res == QuestionAnswerWindow.WRONG:
  114. self.answers.add_try(player, correct=False)
  115. self._inWindow = False
  116. if not done:
  117. self.buzzersOpen.emit(True)
  118. if self.question["Type"] == "Music":
  119. # resume music if question was not answered
  120. MusicBox.play_music("%s-%s" % (self.section, self.qnumber))
  121. elif self.question["Type"] == "Video":
  122. # resume video if question was not answered
  123. self._videoPlayer.play()
  124. elif e.get_playerno() > len(self.players) and not self._inWindow:
  125. # unknown player! to not confuse certain devices we send a buttons open event
  126. self.buzzersOpen.emit(True)
  127. print("unknown player", e.get_playerno())
  128. return True
  129. else:
  130. ret = super(QuestionWindow, self).event(e)
  131. # we want to do this after the window has focus for the first time
  132. if not self._windowSetup and e.type() == QtCore.QEvent.FocusIn:
  133. if not self.answers.is_answered():
  134. self.buzzersOpen.emit(True)
  135. self._windowSetup = True
  136. return ret
  137. def keyPressEvent(self, e):
  138. if e.key() == QtCore.Qt.Key_Escape:
  139. if not self.answers.is_answered():
  140. self.answers.nobody_knew()
  141. self.close()
  142. elif not self.answers.is_answered() and e.key() >= ord('1') and e.key() <= ord(str(len(self.players))):
  143. QtCore.QCoreApplication.postEvent(self, ButtonEvent(int(chr(e.key()))))
  144. @QtCore.Slot(int)
  145. def playerButtonPress(self, no):
  146. QtCore.QCoreApplication.postEvent(self, ButtonEvent(int(no)))
  147. def _question_has_audio(self):
  148. return self.question["Type"] == "Music" or (self.question["Type"] == "Video" and self.question["Audio"])
  149. class QuestionAnswerWindow(QtGui.QDialog):
  150. CORRECT = 1
  151. WRONG = 2
  152. OOPS = 3
  153. def __init__(self, player, parent=None):
  154. super(QuestionAnswerWindow, self).__init__(parent)
  155. self.player = player
  156. self._setupGui()
  157. self.setWindowTitle("Seopardy - Answer by Player %s" % (self.player.name,))
  158. # move window to bottom right of screen
  159. g = QtGui.QApplication.desktop().screenGeometry()
  160. self.show()
  161. cPos = self.rect()
  162. self.move(g.width() - cPos.width(), g.height() - cPos.height())
  163. def _setupGui(self):
  164. self.layout = QtGui.QVBoxLayout()
  165. self.plabel = QtGui.QLabel(self.player.name)
  166. self.plabel.setStyleSheet("QLabel { font-size: 60px; }")
  167. self.layout.addWidget(self.plabel, alignment=QtCore.Qt.AlignCenter)
  168. btnbox = QtGui.QHBoxLayout()
  169. right = QtGui.QPushButton("Correct")
  170. right.clicked.connect(lambda: self.done(self.CORRECT))
  171. btnbox.addWidget(right)
  172. wrong = QtGui.QPushButton("Wrong")
  173. wrong.clicked.connect(lambda: self.done(self.WRONG))
  174. btnbox.addWidget(wrong)
  175. btnbox.addStretch()
  176. oops = QtGui.QPushButton("Oops")
  177. oops.clicked.connect(lambda: self.done(self.OOPS))
  178. btnbox.addWidget(oops)
  179. self.layout.addLayout(btnbox)
  180. self.setLayout(self.layout)
  181. class EditAnswersWindow(QtGui.QDialog):
  182. def __init__(self, players, answers, parent=None):
  183. super(EditAnswersWindow, self).__init__(parent)
  184. self._players = players
  185. self._answers = answers
  186. self._nobody = not answers.got_answered()
  187. self._dj_points = answers.get_dj_points()
  188. self._in_window = False
  189. if self._answers:
  190. self._tries = copy.copy(self._answers.get_tries())
  191. else:
  192. self._tries = []
  193. self._setupGui()
  194. self.setWindowTitle("Seopardy - Edit Answers")
  195. self.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
  196. def get_new_answers(self):
  197. qa = QuestionAnswers(self._answers.section, self._answers.qnumber, dj_points=self._dj_points)
  198. rightPlayer = None
  199. for player, correct in self._tries:
  200. if correct:
  201. rightPlayer = player
  202. else:
  203. qa.add_try(player, correct)
  204. if rightPlayer:
  205. qa.add_try(rightPlayer, True)
  206. elif self._nobody:
  207. qa.nobody_knew()
  208. return qa
  209. def closeEvent(self, event):
  210. if not self._in_window:
  211. event.accept()
  212. else:
  213. event.ignore()
  214. def _setupGui(self):
  215. self.layout = QtGui.QVBoxLayout()
  216. self.qlabel = QtGui.QLabel("Questions")
  217. self.qlabel.setStyleSheet("QLabel { font-size: 30px; }")
  218. self.layout.addWidget(self.qlabel, alignment=QtCore.Qt.AlignCenter)
  219. self.answerlayout = QtGui.QVBoxLayout()
  220. self._resetAllButtons()
  221. self.layout.addLayout(self.answerlayout)
  222. self.xlabel = QtGui.QLabel("+/- right/wrong, d delete, a add, arrows change player\ne edit double jeopardy")
  223. self.xlabel.setStyleSheet("QLabel { font-size: 15px; }")
  224. self.layout.addWidget(self.xlabel)
  225. self.setLayout(self.layout)
  226. def keyPressEvent(self, e):
  227. if e.key() == QtCore.Qt.Key_Escape:
  228. self.close()
  229. elif e.key() == QtCore.Qt.Key_E:
  230. # edit double jeopardy
  231. if self._dj_points is not None and len(self._tries) > 0 and not self._in_window:
  232. self._in_window = True
  233. dwin = DoubleJeopardyWindow(self._players, self._answers.qnumber*100, self._tries[0][0], current_points=self._dj_points, parent=self)
  234. dwin.exec_()
  235. self._dj_points = dwin.get_chosen_points()
  236. self._tries[0] = (dwin.get_player(), self._tries[0][1])
  237. self._in_window = False
  238. else:
  239. currFocus = self._getCurrFocus()
  240. if currFocus is None and e.key() != QtCore.Qt.Key_A:
  241. return
  242. nothingDone = False
  243. if e.key() == QtCore.Qt.Key_Plus:
  244. self._nobody = False
  245. for i, (player, correct) in enumerate(self._tries):
  246. self._tries[i] = (player, i==currFocus)
  247. if currFocus == len(self._tries):
  248. self._nobody = True
  249. elif e.key() == QtCore.Qt.Key_Minus:
  250. if currFocus == len(self._tries):
  251. if len(self._tries) == 0:
  252. self._nobody = False
  253. else:
  254. if self._tries[currFocus][1]:
  255. # give nobody the score for this one
  256. self._nobody = True
  257. self._tries[currFocus] = (self._tries[currFocus][0], False)
  258. elif e.key() == QtCore.Qt.Key_A:
  259. self._tries.append((self._players[0], False))
  260. self._makeNobodyConsistent()
  261. currFocus = len(self._tries) - 1
  262. elif e.key() == QtCore.Qt.Key_D and currFocus < len(self._tries):
  263. del self._tries[currFocus]
  264. elif e.key() == QtCore.Qt.Key_Left and currFocus < len(self._players):
  265. playlen = len(self._players)
  266. prevPlayer = self._players[(self._players.index(self._tries[currFocus][0])-1+playlen)%playlen]
  267. self._tries[currFocus] = (prevPlayer, self._tries[currFocus][1])
  268. elif e.key() == QtCore.Qt.Key_Right and currFocus < len(self._tries):
  269. playlen = len(self._players)
  270. nextPlayer = self._players[(self._players.index(self._tries[currFocus][0])+1+playlen)%playlen]
  271. self._tries[currFocus] = (nextPlayer, self._tries[currFocus][1])
  272. else:
  273. super(EditAnswersWindow, self).keyPressEvent(e)
  274. nothingDone = True
  275. if not nothingDone:
  276. self._resetAllButtons()
  277. self.updateGeometry()
  278. # reset focus
  279. #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())
  280. self.answerlayout.itemAt(min(currFocus, self.answerlayout.count())).widget().setFocus(QtCore.Qt.FocusReason.NoFocusReason)
  281. #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())
  282. #print(self.focusWidget())
  283. #if self.focusWidget():
  284. # print("widget", self.focusWidget().text())
  285. def _makeNobodyConsistent(self):
  286. if len(self._tries) > 0:
  287. someoneKnew = any([c for p, c in self._tries])
  288. self._nobody = not someoneKnew
  289. def _getCurrFocus(self):
  290. if self.focusWidget() is not None:
  291. for i in range(self.answerlayout.count()):
  292. if self.answerlayout.itemAt(i).widget() == self.focusWidget():
  293. return i
  294. return None
  295. def _resetAllButtons(self):
  296. f = self.answerlayout.takeAt(0)
  297. while f is not None:
  298. f.widget().deleteLater()
  299. f = self.answerlayout.takeAt(0)
  300. # add buttons
  301. first = True
  302. for player, correct in self._tries:
  303. self._addAnswerButton(player, correct, first)
  304. first = False
  305. # add the nobody button
  306. self._addAnswerButton(Player("nobody", nobodyColor), self._nobody)
  307. def _addAnswerButton(self, player, correct=False, first=False):
  308. prefix = "+" if correct else "-"
  309. dj = " (D)" if first and self._dj_points is not None else ""
  310. btn = QtGui.QPushButton("\n%s%s%s\n" % (prefix, player.name, dj), self)
  311. btn.setStyleSheet("QPushButton { background-color: %s; color: white; font-size: 20px; border: none; }" % (player.color.name(),))
  312. btn.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
  313. self.answerlayout.addWidget(btn)
  314. class KeyGrabber(QtCore.QObject):
  315. def __init__(self, keys, parent, *args, **kwargs):
  316. super(KeyGrabber, self).__init__(parent, *args, **kwargs)
  317. self._keys = keys
  318. self._parent = parent
  319. def eventFilter(self, obj, e):
  320. if e.type() == QtCore.QEvent.KeyPress:
  321. if e.key() in self._keys:
  322. self._parent.keyPressEvent(e)
  323. return True
  324. return QtCore.QObject.eventFilter(self, obj, e)
  325. class PlayerStartWindow(QtGui.QDialog):
  326. buzzersOpen = QtCore.Signal(bool)
  327. playerGotQuestion = QtCore.Signal(int)
  328. def __init__(self, players, parent):
  329. super(PlayerStartWindow, self).__init__(parent)
  330. self._players = players
  331. self._parent = parent
  332. self._playerLineEdits = []
  333. self._windowSetup = False
  334. self._setupGui()
  335. self.setWindowTitle("Seopardy - Start")
  336. self.show()
  337. MusicBox.play_music("startSong")
  338. # center window
  339. g = QtGui.QApplication.desktop().screenGeometry()
  340. cPos = self.rect()
  341. self.move(g.width()/2 - cPos.width()/2, g.height()/2 - cPos.height()/2)
  342. def event(self, e):
  343. if e.type() == ButtonEvent.eventType:
  344. if e.get_playerno() <= len(self._players)+1:
  345. if e.get_playerno() == len(self._players)+1:
  346. # add a new player
  347. self._parent.add_player(addToGui=True)
  348. self._guiAddPlayer(self._players[-1])
  349. layoutItem = self.playerGrid.itemAtPosition(e.get_playerno(), 1)
  350. if layoutItem:
  351. widget = layoutItem.widget()
  352. widget.selectAll()
  353. widget.setFocus()
  354. self.playerGotQuestion.emit(e.get_playerno())
  355. return True
  356. else:
  357. ret = super(PlayerStartWindow, self).event(e)
  358. if not self._windowSetup and e.type() == QtCore.QEvent.WindowActivate:
  359. self.buzzersOpen.emit(True)
  360. self._windowSetup = True
  361. return ret
  362. def closeEvent(self, event):
  363. MusicBox.stop_music()
  364. self.buzzersOpen.emit(False)
  365. event.accept()
  366. def keyPressEvent(self, e):
  367. # needed to circumvent dialogclosing when enter is pressed
  368. if e.key() == QtCore.Qt.Key_Escape:
  369. self.close()
  370. elif e.key() == QtCore.Qt.Key_K:
  371. # FIXME: Remove this
  372. QtCore.QCoreApplication.postEvent(self, ButtonEvent(1))
  373. def _setupGui(self):
  374. self.layout = QtGui.QVBoxLayout()
  375. self.playerGrid = QtGui.QGridLayout()
  376. for player in self._players:
  377. self._guiAddPlayer(player)
  378. self.layout.addLayout(self.playerGrid)
  379. startbtn = QtGui.QPushButton("\nStart\n", self)
  380. startbtn.setStyleSheet("QPushButton { font-size: 40px; }")
  381. startbtn.clicked.connect(self.close)
  382. self.layout.addWidget(startbtn)
  383. self.setLayout(self.layout)
  384. def _guiAddPlayer(self, player):
  385. row = self.playerGrid.rowCount()
  386. label = QtGui.QLabel("Player %d" % (row,), self)
  387. label.setStyleSheet("QLabel { font-size: 40px; background-color: %s; color: white; }" % (player.color.name(),))
  388. self.playerGrid.addWidget(label, row, 0)
  389. edit = QtGui.QLineEdit(player.name, self)
  390. edit.setStyleSheet("QLineEdit { font-size: 40px; }")
  391. edit.editingFinished.connect(lambda widget=edit, player=player: self._playerDoneEditing(widget, player))
  392. self.playerGrid.addWidget(edit, row, 1)
  393. def _playerDoneEditing(self, widget, player):
  394. player.change_name(widget.text())
  395. self.buzzersOpen.emit(True)
  396. @QtCore.Slot(int)
  397. def playerButtonPress(self, no):
  398. QtCore.QCoreApplication.postEvent(self, ButtonEvent(int(no)))
  399. class VictoryWindow(QtGui.QDialog):
  400. def __init__(self, players, parent):
  401. super(VictoryWindow, self).__init__(parent)
  402. self._players = players
  403. self._parent = parent
  404. self._setupGui()
  405. self.setWindowTitle("Seopardy - Victory")
  406. MusicBox.play_music("closingSong")
  407. def _setupGui(self):
  408. self.layout = QtGui.QVBoxLayout()
  409. self.playerGrid = QtGui.QGridLayout()
  410. winPlayers = sorted(self._players, key=lambda p: p.points, reverse=True)
  411. for i, player in enumerate(winPlayers):
  412. label = QtGui.QLabel(player.name, self)
  413. fsize = 60 if i == 0 else 25
  414. label.setStyleSheet("QLabel { font-size: %dpx; background-color: %s; color: white; }" % (fsize, player.color.name(),))
  415. self.playerGrid.addWidget(label, i, 0)
  416. points = QtGui.QLabel(str(player.points), self)
  417. points.setStyleSheet("QLabel { font-size: %dpx; }" % (fsize,))
  418. self.playerGrid.addWidget(points, i, 1, alignment=QtCore.Qt.AlignRight)
  419. self.layout.addLayout(self.playerGrid)
  420. self.setLayout(self.layout)
  421. def keyPressEvent(self, e):
  422. if e.key() == QtCore.Qt.Key_Escape:
  423. self.close()
  424. def closeEvent(self, event):
  425. MusicBox.stop_music()
  426. event.accept()
  427. class DoubleJeopardyWindow(QtGui.QDialog):
  428. def __init__(self, player, points, current_player=None, current_points=None, parent=None):
  429. super(DoubleJeopardyWindow, self).__init__(parent)
  430. self._player = player
  431. self._currentPlayer = current_player
  432. self._points = points
  433. if current_points:
  434. self._currentPoints = current_points
  435. else:
  436. self._currentPoints = points
  437. self._setupGui()
  438. self.setWindowTitle("Seopardy - Double Jeopardy")
  439. # move window to bottom right of screen
  440. g = QtGui.QApplication.desktop().screenGeometry()
  441. self.show()
  442. cPos = self.rect()
  443. self.move(g.width() - cPos.width(), g.height() - cPos.height())
  444. def get_chosen_points(self):
  445. return self._currentPoints
  446. def get_player(self):
  447. return self._currentPlayer
  448. def _setupGui(self):
  449. self.layout = QtGui.QVBoxLayout()
  450. header = QtGui.QLabel("Double Jeopardy", self)
  451. header.setStyleSheet("QLabel { font-size: 50px; }")
  452. self.layout.addWidget(header, alignment=QtCore.Qt.AlignCenter)
  453. self.pbtn = QtGui.QPushButton("", self)
  454. self._stylePlayerButton()
  455. self.pbtn.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
  456. self.layout.addWidget(self.pbtn)
  457. self.pointsbtn = QtGui.QPushButton("% 5s" % self._currentPoints)
  458. self.pointsbtn.setStyleSheet("QPushButton { font-size: 50px; border: none; }")
  459. self.pointsbtn.installEventFilter(KeyGrabber((QtCore.Qt.Key.Key_Left, QtCore.Qt.Key.Key_Right), self))
  460. self.layout.addWidget(self.pointsbtn, alignment=QtCore.Qt.AlignCenter)
  461. self.pointsbtn.setFocus()
  462. start = QtGui.QPushButton("Done", self)
  463. start.clicked.connect(self.closeIfNotNobody)
  464. self.layout.addWidget(start)
  465. self.setLayout(self.layout)
  466. def closeIfNotNobody(self):
  467. if self.get_player() is not None:
  468. self.close()
  469. def keyPressEvent(self, e):
  470. if e.key() == QtCore.Qt.Key_Escape or e.key() == QtCore.Qt.Key_Enter:
  471. self.closeIfNotNobody()
  472. elif e.key() == QtCore.Qt.Key_Left or e.key() == QtCore.Qt.Key_Right:
  473. if self.focusWidget() == self.pbtn:
  474. if e.key() == QtCore.Qt.Key_Right:
  475. if self._currentPlayer == None:
  476. self._currentPlayer = self._player[0]
  477. elif self._currentPlayer == self._player[-1]:
  478. self._currentPlayer = None
  479. else:
  480. self._currentPlayer = self._player[self._player.index(self._currentPlayer)+1]
  481. elif e.key() == QtCore.Qt.Key_Left:
  482. if self._currentPlayer == None:
  483. self._currentPlayer = self._player[-1]
  484. elif self._currentPlayer == self._player[0]:
  485. self._currentPlayer = None
  486. else:
  487. self._currentPlayer = self._player[self._player.index(self._currentPlayer)-1]
  488. self._stylePlayerButton()
  489. elif self.focusWidget() == self.pointsbtn:
  490. if e.key() == QtCore.Qt.Key_Right and self._currentPoints < self._points*2:
  491. self._currentPoints += 50
  492. elif e.key() == QtCore.Qt.Key_Left and self._currentPoints > self._points/2:
  493. self._currentPoints += -50
  494. self.pointsbtn.setText("% 4s" % self._currentPoints)
  495. def _stylePlayerButton(self):
  496. player = None
  497. color = None
  498. if self._currentPlayer == None:
  499. player = "nobody"
  500. color = nobodyColor
  501. else:
  502. player = self._currentPlayer.name
  503. color = self._currentPlayer.color
  504. self.pbtn.setText(player)
  505. self.pbtn.setStyleSheet("QPushButton { background-color: %s; color: white; font-size: 50px; border: none; }" % (color.name(),))