Форум программистов, компьютерный форум, киберфорум
Python: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
 Аватар для lenusscik
0 / 0 / 0
Регистрация: 03.11.2019
Сообщений: 77
PyQt5

Ожидание получения сигнала от пользователя в цикле игры

20.03.2022, 10:37. Показов 1001. Ответов 2

Студворк — интернет-сервис помощи студентам
Добрый день. Имеется игра, скажем к примеру монополия. Взаимодействие компонентов осуществлено на основе архитектуры mvc. Имеется интерфейс пользователя в view, контроллер, который отвечает за обработку сигналов от view, и модель, где расположен весь функционал приложения и которая манипулирует view.
Теперь подробнее о проблеме. В модели есть функция запуска главного цикла игры, обозначим как game_loop. Код и общая схема приведены ниже
Проблема состоит в том, что мне нужно, чтобы скрипт внутри while ожидал пока игрок не будет готов продолжить игру, путем вызова события(именно события абстрактного, тк игроком может быть также и бот, т.е. алгоритм, который взаимодействует напрямую с контроллером, путем вызова соответствующих событий, методов) Т.е. цикл должен либо приостановиться, пока не наступит событие от игрока, либо крутиться бесконечно с тем же условием. Причем, игрок в это время может и должен взаимодействовать с программой и интерфейсом, путем нажатия кнопок в view pyqt5, после чего должны выполняться действия в модели. И что самое главное, приложение не должно подвисать.

Обобщая вопрос: в цикле должна быть проверка на поступление события от игрока, сам игрока до наступления этого события может и должен взаимодействовать с gui. Я не понимаю, как это реализовать, чтобы не зависало намертво приложение, крутясь в цикле.

С потоками не знаком, но готов ко всем вариантам решений данной проблемы, при должном пояснении.

while running:
# выбираем текущего игрока из 2х
#у него проверяем флаги возможности продолжить игру getMoved
#ждем пока наступит событие от игрока о готовности продолжить игру
#бросаем кубик, получаем значение хода getViewCube
#выполняем ход
#выполняем действия на заданной ячейке process

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def gameLoop(self):
        condition = 0 # 0 игра на банкротство, 1 игра на количество кругов
        lapsCount = 6
        selector = 0
        curPlaceIndex = [0,0]
        running = True
        while running:
            curPlayer = self.playerList.items[selector]
            if curPlayer.getMoved():
                if curPlayer.getReady(): #????????? тут представлена попытка реализации без вызова события, через проверку флагов игрока, не очень удачная идея, поэтому будет событие
                    curPlayer.setReady(False)
                    cubeValue = self.getViewCube()
                    nextPlaceIndex = curPlaceIndex[selector]+cubeValue
                    self.view.ui.drivePlayer(selector, cubeValue)
                    if nextPlaceIndex >= len(self.cardList.items):
                        curPlaceIndex[selector] = nextPlaceIndex-len(self.cardList.items)
                        curPlayer.addLap()
                        curPlayer.addCash(DEF_LAP_CASH)
                        curPlayer.showMessage(f'прошел круг.')
                    else:
                        curPlaceIndex[selector] = nextPlaceIndex
                    self.cardList.items[curPlaceIndex[selector]].process(curPlayer)    
            else:
                turma1 = self.cardList.get('turma1')
                turma2 = self.cardList.get('turma2')
                hotel = self.cardList.get('hotel')
                if turma1.getPrisoners(curPlayer):
                    turma1.process(curPlayer)
                elif turma2.getPrisoners(curPlayer):
                    turma2.process(curPlayer)
                elif hotel.getPrisoners(curPlayer):
                    hotel.process(curPlayer)
                  
            if condition == 0:
                if self.playerList.items[0].getCash()+self.playerList.items[0].getCapital()<=0:
                    running = False
                    self.playerList.items[0].showMessage('банкрот! Игра окончена!')
                elif self.playerList.items[1].getCash()+self.playerList.items[1].getCapital()<=0:
                    running = False
                    self.playerList.items[1].showMessage('банкрот! Игра окончена!')
                    
            elif condition == 1:
                laps = max(self.playerList.items[0].getLaps(), self.playerList.items[1].getLaps())
                if laps>=lapsCount:
                    running=False
                    self.showMessage('Игра окончена!')
                    pl_0 =  self.playerList.items[0].getCapital()+self.playerList.items[0].getCash()
                    pl_1 =  self.playerList.items[1].getCapital()+self.playerList.items[1].getCash()
                    if pl_0>pl_1:
                        self.showMessage(f'Победил {self.playerList.items[0].getName()}')
                    elif pl_1>pl_0:
                        self.showMessage(f'Победил {self.playerList.items[1].getName()}')
                    else:
                        self.showMessage('Ничья!')
                        
            selector = 1 - selector
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.03.2022, 10:37
Ответы с готовыми решениями:

