def end_flash(self): # 游戏结束时的闪烁操作 if self.flash_cnt <= 5: # 执行闪烁 self.flash_cnt += 1 self.repaint() else: # 闪烁完毕,执行重新开始的操作 self.end_timer.stop() # 1. 显示游戏结束的信息 if self.res == 1: QMessageBox.about(self, '游戏结束', '玩家获胜!') elif self.res == 2: QMessageBox.about(self, '游戏结束', '电脑获胜!') elif self.res == 3: QMessageBox.about(self, '游戏结束', '平局!') else: raise ValueError('当前游戏结束的标志位为' + self.res + '. 而游戏结束的标志位必须为1, 2 或 3') # 2. 游戏重新开始的操作 self.res = 0 self.operate_status = 0 self.flash_cnt = 0 self.g = Gomoku() # 重新初始化游戏内容 self.repaint(0, 0, 650, 650) # 重新绘制游戏界面
def __init__(self): super().__init__() self.init_ui() # 初始化游戏界面 self.g = Gomoku() # 初始化游戏内容 self.last_pos = (-1, -1) self.res = 0 # 记录那边获得了胜利 self.operate_status = 0 # 游戏操作状态。0为游戏中(可操作),1为游戏结束闪烁过程中(不可操作)
def start_game(self): # return to hall after the match # if return to room, must init socket, reset the to_influence by calling hook() #hall_hook = self.hall_hook self.game_board = Gomoku(self.is_master, self.room_name,\ self.master_name, self.guest_name,\ self.master_stone, self.server_ip,\ self.web_socket, self.hall_hook) self.game_board.show() self.close()
def watch_game(self): """call by action_btn, watch a match in certain room""" selected_row = self.rooms_observed.currentRow() master_name = self.room_list[selected_row + self.current_page * 10]["master"] guest_name = self.room_list[selected_row + self.current_page * 10]["guest"] room_name = self.rooms_observed.item(selected_row, 0).text() uri = 'ws://' + self.server_ip + ':8080/playing' socket_headers = [("role", 'a'),\ ("roomName", room_name),\ ("userName", self.username),\ ("masterStone", 1)] self.web_socket = SocketCli(uri, headers=socket_headers) # self.web_socket.hook(self) self.game_board = Gomoku(True, room_name, master_name,\ guest_name, 1, self.server_ip, self.web_socket,\ self.hall_hook, True) self.game_board.show() self.close()
class GameRoomWindow(QWidget): start_game_signal = pyqtSignal() def __init__(self, room_name, master_name, guest_name,\ server_ip, is_master, hall_hook, login_hook, auth_headers): super().__init__() self.auth_headers = auth_headers self.start_game_signal.connect(self.start_game) self.hall_hook = hall_hook self.login_hook = login_hook self.layout = QHBoxLayout() self.room_name = room_name self.server_ip = server_ip #self.user_name = user_name self.is_master = is_master self.master_stone = 1 self.master_name = master_name self.guest_name = guest_name self.title = "Game Hall" self.top = 100 self.left = 100 self.width = 600 self.height = 200 self.ready = False self.init_socket() self.init_ui() def init_ui(self): self.setWindowTitle(self.title) self.setGeometry(self.top, self.left, self.width, self.height) current_path = ':/' # sys.path[0] + '/' self.setWindowIcon( QIcon(current_path + 'chessboard/gomoku_icon.png')) # set window icon self.stone_color_label = QLabel("Creator will use:", self) self.stone_color_label.move(255, 14) self.colors = QComboBox(self) self.colors.addItems(["Black", "White"]) self.colors.setGeometry(250, 40, 100, 20) self.colors.setEnabled(self.is_master) if self.is_master: self.colors.currentIndexChanged.connect(self.handle_color_change) self.start_button_label = QLabel("Start the game:", self) self.start_button_label.move(405, 14) self.start_button = QPushButton('Start', self) self.start_button.move(400, 34) self.start_button.clicked.connect(self.handle_start) self.start_button.setEnabled(False) self.leave_button_label = QLabel("Leave the game:", self) self.leave_button_label.move(255, 74) self.leave_button = QPushButton(' Leave ', self) self.leave_button.move(250, 94) self.leave_button.clicked.connect(self.handle_leave) self.guest_status_label = QLabel("Guest is:", self) self.guest_status_label.move(405, 74) self.ready_button = QPushButton('Unready', self) self.ready_button.move(400, 94) self.ready_button.clicked.connect(self.handle_ready) self.ready_button.setEnabled(not self.is_master) self.start_button.resize(self.leave_button.sizeHint()) self.ready_button.resize(self.leave_button.sizeHint()) self.room_status_label = QLabel(self) self.room_status_label.move(255, 140) # id label self.id_label = QLabel(self) self.id_label.move(40, 14) self.role_label = QLabel(self) self.role_label.move(40, 44) if self.is_master: self.id_label.setText("Your id: " + self.master_name) self.role_label.setText("You're creator of this room.") self.room_status_label.setText("Waiting for player ...") else: self.id_label.setText("Your id: " + self.guest_name) self.role_label.setText("You're guest of this room.") self.room_status_label.setText("Creator id: " + self.master_name) self.show() def handle_message(self, message): print("Received: ", message) if message[0] == 'J': # join signal if self.is_master: self.guest_name = message[1:] self.room_status_label.setText("Guest id: " + self.guest_name) if self.colors.currentText() == 'Black': self.master_stone = 1 self.web_socket.send(BLACK_STONE_SIGNAL_MESSAGE) else: self.master_stone = 2 self.web_socket.send(WHITE_STONE_SIGNAL_MESSAGE) else: try: signal = int(message) print("signal", signal) if signal < 0: # START_SIGNAL = -1 # GUEST_READY_SIGNAL = -2 # GUEST_UNREADY_SIGNAL = -3 # GUEST_LEAVE_SIGNAL = -4 # MASTER_DELETE_SIGNAL = -5 # END_SIGNAL = -6 if self.is_master: if signal == GUEST_READY_SIGNAL: print("ready") self.ready = True self.start_button.setEnabled(True) self.ready_button.setText("Ready") elif signal == GUEST_UNREADY_SIGNAL: print("unready") self.ready = False self.start_button.setEnabled(False) self.ready_button.setText("Unready") elif signal == GUEST_LEAVE_SIGNAL: self.ready = False self.start_button.setEnabled(self.ready) self.ready_button.setText("Unready") self.guest_name = None self.room_status_label.setText( "Waiting for player ...") elif signal == START_SIGNAL: print("try to start") self.start_game_signal.emit() else: print("Unvalid master control signal.") else: if signal == START_SIGNAL: print("try to start") self.start_game_signal.emit() elif signal == MASTER_DELETE_SIGNAL: self.hall_hook() self.close() # TODO: pop a message box elif signal == BLACK_STONE_SIGNAL: self.master_stone = 1 self.colors.setCurrentIndex( self.colors.findText('Black')) elif signal == WHITE_STONE_SIGNAL: self.master_stone = 2 self.colors.setCurrentIndex( self.colors.findText('White')) else: print("Unvalid guest control signal.") # control signal else: # should not be processed now print("Moving signal, game does not start yet.") except: print("Unvalid message format.") @pyqtSlot() def start_game(self): # return to hall after the match # if return to room, must init socket, reset the to_influence by calling hook() #hall_hook = self.hall_hook self.game_board = Gomoku(self.is_master, self.room_name,\ self.master_name, self.guest_name,\ self.master_stone, self.server_ip,\ self.web_socket, self.hall_hook) self.game_board.show() self.close() def init_socket(self): # uri = 'ws://' + self.server_ip + ':8080/playing' # role can be: "m" for master, "g" for guest, "a" for audience # if master use balck stone, "master_stone:1", if white, "master_stone:2" # if self.colors.currentText() == 'Black': # master_stone = '1' # else: # master_stone = '2' self.uri = 'ws://' + self.server_ip + ':8080/playing' # self.uri = 'ws://' + self.server_ip + ':8080/test' if self.is_master: role = 'm' user_name = self.master_name else: role = 'g' user_name = self.guest_name self.headers = [("role", role),\ ("roomName", self.room_name),\ ("userName", user_name),\ ("masterStone", self.master_stone)] self.web_socket = SocketCli(self.uri, headers=self.headers) self.web_socket.connect() self.web_socket.hook(self) if not self.is_master: print("before send join") self.web_socket.send('J' + self.guest_name) print("sent join") @pyqtSlot() def handle_color_change(self): if self.colors.currentText() == 'Black': self.master_stone = 1 print("send: change to balck") self.web_socket.send(BLACK_STONE_SIGNAL_MESSAGE) else: self.master_stone = 2 print("send: change to white") self.web_socket.send(WHITE_STONE_SIGNAL_MESSAGE) @pyqtSlot() def handle_start(self): # donot need to send info to redis, # done by server self.web_socket.send(START_SIGNAL_MESSAGE) @pyqtSlot() def handle_leave(self): # donot need to send info to redis, # done by server if self.is_master: response = requests.get('http://' + self.server_ip +\ ':8080/room/delete/'+ self.room_name + '/' +\ self.master_name, headers=self.auth_headers) # if response.text == 'Success': # self.web_socket.send(MASTER_DELETE_SIGNAL_MESSAGE) # self.hall_hook() # self.close() # elif response.text == "Unauthorized or timeout.": # pop_info_and_back(self, response.text, self.login_hook) # else: print('#### Info: master delete: ' + response.text) if response.text == 'Success': print("Success") self.web_socket.send(MASTER_DELETE_SIGNAL_MESSAGE) self.web_socket.close() self.hall_hook() else: print("Fail") self.web_socket.close() self.hall_hook(refresh=True) self.close() else: response = requests.get('http://' + self.server_ip +\ ':8080/room/leave/'+ self.room_name + '/' +\ self.guest_name, headers=self.auth_headers) # if response.text == 'Success': # self.web_socket.send(GUEST_LEAVE_SIGNAL_MESSAGE) # self.hall_hook() # self.close() # elif response.text == "Unauthorized or timeout.": # pop_info_and_back(self, response.text, self.login_hook) # else: # print(response.text) print('#### Info: guest leave: ' + response.text) self.web_socket.send(GUEST_LEAVE_SIGNAL_MESSAGE) self.web_socket.close() self.hall_hook() self.close() if response.text == 'Success': print("Success") self.web_socket.close() self.hall_hook() else: print("Fail") self.web_socket.close() self.hall_hook(refresh=True) self.close() @pyqtSlot() def handle_ready(self): # donot need to send info to redis, # done by server if self.ready: self.ready = False self.web_socket.send(GUEST_UNREADY_SIGNAL_MESSAGE) self.ready_button.setText("Unready") else: self.ready = True self.web_socket.send(GUEST_READY_SIGNAL_MESSAGE) self.ready_button.setText("Ready")
class GomokuWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() # 初始化游戏界面 self.g = Gomoku() # 初始化游戏内容 self.last_pos = (-1, -1) self.res = 0 # 记录那边获得了胜利 self.operate_status = 0 # 游戏操作状态。0为游戏中(可操作),1为游戏结束闪烁过程中(不可操作) def init_ui(self): """初始化游戏界面""" # 1. 确定游戏界面的标题,大小和背景颜色 self.setObjectName('MainWindow') self.setWindowTitle('五子棋') self.setFixedSize(650, 650) palette = QPalette() palette.setBrush(QPalette.Window, QBrush(QPixmap('imgs/muzm.jpg'))) # 把背景替换成木质桌面 self.setPalette(palette) # 2. 开启鼠标位置的追踪。并在鼠标位置移动时,使用特殊符号标记当前的位置 self.setMouseTracking(True) # 3. 鼠标位置移动时,对鼠标位置的特殊标记 self.corner_widget = CornerWidget(self) self.corner_widget.repaint() self.corner_widget.hide() # 4. 游戏结束时闪烁的定时器 self.end_timer = QTimer(self) self.end_timer.timeout.connect(self.end_flash) self.flash_cnt = 0 # 游戏结束之前闪烁了多少次 self.flash_pieces = ((-1, -1), ) # 哪些棋子需要闪烁 # 5. 显示初始化的游戏界面 self.show() @run_with_exc def paintEvent(self, e): """绘制游戏内容""" def draw_map(): """绘制棋盘""" qp.setPen(QPen(QColor(0, 0, 0), 2, Qt.SolidLine)) # 棋盘的颜色为黑色 # 绘制横线 for x in range(15): qp.drawLine(40 * (x + 1), 40, 40 * (x + 1), 600) # 绘制竖线 for y in range(15): qp.drawLine(40, 40 * (y + 1), 600, 40 * (y + 1)) # 绘制棋盘中的星位(黑色圆点) qp.setBrush(QColor(0, 0, 0)) key_points = [(4, 4), (12, 4), (4, 12), (12, 12), (8, 8)] for t in key_points: qp.drawEllipse(QPoint(40 * t[0], 40 * t[1]), 5, 5) def draw_pieces(): """绘制棋子""" # 绘制黑棋子 qp.setPen(QPen(QColor(0, 0, 0), 1, Qt.SolidLine)) # qp.setBrush(QColor(0, 0, 0)) for x in range(15): for y in range(15): if self.g.g_map[x][y] == 1: if self.flash_cnt % 2 == 1 and (x, y) in self.flash_pieces: continue radial = QRadialGradient(40 * (x + 1), 40 * (y + 1), 15, 40 * x + 35, 40 * y + 35) # 棋子的渐变效果 radial.setColorAt(0, QColor(96, 96, 96)) radial.setColorAt(1, QColor(0, 0, 0)) qp.setBrush(QBrush(radial)) qp.drawEllipse(QPoint(40 * (x + 1), 40 * (y + 1)), 15, 15) # 绘制白棋子 qp.setPen(QPen(QColor(160, 160, 160), 1, Qt.SolidLine)) # qp.setBrush(QColor(255, 255, 255)) for x in range(15): for y in range(15): if self.g.g_map[x][y] == 2: if self.flash_cnt % 2 == 1 and (x, y) in self.flash_pieces: continue radial = QRadialGradient(40 * (x + 1), 40 * (y + 1), 15, 40 * x + 35, 40 * y + 35) # 棋子的渐变效果 radial.setColorAt(0, QColor(255, 255, 255)) radial.setColorAt(1, QColor(160, 160, 160)) qp.setBrush(QBrush(radial)) qp.drawEllipse(QPoint(40 * (x + 1), 40 * (y + 1)), 15, 15) if hasattr(self, 'g'): # 游戏还没开始的话,就不用画了 qp = QPainter() qp.begin(self) draw_map() # 绘制棋盘 draw_pieces() # 绘制棋子 qp.end() @run_with_exc def mouseMoveEvent(self, e): # 1. 首先判断鼠标位置对应棋盘中的哪一个格子 mouse_x = e.windowPos().x() mouse_y = e.windowPos().y() if 25 <= mouse_x <= 615 and 25 <= mouse_y <= 615 and (mouse_x % 40 <= 15 or mouse_x % 40 >= 25) and (mouse_y % 40 <= 15 or mouse_y % 40 >= 25): game_x = int((mouse_x + 15) // 40) - 1 game_y = int((mouse_y + 15) // 40) - 1 else: # 鼠标当前的位置不对应任何一个游戏格子,将其标记为(01, 01 game_x = -1 game_y = -1 # 2. 然后判断鼠标位置较前一时刻是否发生了变化 pos_change = False # 标记鼠标位置是否发生了变化 if game_x != self.last_pos[0] or game_y != self.last_pos[1]: pos_change = True self.last_pos = (game_x, game_y) # 3. 最后根据鼠标位置的变化,绘制特殊标记 if pos_change and game_x != -1: self.setCursor(Qt.PointingHandCursor) if pos_change and game_x == -1: self.setCursor(Qt.ArrowCursor) if pos_change and game_x != -1: self.corner_widget.move(25 + game_x * 40, 25 + game_y * 40) self.corner_widget.show() if pos_change and game_x == -1: self.corner_widget.hide() @run_with_exc def mousePressEvent(self, e): """根据鼠标的动作,确定落子位置""" if not (hasattr(self, 'operate_status') and self.operate_status == 0): return if e.button() == Qt.LeftButton: # 1. 首先判断按下了哪个格子 mouse_x = e.windowPos().x() mouse_y = e.windowPos().y() if (mouse_x % 40 <= 15 or mouse_x % 40 >= 25) and (mouse_y % 40 <= 15 or mouse_y % 40 >= 25): game_x = int((mouse_x + 15) // 40) - 1 game_y = int((mouse_y + 15) // 40) - 1 else: # 鼠标点击的位置不正确 return self.g.move_1step(True, game_x, game_y) # 2. 根据操作结果进行一轮游戏循环 res, self.flash_pieces = self.g.game_result(show=True) # 判断游戏结果 if res != 0: # 如果游戏结果为“已经结束”,则显示游戏内容,并退出主循环 self.repaint(0, 0, 650, 650) self.game_restart(res) return # self.g.ai_move_1step() # 电脑下一步 self.g.ai_play_1step() # 电脑下一步 res, self.flash_pieces = self.g.game_result(show=True) if res != 0: self.repaint(0, 0, 650, 650) self.game_restart(res) return self.repaint(0, 0, 650, 650) # 在游戏还没有结束的情况下,显示游戏内容,并继续下一轮循环 @run_with_exc def end_flash(self): # 游戏结束时的闪烁操作 if self.flash_cnt <= 5: # 执行闪烁 self.flash_cnt += 1 self.repaint() else: # 闪烁完毕,执行重新开始的操作 self.end_timer.stop() # 1. 显示游戏结束的信息 if self.res == 1: QMessageBox.about(self, '游戏结束', '玩家获胜!') elif self.res == 2: QMessageBox.about(self, '游戏结束', '电脑获胜!') elif self.res == 3: QMessageBox.about(self, '游戏结束', '平局!') else: raise ValueError('当前游戏结束的标志位为' + self.res + '. 而游戏结束的标志位必须为1, 2 或 3') # 2. 游戏重新开始的操作 self.res = 0 self.operate_status = 0 self.flash_cnt = 0 self.g = Gomoku() # 重新初始化游戏内容 self.repaint(0, 0, 650, 650) # 重新绘制游戏界面 def game_restart(self, res): """游戏出现开始""" self.res = res # 标记谁获胜了 self.operate_status = 1 # 游戏结束时的闪烁过程中,不可操作 self.end_timer.start(300) # 开始结束时闪烁的计时器
def main(): g = Gomoku() g.play()
class GameHallWindow(QWidget): """Game hall window, create/ join/ watch a match""" def __init__(self, username, server_ip, auth_headers, login_hook, manual_hook): super().__init__() self.auth_headers = auth_headers self.login_hook = login_hook self.manual_hook = manual_hook self.server_ip = server_ip self.username = username self.current_page = -1 self.title = "Game Hall" self.top = 100 self.left = 100 self.width = 700 self.height = 500 self.init_ui() self.refresh() def init_ui(self): """ init the ui of game hall: table, buttons. And set the style of them """ self.setWindowTitle(self.title) self.setWindowIcon(QIcon('chessboard/gomoku_icon.png')) # set window icon self.setGeometry(self.top, self.left, self.width, self.height) self.create_room_button = QPushButton('Create', self) self.create_room_button.move(580, 20) self.create_room_button.clicked.connect(self.handle_create_room) self.action_button = QPushButton('Action', self) self.action_button.move(580, 70) self.action_button.clicked.connect(self.handle_action) # disable the action button at first self.action_button.setEnabled(False) self.refresh_button = QPushButton('Refresh', self) self.refresh_button.move(580, 120) self.refresh_button.clicked.connect(self.refresh) self.back_button = QPushButton('Back', self) self.back_button.move(580, 340) self.back_button.clicked.connect(self.handle_back) self.exit_button = QPushButton('Exit', self) self.exit_button.move(580, 390) self.exit_button.clicked.connect(self.handle_exit) # room list, using table self.rooms_observed = QTableWidget(self) self.rooms_observed.setRowCount(10) self.rooms_observed.setColumnCount(2) # change the action button after selecting a room self.rooms_observed.clicked.connect(self.handle_click_room_observed) # set column name self.rooms_observed.setHorizontalHeaderLabels(['Room Name', 'Status']) self.rooms_observed.setGeometry(50, 20, 500, 400) # cannot edit self.rooms_observed.setEditTriggers(QAbstractItemView.NoEditTriggers) # choose whole row self.rooms_observed.setSelectionBehavior(QAbstractItemView.SelectRows) # at most select one row self.rooms_observed.setSelectionMode(QAbstractItemView.SingleSelection) # hide vertical header self.rooms_observed.verticalHeader().setVisible(False) # fix the table width self.rooms_observed.setColumnWidth(0, 400) self.rooms_observed.setColumnWidth(1, 99) # disable the scrol bar self.rooms_observed.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.rooms_observed.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # disable resizing table self.rooms_observed.setCornerButtonEnabled(False) self.rooms_observed.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed) self.create_room_button.resize(self.refresh_button.sizeHint()) self.action_button.resize(self.refresh_button.sizeHint()) self.exit_button.resize(self.refresh_button.sizeHint()) self.back_button.resize(self.refresh_button.sizeHint()) self.show() @pyqtSlot() def refresh(self): """handle clicking refresh button, refresh the room info in the table""" response = requests.get('http://%s:8080/room/all'\ % self.server_ip,\ headers=self.auth_headers) try: self.room_list = response.json() print(self.room_list) self.max_page = int(len(self.room_list) / 10) self.current_page = -1 self.browse(0) # refresh chane the room list, should init the action btn self.action_button.setEnabled(False) self.action_button.setText("Action") except: pop_info_and_back(self, response.text, self.login_hook) # info = response.text # button = QMessageBox.question(self, "Info",\ # info,\ # QMessageBox.Ok,\ # QMessageBox.Ok) # if button == QMessageBox.Ok: # self.login_hook() # self.close() # else: # self.close() # raise SystemExit(0) def browse(self, page): """choose the page of rooms to browse""" if self.current_page != page: self.rooms_observed.clearContents() self.current_page = page for i in range(10): if self.current_page*10+i >= len(self.room_list): break self.add_line(self.room_list[self.current_page*10 + i], i) def add_line(self, a_room, row_num): """add a room into the table, call by browse""" self.rooms_observed.setItem(row_num, 0, QTableWidgetItem(a_room['roomName'])) self.rooms_observed.setItem(row_num, 1, QTableWidgetItem(a_room['roomStatus'])) @pyqtSlot() def handle_create_room(self): """create a room, call create window""" self.create_room_page = CreateRoomWindow(master_name=self.username,\ server_ip=self.server_ip,\ hall_hook=self.hall_hook,\ login_hook=self.login_hook,\ auth_headers=self.auth_headers) self.create_room_page.show() self.close() @pyqtSlot() def handle_action(self): """watch or join or disable based on the room chosen""" # selected_row = self.rooms_observed.currentRow() action = self.action_button.text() print(action) if action == "Join": self.join_room() elif action == "Watch": # try to watch the game self.watch_game() def watch_game(self): """call by action_btn, watch a match in certain room""" selected_row = self.rooms_observed.currentRow() master_name = self.room_list[selected_row + self.current_page * 10]["master"] guest_name = self.room_list[selected_row + self.current_page * 10]["guest"] room_name = self.rooms_observed.item(selected_row, 0).text() uri = 'ws://' + self.server_ip + ':8080/playing' socket_headers = [("role", 'a'),\ ("roomName", room_name),\ ("userName", self.username),\ ("masterStone", 1)] self.web_socket = SocketCli(uri, headers=socket_headers) # self.web_socket.hook(self) self.game_board = Gomoku(True, room_name, master_name,\ guest_name, 1, self.server_ip, self.web_socket,\ self.hall_hook, True) self.game_board.show() self.close() @pyqtSlot() def handle_exit(self): """exit the programm, pop a window to ensure""" reply = QMessageBox.question(self, 'Exit', 'You sure to exit?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: # TODO: other actions self.close() @pyqtSlot() def handle_back(self): self.manual_hook() self.close() @pyqtSlot() def handle_click_room_observed(self): """ select a room in the table, change the action_btn based on the game status """ selected_row = self.rooms_observed.currentRow() try: select_status = self.rooms_observed.item(selected_row, 1).text() self.action_button.setEnabled(True) if select_status == 'Open': self.action_button.setText("Join") elif select_status == 'Playing': self.action_button.setText("Watch") else: self.action_button.setEnabled(False) self.action_button.setText("Action") except: self.action_button.setEnabled(False) self.action_button.setText("Action") def join_room(self): """join the room as a guest""" selected_row = self.rooms_observed.currentRow() try: room_name = self.rooms_observed.item(selected_row, 0).text() uri = "http://%s:8080/room/join/%s/%s"\ % (self.server_ip, room_name, self.username) result = requests.get(uri, headers=self.auth_headers) print('from server: '+ result.text) if result.text == "Success": master_name = self.room_list[selected_row + self.current_page * 10]["master"] self.game_room = GameRoomWindow(room_name, master_name,\ self.username, self.server_ip, False, self.hall_hook,\ self.login_hook, self.auth_headers) self.game_room.show() self.close() else: QMessageBox.warning(self, 'Error', result.text) except Exception as e: print(e) QMessageBox.warning(self, 'Error', "Try again.") def hall_hook(self, refresh=True): self.show() if refresh: self.refresh()