def iniGraphicsSystem(self, name=None): ##初始化 Graphics View系统 scene = GraphicsScene() # 创建QGraphicsScene view = GraphicsView(self, scene) # 创建图形视图组件 view.mouseMove.connect(self.do_mouseMove) # 鼠标移动 view.mouseClicked.connect(self.do_mouseClicked) # 左键按下 scene.itemMoveSignal.connect(self.do_shapeMoved) scene.itemLock.connect(self.do_nodeLock) scene.isHasItem.connect(self.do_checkIsHasItems) if name: title = name else: text = self.tr('未命名') title = f'{text}{self.ui.tabWidget.count()}' curIndex = self.ui.tabWidget.addTab(view, title) self.ui.tabWidget.setCurrentIndex(curIndex) self.ui.tabWidget.setVisible(True)
def createLayout(self): self.ui = uic.loadUi("GameWidget.ui", self) self.scene = GraphicsScene( self.nrRows, self.nrCols, QtGui.QColor(self.player.color[0], self.player.color[1], self.player.color[2]), self, ) self.scene.block(False) self.ui.graphicsView.setScene(self.scene) self.logList = LogWidget(self) self.logList.setMaximumSize(250, 200) self.freezeButton = QtGui.QPushButton("Freeze", self) QtCore.QObject.connect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.freezeGame) self.freezeButton.setDisabled(True) self.ui.verticalLayout.addWidget(self.logList) self.ui.verticalLayout.addWidget(self.freezeButton) self.ui.chatEdit.returnPressed.connect(self.sendMessage) self.ui.aiCheckBox.stateChanged.connect(self.aiToggled) self.ui.show() self.layoutCreated = True
def __init__(self, parent=None): super(PrepareBattle, self).__init__(parent) self.threadpool = QThreadPool() layout = QtWidgets.QHBoxLayout() self.parent = parent self.opponent_player = False self.ally_player = False self.parent.board_plane = [[0 for x in range(16)] for y in range(16)] self.verticalLayoutWidget = QtWidgets.QWidget() self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 791, 511)) self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.graphicsView = QtWidgets.QGraphicsView(self.verticalLayoutWidget) self.graphicsView.setMouseTracking(True) self.graphicsView.setObjectName("graphicsView") self.graphics_scene = GraphicsScene() self.graphicsView.setMouseTracking(True) self.graphicsView.setScene(self.graphics_scene) pen = QtGui.QPen(QtCore.Qt.darkCyan) side = 24 for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * side, j * side), QtCore.QSizeF(side, side)) self.graphics_scene.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView) self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") pixmap = QtGui.QPixmap("images/plane_0.png") self.label_2 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 0) self.label_2.setMinimumSize(QtCore.QSize(100, 100)) self.label_2.setMaximumSize(QtCore.QSize(100, 100)) self.label_2.setAcceptDrops(True) self.label_2.setText("") self.label_2.setPixmap(pixmap) self.label_2.setScaledContents(True) self.label_2.setObjectName("label_2") self.label_2.setMouseTracking(True) self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1) self.label_3 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 1) self.label_3.setMinimumSize(QtCore.QSize(100, 100)) self.label_3.setMaximumSize(QtCore.QSize(100, 100)) self.label_3.setAcceptDrops(True) self.label_3.setText("") self.label_3.setPixmap(pixmap) self.label_3.setScaledContents(True) self.label_3.setObjectName("label_3") self.label_3.setMouseTracking(True) self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) self.label_4 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 2) self.label_4.setMinimumSize(QtCore.QSize(100, 100)) self.label_4.setMaximumSize(QtCore.QSize(100, 100)) self.label_4.setAcceptDrops(True) self.label_4.setText("") self.label_4.setPixmap(pixmap) self.label_4.setScaledContents(True) self.label_4.setObjectName("label_4") self.label_4.setMouseTracking(True) self.gridLayout.addWidget(self.label_4, 0, 1, 1, 1) self.label = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 3) self.label.setMinimumSize(QtCore.QSize(100, 100)) self.label.setMaximumSize(QtCore.QSize(100, 100)) self.label.setAcceptDrops(True) self.label.setText("") self.label.setPixmap(pixmap) self.label.setScaledContents(True) self.label.setObjectName("label") self.label.setMouseTracking(True) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.label_5 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 4) self.label_5.setMinimumSize(QtCore.QSize(100, 100)) self.label_5.setMaximumSize(QtCore.QSize(100, 100)) self.label_5.setAcceptDrops(True) self.label_5.setText("") self.label_5.setPixmap(pixmap) self.label_5.setScaledContents(True) self.label_5.setObjectName("label_5") self.label_5.setMouseTracking(True) self.gridLayout.addWidget(self.label_5, 2, 0, 1, 1) self.horizontalLayout.addLayout(self.gridLayout) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget) self.pushButton.setMinimumSize(QtCore.QSize(100, 50)) self.pushButton.setObjectName("pushButton") self.pushButton.clicked.connect(self.click_battle_now) self.horizontalLayout_3.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout_3) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) layout.addWidget(self.verticalLayoutWidget) self.setLayout(layout) self.wait_for_message()
class PrepareBattle(QtWidgets.QWidget): graphics_scene = None opponent_player = None ally_player = None def __init__(self, parent=None): super(PrepareBattle, self).__init__(parent) self.threadpool = QThreadPool() layout = QtWidgets.QHBoxLayout() self.parent = parent self.opponent_player = False self.ally_player = False self.parent.board_plane = [[0 for x in range(16)] for y in range(16)] self.verticalLayoutWidget = QtWidgets.QWidget() self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 791, 511)) self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.graphicsView = QtWidgets.QGraphicsView(self.verticalLayoutWidget) self.graphicsView.setMouseTracking(True) self.graphicsView.setObjectName("graphicsView") self.graphics_scene = GraphicsScene() self.graphicsView.setMouseTracking(True) self.graphicsView.setScene(self.graphics_scene) pen = QtGui.QPen(QtCore.Qt.darkCyan) side = 24 for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * side, j * side), QtCore.QSizeF(side, side)) self.graphics_scene.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView) self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") pixmap = QtGui.QPixmap("images/plane_0.png") self.label_2 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 0) self.label_2.setMinimumSize(QtCore.QSize(100, 100)) self.label_2.setMaximumSize(QtCore.QSize(100, 100)) self.label_2.setAcceptDrops(True) self.label_2.setText("") self.label_2.setPixmap(pixmap) self.label_2.setScaledContents(True) self.label_2.setObjectName("label_2") self.label_2.setMouseTracking(True) self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1) self.label_3 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 1) self.label_3.setMinimumSize(QtCore.QSize(100, 100)) self.label_3.setMaximumSize(QtCore.QSize(100, 100)) self.label_3.setAcceptDrops(True) self.label_3.setText("") self.label_3.setPixmap(pixmap) self.label_3.setScaledContents(True) self.label_3.setObjectName("label_3") self.label_3.setMouseTracking(True) self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1) self.label_4 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 2) self.label_4.setMinimumSize(QtCore.QSize(100, 100)) self.label_4.setMaximumSize(QtCore.QSize(100, 100)) self.label_4.setAcceptDrops(True) self.label_4.setText("") self.label_4.setPixmap(pixmap) self.label_4.setScaledContents(True) self.label_4.setObjectName("label_4") self.label_4.setMouseTracking(True) self.gridLayout.addWidget(self.label_4, 0, 1, 1, 1) self.label = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 3) self.label.setMinimumSize(QtCore.QSize(100, 100)) self.label.setMaximumSize(QtCore.QSize(100, 100)) self.label.setAcceptDrops(True) self.label.setText("") self.label.setPixmap(pixmap) self.label.setScaledContents(True) self.label.setObjectName("label") self.label.setMouseTracking(True) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.label_5 = DragLabel(self.verticalLayoutWidget, self.graphics_scene, 4) self.label_5.setMinimumSize(QtCore.QSize(100, 100)) self.label_5.setMaximumSize(QtCore.QSize(100, 100)) self.label_5.setAcceptDrops(True) self.label_5.setText("") self.label_5.setPixmap(pixmap) self.label_5.setScaledContents(True) self.label_5.setObjectName("label_5") self.label_5.setMouseTracking(True) self.gridLayout.addWidget(self.label_5, 2, 0, 1, 1) self.horizontalLayout.addLayout(self.gridLayout) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget) self.pushButton.setMinimumSize(QtCore.QSize(100, 50)) self.pushButton.setObjectName("pushButton") self.pushButton.clicked.connect(self.click_battle_now) self.horizontalLayout_3.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout_3) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) layout.addWidget(self.verticalLayoutWidget) self.setLayout(layout) self.wait_for_message() def click_battle_now(self): if self.graphics_scene.valid_plane_position != 0: self.ally_player = True try: if type(self.parent.conn) is socket.socket: self.parent.conn.send('Im set'.encode()) else: self.parent.conn.send('Im set'.encode()).fire() except Exception as e: print(e) if self.opponent_player and self.ally_player: print('Battle Time') self.prepare_battle() self.parent.goto_battle_field() else: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Error. . .") msg.setText("Invalid values") msg.setInformativeText("Not all the planes are set in the board") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() def wait_for_message(self): worker = Worker(self.receive_message) worker.signals.result.connect(self.print_output) worker.signals.finished.connect(self.thread_complete) worker.signals.progress.connect(self.progress_fn) self.threadpool.start(worker) def progress_fn(self, output): print("%s" % output) def print_output(self, result): if result: try: if result.decode('utf-8') == 'Im set': self.opponent_player = True if self.opponent_player and self.ally_player: print('Battle Time') self.prepare_battle() self.parent.goto_battle_field() except Exception as e: print(e) def thread_complete(self): print("THREAD COMPLETE!") def receive_message(self, progress_callback): try: progress_callback.emit('Waiting for message. . .') if type(self.parent.conn) is socket.socket: data = self.parent.conn.recv(1024) else: data = self.parent.conn.recv(1024).fire() except Exception as e: data = 'NULL' print(e) finally: return data def prepare_battle(self): for i in range(16): for j in range(16): for k in range(5): if self.graphics_scene.board_plane[i][j][k]: self.parent.board_plane[i][j] = True break else: self.parent.board_plane[i][j] = False def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.pushButton.setText(_translate("Form", "Battle"))
def __init__(self, parent=None): super(BattleField, self).__init__(parent) self.parent = parent self.threadpool = QThreadPool() self.next_move_shot = False layout = QtWidgets.QHBoxLayout() self.verticalLayoutWidget = QtWidgets.QWidget() self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 791, 511)) self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.graphicsView = QtWidgets.QGraphicsView(self.verticalLayoutWidget) self.graphicsView.setObjectName("graphicsView") self.graphics_scene_defense = GraphicsScene() self.graphicsView.setMouseTracking(True) self.graphicsView.setScene(self.graphics_scene_defense) pen = QtGui.QPen(QtCore.Qt.darkCyan) for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * self.side, j * self.side), QtCore.QSizeF(self.side, self.side)) self.graphics_scene_defense.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView) self.graphicsView_2 = QtWidgets.QGraphicsView( self.verticalLayoutWidget) self.graphicsView_2.setObjectName("graphicsView_2") self.graphics_scene_attack = GraphicsScene() self.graphicsView_2.setMouseTracking(True) self.graphicsView_2.setScene(self.graphics_scene_attack) self.graphics_scene_attack.mousePressEvent = self.shot_bullet pen = QtGui.QPen(QtCore.Qt.darkCyan) for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * self.side, j * self.side), QtCore.QSizeF(self.side, self.side)) self.graphics_scene_attack.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView_2) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget) self.pushButton.setMinimumSize(QtCore.QSize(100, 50)) self.pushButton.setObjectName("pushButton") self.horizontalLayout_3.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout_3) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) layout.addWidget(self.verticalLayoutWidget) self.setLayout(layout) if type(self.parent.conn) is socket.socket: self.next_move_shot = True else: self.wait_for_shot()
class BattleField(QtWidgets.QWidget): graphics_scene_defense = None graphics_scene_attack = None next_move_shot = None side = 24 def __init__(self, parent=None): super(BattleField, self).__init__(parent) self.parent = parent self.threadpool = QThreadPool() self.next_move_shot = False layout = QtWidgets.QHBoxLayout() self.verticalLayoutWidget = QtWidgets.QWidget() self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 791, 511)) self.verticalLayoutWidget.setObjectName("verticalLayoutWidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.graphicsView = QtWidgets.QGraphicsView(self.verticalLayoutWidget) self.graphicsView.setObjectName("graphicsView") self.graphics_scene_defense = GraphicsScene() self.graphicsView.setMouseTracking(True) self.graphicsView.setScene(self.graphics_scene_defense) pen = QtGui.QPen(QtCore.Qt.darkCyan) for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * self.side, j * self.side), QtCore.QSizeF(self.side, self.side)) self.graphics_scene_defense.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView) self.graphicsView_2 = QtWidgets.QGraphicsView( self.verticalLayoutWidget) self.graphicsView_2.setObjectName("graphicsView_2") self.graphics_scene_attack = GraphicsScene() self.graphicsView_2.setMouseTracking(True) self.graphicsView_2.setScene(self.graphics_scene_attack) self.graphics_scene_attack.mousePressEvent = self.shot_bullet pen = QtGui.QPen(QtCore.Qt.darkCyan) for i in range(16): for j in range(16): r = QtCore.QRectF(QtCore.QPointF(i * self.side, j * self.side), QtCore.QSizeF(self.side, self.side)) self.graphics_scene_attack.addRect(r, pen) self.horizontalLayout.addWidget(self.graphicsView_2) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem) self.pushButton = QtWidgets.QPushButton(self.verticalLayoutWidget) self.pushButton.setMinimumSize(QtCore.QSize(100, 50)) self.pushButton.setObjectName("pushButton") self.horizontalLayout_3.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout_3) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) layout.addWidget(self.verticalLayoutWidget) self.setLayout(layout) if type(self.parent.conn) is socket.socket: self.next_move_shot = True else: self.wait_for_shot() def retranslateUi(self): _translate = QtCore.QCoreApplication.translate self.pushButton.setText(_translate("Form", "Battle")) def shot_bullet(self, event): try: if self.next_move_shot: self.next_move_shot = False row = int(event.scenePos().y() / 24) column = int(event.scenePos().x() / 24) strout = ('Fire;Row:' + str(row) + ';Column:' + str(column)) if 0 <= row < 16 and 0 <= column < 16: if type(self.parent.conn) is socket.socket: self.parent.conn.send(strout.encode()) self.wait_for_shot() else: self.parent.conn.send(strout.encode()).fire() self.wait_for_shot() except Exception as e: print(e) def wait_for_shot(self): worker = Worker(self.receive_shot) worker.signals.result.connect(self.print_output) worker.signals.finished.connect(self.thread_complete) worker.signals.progress.connect(self.progress_fn) self.threadpool.start(worker) def progress_fn(self, output): print("%s" % output) def print_output(self, result): if result: try: result = result.decode('utf-8') tokens = result.split(';') if tokens[0] == 'Fire': row = int(tokens[1].split(':')[1]) column = int(tokens[2].split(':')[1]) pen = QtGui.QPen(QtCore.Qt.darkCyan) self.graphics_scene_defense.addLine( column * self.side + 2, row * self.side + 2, column * self.side + self.side - 2, row * self.side + self.side - 2, pen) self.graphics_scene_defense.addLine( column * self.side + self.side - 2, row * self.side + 2, column * self.side + 2, row * self.side + self.side - 2, pen) if self.parent.board_plane[row][column]: str_output = 'Result;Shot:Hit;Row:' + str( row) + ';Column:' + str(column) self.parent.board_plane[row][column] = False else: str_output = 'Result;Shot:Miss;Row:' + str( row) + ";Column:" + str(column) if self.finish_match(): str_output = str_output + ';Match:Won' if type(self.parent.conn) is socket.socket: self.parent.conn.send(str_output.encode()) else: self.parent.conn.send(str_output.encode()).fire() msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Too bad") msg.setText("Too bad! You lost the match.") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() self.next_move_shot = True elif tokens[0] == 'Result': result = tokens[1].split(':')[1] row = int(tokens[2].split(':')[1]) column = int(tokens[3].split(':')[1]) if len(tokens) == 5: match = tokens[4].split(':') if match[1] == 'Won': msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setWindowTitle("Congratulations") msg.setText("Congratulations! You won the match.") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() if result == 'Hit': pen = QtGui.QPen(QtCore.Qt.red) else: pen = QtGui.QPen(QtCore.Qt.green) self.graphics_scene_attack.addLine( column * self.side + 2, row * self.side + 2, column * self.side + self.side - 2, row * self.side + self.side - 2, pen) self.graphics_scene_attack.addLine( column * self.side + self.side - 2, row * self.side + 2, column * self.side + 2, row * self.side + self.side - 2, pen) self.next_move_shot = False self.wait_for_shot() except Exception as e: print(e) def thread_complete(self): print("THREAD COMPLETE!") def finish_match(self): for i in range(16): for j in range(16): if self.parent.board_plane[i][j]: return False return True def receive_shot(self, progress_callback): try: progress_callback.emit('Waiting for message. . .') if type(self.parent.conn) is socket.socket: data = self.parent.conn.recv(1024) else: data = self.parent.conn.recv(1024).fire() except Exception as e: data = 'NULL' print(e) finally: return data
class GameWidget(QtGui.QWidget): # GameWidget provides a window in which a game can be played. It displays the gameboard(GraphicsScene), # active players, log messages and chat messages CREATE_NEW_GAME, JOIN_GAME = range(2) def __init__(self, type, info, player, service, win_parent=None): # If type is CREATE_NEW_GAME, info contains the number of rows and colums, name and comment. # If type is JOIN_GAME, info contains the UUID of the game the user wishes to join. QtGui.QWidget.__init__(self, win_parent) self.scene = None self.aiActive = False self.manyInARowService = service self.player = player self.nrCols = info["cols"] self.nrRows = info["rows"] self.gameName = str(info["name"]) self.comment = str(info["comment"]) self.waitTime = info["waitTime"] self.startTime = None self.players = {} self.manyInARow = None self.layoutCreated = False self.aiTimer = QtCore.QTimer() self.aiTimer.timeout.connect(self.aiMakeMove) self.aiTimer.setInterval(1000) self.errorBox = QtGui.QMessageBox(QtGui.QMessageBox.Information, "0", "0", QtGui.QMessageBox.Ok, self) # Custom event types: self.MAKE_MOVE_EVENT = QtCore.QEvent.User + 1 self.PLAYER_WON_EVENT = QtCore.QEvent.User + 2 self.GAME_FINISHED_EVENT = QtCore.QEvent.User + 3 # ensure threading safety: self.lock = threading.Condition() if type == self.CREATE_NEW_GAME: self.manyInARow = ManyInARowGame.hostGame( service, player, self.gameName, self.comment, self.nrRows, self.nrCols, self.waitTime, self.chatCallBack, self.gameJoinedCallBack, self.playerJoinedCallBack, self.playerLeftCallBack, self.moveCallBack, self.enableClicks, self.disableClicks, self.playerWonCallBack, self.gameFinishedCallBack, self.freezeCallback, self.unfreezeCallback, ) if not self.layoutCreated: self.createLayout() QtCore.QObject.connect(self.scene, QtCore.SIGNAL("playerClicked(int)"), self.makeMove) QtCore.QObject.connect(self.scene, QtCore.SIGNAL("mouseHoverColumn(int)"), self.makeHoverMove) self.manyInARow.start() if type == self.JOIN_GAME: self.gameUUID = info["UUID"] self.manyInARow = ManyInARowGame.joinGame( service, player, self.gameUUID, self.gameName, self.comment, self.nrRows, self.nrCols, self.waitTime, self.chatCallBack, self.gameJoinedCallBack, self.playerJoinedCallBack, self.playerLeftCallBack, self.moveCallBack, self.enableClicks, self.disableClicks, self.playerWonCallBack, self.gameFinishedCallBack, self.freezeCallback, self.unfreezeCallback, ) self.gameUUID = self.manyInARow.UUID self.startTime = self.manyInARow.startTime self.manyInARow.start() # Instead of accessing the GUI directly from other threads, we need to provide a clean way to change the GUI. # By using custom events, other trhead can signal the gui that it has to change. The changes will be made in # the main GUI thread def customEvent(self, event): if event.type() == self.MAKE_MOVE_EVENT: with self.lock: playerUUID = event.userData["playerUUID"] row = event.userData["row"] col = event.userData["col"] player = self.getPlayer(playerUUID) self.logList.addMessage(player, "placed: (column, row) - (" + str(col) + ", " + str(row) + ")") self.scene.makeMove(col, row, QtGui.QColor(player.color[0], player.color[1], player.color[2])) elif event.type() == self.PLAYER_WON_EVENT: with self.lock: winners = event.userData["winners"] currentGoal = event.userData["currentGoal"] winnerUUID = winners[currentGoal] player = self.getPlayer(winnerUUID) self.logList.addMessage(player, "has won round " + str(currentGoal)) # winnerBox = QtGui.QMessageBox(QtGui.QMessageBox.Information, "Round finished in game: " + "\'"+self.gameName+"\'", player.name + " has won this round", QtGui.QMessageBox.Ok, self) # winnerBox.exec_() elif event.type() == self.GAME_FINISHED_EVENT: with self.lock: self.scene.block(False) winners = event.userData["winners"] self.logList.addMessage(self.player, "The game has finished") winnerStr = "" self.aiTimer.stop() for winner in winners.items(): player = self.getPlayer(winner[1]) winnerStr = winnerStr + str(winner[0]) + " in a row: " + player.name + "\n" winnerBox = QtGui.QMessageBox( QtGui.QMessageBox.Information, "Game " + "'" + self.gameName + "' " + "finished", "The game has finished, the winners are: \n" + winnerStr, QtGui.QMessageBox.Ok, self, ) winnerBox.exec_() else: return QtCore.QObject.customEvent(event) def getGameUUID(self): return self.gameUUID def getPlayer(self, playerUUID): player = None if playerUUID in self.players.keys(): player = self.players[playerUUID] else: player = Player("Disconnected player", playerUUID) return player def aiToggled(self, state): if state == QtCore.Qt.Checked: self.aiActive = True self.aiTimer.start() else: self.aiActive = False self.aiTimer.stop() # Functions the user can trigger: def sendMessage(self): message = self.ui.chatEdit.text() self.ui.chatEdit.clear() self.manyInARow.sendChatMessage(message) def makeMove(self, column): # Passes the move to the class coordinating the game (ManyInARowGame) with self.lock: if self.aiActive: self.errorBox.setWindowTitle("AI is playing") self.errorBox.setText("The A.I. is currently playing, uncheck the checkbox to enable normal game mode.") else: self.scene.block(False) self.manyInARow.makeMove(column) def freezeGame(self): with self.lock: self.freezeButton.setDisabled(True) self.freezeButton.setText("Unfreeze") self.manyInARow.freezeGame() def unfreezeGame(self): with self.lock: self.freezeButton.setDisabled(True) self.freezeButton.setText("Freeze") self.manyInARow.unfreezeGame() # Callbacks: def aiMakeMove(self): if not self.scene.rejectClicks: self.scene.block(False) self.manyInARow._makeAiMove(self.players) def gameJoinedCallBack(self, UUID, name, description, numRows, numCols, waitTime, startTime): # We know the number of rows and colums, build the GUI board. with self.lock: self.gameUUID = UUID self.nrCols = numCols self.nrRows = numRows self.gameName = name self.comment = description self.waitTime = waitTime self.startTime = startTime if not self.layoutCreated: self.createLayout() QtCore.QObject.connect(self.scene, QtCore.SIGNAL("playerClicked(int)"), self.makeMove) QtCore.QObject.connect(self.scene, QtCore.SIGNAL("mouseHoverColumn(int)"), self.makeHoverMove) def enableClicks(self): with self.lock: self.freezeButton.setEnabled(True) if self.scene != None: self.scene.unblock(False) def disableClicks(self): with self.lock: self.freezeButton.setDisabled(True) if self.scene != None: self.scene.block(False) def playerJoinedCallBack(self, playerUUID, newPlayer): with self.lock: if not self.layoutCreated: self.createLayout() if playerUUID not in self.players.keys(): self.logList.addMessage(newPlayer, "successfully joined") self.players[playerUUID] = newPlayer self.ui.playerList.clear() for currentPlayer in self.players.values(): currentPlayer newItem = QtGui.QListWidgetItem(currentPlayer.name, self.ui.playerList) newItem.setBackgroundColor( QtGui.QColor(currentPlayer.color[0], currentPlayer.color[1], currentPlayer.color[2]) ) self.ui.playerList.addItem(newItem) def playerLeftCallBack(self, playerUUID): with self.lock: self.logList.addMessage(self.players[playerUUID], "has left") del self.players[playerUUID] self.ui.playerList.clear() for currentPlayer in self.players.values(): newItem = QtGui.QListWidgetItem(currentPlayer.name, self.ui.playerList) newItem.setBackgroundColor( QtGui.QColor(currentPlayer.color[0], currentPlayer.color[1], currentPlayer.color[2]) ) self.ui.playerList.addItem(newItem) def chatCallBack(self, playerUUID, message): with self.lock: player = self.getPlayer(playerUUID) self.logList.addMessage(player, "said: " + message) color = QtGui.QColor(player.color[0], player.color[1], player.color[2]) playerName = player.name newItem = QtGui.QListWidgetItem(playerName + ": " + message, self.ui.messageList) newItem.setBackgroundColor(color) self.ui.messageList.addItem(newItem) self.ui.messageList.scrollToItem(newItem) def moveCallBack(self, playerUUID, col, row): customEvent = CustomEvent(self.MAKE_MOVE_EVENT, {"playerUUID": playerUUID, "col": col, "row": row}) QtCore.QCoreApplication.postEvent(self, customEvent) def playerWonCallBack(self, winners, currentGoal): customEvent = CustomEvent(self.PLAYER_WON_EVENT, {"winners": winners, "currentGoal": currentGoal}) QtCore.QCoreApplication.postEvent(self, customEvent) def gameFinishedCallBack(self, winners): customEvent = CustomEvent(self.GAME_FINISHED_EVENT, {"winners": winners}) QtCore.QCoreApplication.postEvent(self, customEvent) def freezeCallback(self): with self.lock: self.freezeButton.setText("Unfreeze") QtCore.QObject.disconnect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.freezeGame) # self.freezeButton.clicked.disconnect(self.freezeGame) QtCore.QObject.connect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.unfreezeGame) self.freezeButton.setEnabled(True) self.scene.block(True) def unfreezeCallback(self): with self.lock: self.freezeButton.setEnabled(True) self.freezeButton.setText("Freeze") QtCore.QObject.disconnect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.unfreezeGame) # self.freezeButton.clicked.disconnect(self.unfreezeGame) QtCore.QObject.connect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.freezeGame) self.scene.unblock(True) def makeHoverMove(self, column): with self.lock: if not self.aiActive: row = self.manyInARow._makeDummyMove(column) if row != -1: # update the gui color = QtGui.QColor(self.player.color[0], self.player.color[1], self.player.color[2]) self.scene.makeDummyMove(column, row, color) def createLayout(self): self.ui = uic.loadUi("GameWidget.ui", self) self.scene = GraphicsScene( self.nrRows, self.nrCols, QtGui.QColor(self.player.color[0], self.player.color[1], self.player.color[2]), self, ) self.scene.block(False) self.ui.graphicsView.setScene(self.scene) self.logList = LogWidget(self) self.logList.setMaximumSize(250, 200) self.freezeButton = QtGui.QPushButton("Freeze", self) QtCore.QObject.connect(self.freezeButton, QtCore.SIGNAL("clicked()"), self.freezeGame) self.freezeButton.setDisabled(True) self.ui.verticalLayout.addWidget(self.logList) self.ui.verticalLayout.addWidget(self.freezeButton) self.ui.chatEdit.returnPressed.connect(self.sendMessage) self.ui.aiCheckBox.stateChanged.connect(self.aiToggled) self.ui.show() self.layoutCreated = True def closeEvent(self, event): if self.manyInARow != None: self.manyInARow.kill()