Ожидание получения имени
Нужно получить имя для последующих действий, в функции после создания текстового поля нужно ожидать пока пользователь впишет значение. Как...

Ожидание сигнала
Приветствую! Проблема такая. Есть кнопка, при нажатии она испускает сигнал, но таймер должен запустится только тогда когда изменится...

Получения спектра сигнала
Вообщем есть функция сигнала (допустим синус на синус с разными частотами) и теперь мне надо сделать вывод как на спектроанализаторе - что...

2
290 / 205 / 68
Регистрация: 18.09.2019
Сообщений: 407
Записей в блоге: 58
20.03.2022, 15:42
Наверное, добавление в цикл
Python
1
QApplication.processEvents()
всё таки не поможет.
Можно попробовать цикл по другому организовать, например, с помощью QTimer:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
 
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWidgets import QAction, QWidget
from PyQt5.QtWidgets import QVBoxLayout, QProgressBar
from PyQt5.QtWidgets import QLabel, QPushButton
from PyQt5.QtWidgets import QStyleFactory
from PyQt5.QtCore import QTimer
 
BAR_MIN = 0
BAR_MAX = 100
BAR_TIMEOUT = 100
 
class Main_window(QMainWindow):
    def __init__(self, parent=None):
        super(Main_window, self).__init__(parent)
 
        self.is_running = False
        self.is_inverted = False
 
        exit_action = QAction(
            'Выход', self, shortcut='Ctrl+Q',
            statusTip=('Завершить работу'),
            triggered=self.close, enabled=True)
 
        task_menu = self.menuBar().addMenu('Файл')
        task_menu.addAction(exit_action)
 
        self.cw_bar = QProgressBar(self)
        self.cw_bar.setRange(BAR_MIN, BAR_MAX)
        self.cw_bar.setValue(BAR_MIN)
        self.cw_lbl = QLabel('Не работает', self)
        self.cw_btn = QPushButton('СТАРТ', self)
 
        cw_map = QVBoxLayout()
        cw_map.addWidget(self.cw_bar)
        cw_map.addWidget(self.cw_lbl)
        cw_map.addWidget(self.cw_btn)
        cw_map.addStretch(1)
 
        central_widget = QWidget(self)
        central_widget.setLayout(cw_map)
        self.setCentralWidget(central_widget)
 
        self.cw_btn.pressed.connect(self.on_button_pressed)
 
    def on_button_pressed(self):
        self.is_running = not self.is_running
        if self.is_running:
            self.cw_lbl.setText('Работает')
            self.cw_btn.setText('СТОП')
            self.running_bar()
        else:
            self.cw_lbl.setText('Не работает')
            self.cw_btn.setText('СТАРТ')
 
    def running_bar(self):
        if (((self.cw_bar.value() <= BAR_MIN) and self.is_inverted) or
            ((self.cw_bar.value() >= BAR_MAX) and not self.is_inverted)):
 
            self.is_inverted = not self.is_inverted
 
        elif self.is_inverted:
            self.cw_bar.setValue(self.cw_bar.value() - 1)
        else:
            self.cw_bar.setValue(self.cw_bar.value() + 1)
 
        if self.is_running:
            QTimer.singleShot(BAR_TIMEOUT, self.running_bar)
 
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    if 'Windows' in QStyleFactory.keys():
        app.setStyle(QStyleFactory.create('Windows'))
 
    m_win = Main_window()
    m_win.show()
 
    sys.exit(app.exec_())
0
963 / 718 / 276
Регистрация: 10.12.2016
Сообщений: 1,764
20.03.2022, 16:04
lenusscik, теоретически есть два метода - прерывание и опрос
в Qt опрос реализуется по таймеру, прерывание - сигнал-слот
потоки имеют смысл при выполнении какой-то длинной задачи, чтобы не вис GUI. для ожидания их применять имхо не надо
в любом приложении Qt есть eventLoop( QApplication.exec) , так что ваша gameLoop нарушит работу приложения
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.03.2022, 16:04
Помогаю со студенческими работами здесь

Мат ожидание и дисперсия сигнала
Есть сигнал *.mat собственно ему и нужно посчитать мат ожидание и дисперсию. Файл прикрепил. Если кто то может помочь, буду премного...

Ожидание приема сигнала в потоке
Есть материнский поток и два дочерних. Эти дочерние обмениваются информацией между собой посредством сигналов, объекты друг друга им...

Получения сигнала о завершении печати
Суть проблемы проста - нужно получить сигнал что принтер закончил печать всех страниц. Проблема в том, что QPrinter завершает свою работу...

Получения амплитуды сигнала с микрофона
Доброго времени, есть у меня тут задачка, нужно получить амплитуду (уровень сигнала) с микрофона желательно средствами Win API или на...

Какова вероятность получения искаженного сигнала
По линии связи, имеющей 4 приемно-передающих пункта, передается сообщение. На первом пункте происходит искажение сообщения с вероятностью...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru