How can I run pygame and PyQt5 together but seperately?

Question:

I have a question about using pyqt5 and pygame. I have already made a pygame script and a pyqt5 script. The problem is that when I want to make pygame excute the game, it shows a ranking board in pyqt5 and plays game by a pygame script.

This is my pyqt UI code:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QMovie
import rankingUI
import sys
import main
import pickle
import subprocess

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setFixedSize(800,400)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # create label
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.move(0,0)

        # start button
        self.button = QtWidgets.QPushButton(self.centralwidget)
        self.button.setGeometry(320,300,150,100)
        self.button.setStyleSheet("border-image:url(./assets/ui/start_btn.png); border:0px;")
        self.button.clicked.connect(self.game_start)

        # title
        self.title = QtWidgets.QLabel(self.centralwidget)
        self.title.setGeometry(250, 10, 300, 100)
        self.title.setStyleSheet("border-image:url(./assets/ui/dinotitle.png); border:0px;")

        # input nick
        self.nick_inp = QtWidgets.QLineEdit("ENTER YOUR NICK",self.centralwidget)
        self.nick_inp.setAlignment(QtCore.Qt.AlignCenter)
        self.nick_inp.setGeometry(320,290, 150 ,20)

        #ranking
        self.ranking_btn = QtWidgets.QPushButton(self.centralwidget)
        self.ranking_btn.setStyleSheet("border-image:url(./assets/ui/rank_btn.png); border:0px;")
        self.ranking_btn.setGeometry(730, 325, 50, 50)
        self.ranking_btn.clicked.connect(self.popup_ranking)

        # add popup
        self.add_dia = QtWidgets.QDialog()
        self.rank_dia = QtWidgets.QDialog()


        # add label to main window
        MainWindow.setCentralWidget(self.centralwidget)

        # set qmovie as label
        self.movie = QMovie("assets/ui/dinogif.gif")
        self.label.setMovie(self.movie)
        self.movie.start()

    def game_start(self):
        player_nick = self.nick_inp.text()
        if(len(player_nick)==0):
            self.nick_inp.setText("ENTER YOUR NICK")
            return
        main.game_start(player_nick)

    def popup_ranking(self):
        # ui init
        self.rank_dia.setWindowModality(QtCore.Qt.ApplicationModal)
        self.rank_dia.setWindowTitle("RANKING")
        self.rank_dia.setFixedSize(500,330)
        rank_label = QtWidgets.QLabel("RANKKING")
        rank_label.setAlignment(QtCore.Qt.AlignCenter)
        rank_label.setFont(QtGui.QFont('Arial', 30))
        output = QtWidgets.QTextEdit()
        output.setFont(QtGui.QFont('Ubuntu',15))
        window = QtWidgets.QVBoxLayout()
        window.addWidget(rank_label)
        window.addWidget(output)

        # read data
        rank_list = []
        ranking_dat = open("ranking.dat", 'rb')
        try:
            rank_list = pickle.load(ranking_dat)
        except:
            pass
        ranking_dat.close()


        # write data
        strFormat = '%-18s%-18s%-18sn'
        strOut = strFormat % ('RANK', 'SCORE', 'NICK')
        rank_num = 1
        strFormat = '%-20s%-20s%-20sn'
        for x in sorted(rank_list, key=lambda s: s["Score"], reverse=True):
            tmp = []
            tmp.append(str(rank_num))
            rank_num += 1
            for y in x:
                tmp.append(str(x[y]))
            strOut += strFormat % (tmp[0], tmp[2], tmp[1])
            if rank_num == 10:
                break

        output.setText(strOut)
        self.rank_dia.setLayout(window)
        self.rank_dia.show()

    # def score_reg(self):
    #     # popup UI setting
    #     self.add_dia.setWindowTitle("score registration")
    #     self.add_dia.setWindowModality(QtCore.Qt.ApplicationModal)
    #     self.add_dia.setFixedSize(300,70)
    #
    #     # add widget
    #     nick_label = QtWidgets.QLabel("Insert Nickname :")
    #     self.nick_input = QtWidgets.QLineEdit()
    #     score_label = QtWidgets.QLabel("Your Score : ")
    #     self.score_input = QtWidgets.QLabel("333")
    #     reg_btn = QtWidgets.QPushButton("register")
    #     reg_btn.clicked.connect(self.register)
    #
    #     h_box1 = QtWidgets.QHBoxLayout()
    #     h_box1.addWidget(nick_label)
    #     h_box1.addWidget(self.nick_input)
    #
    #     h_box2 = QtWidgets.QHBoxLayout()
    #     h_box2.addWidget(score_label)
    #     h_box2.addWidget(self.score_input)
    #     h_box2.addStretch()
    #     h_box2.addWidget(reg_btn)
    #
    #     v_box = QtWidgets.QVBoxLayout()
    #     v_box.addLayout(h_box1)
    #     v_box.addLayout(h_box2)
    #
    #     self.add_dia.setLayout(v_box)
    #     self.add_dia.show()
    #
    # def register(self):
    #     print(self.nick_input.text())
    #     print(self.score_input.text())


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(window)
    window.show()
    sys.exit(app.exec_())

This is the pygame code:

import pygame as pyg
import os
import random
import sys
import pickle
import pygame.time
import ui

nickname = ...
# 화면 크기
SCREEN_HEIGHT = 600
SCREEN_WIDTH = 1600
SCREEN = ...
# 달리는 모션 (running1, running2)
RUNNING_MOTIONS = [pyg.image.load(os.path.join("assets/Dino", "DinoRun1.png")),
                   pyg.image.load(os.path.join("assets/Dino", "DinoRun2.png"))]
# 뛰는 모션, 숙이는 모션 (stooping1, stooping2)
JUMPING_MOTION = pyg.image.load(os.path.join("assets/Dino", "DinoJump.png"))

STOOPING_MOTIONS = [pyg.image.load(os.path.join("assets/Dino", "DinoStoop1.png")),
                    pyg.image.load(os.path.join("assets/Dino", "DinoStoop2.png"))]
# 선인장
SMALL_CACTUS_IMG = [pyg.image.load(os.path.join("assets/Cactus", "SmallCactus1.png")),
                    pyg.image.load(os.path.join("assets/Cactus", "SmallCactus2.png")),
                    pyg.image.load(os.path.join("assets/Cactus", "SmallCactus3.png"))]
LARGE_CACTUS_IMG = [pyg.image.load(os.path.join("assets/Cactus", "LargeCactus1.png")),
                    pyg.image.load(os.path.join("assets/Cactus", "LargeCactus2.png")),
                    pyg.image.load(os.path.join("assets/Cactus", "LargeCactus3.png"))]
# 새 모션
BIRD_MOTIONS = [pyg.image.load(os.path.join("assets/Bird", "Bird1.png")),
                pyg.image.load(os.path.join("assets/Bird", "Bird2.png"))]

# 기타 (구름, 바닥) -> 하트 추가 예정
CLOUD = pyg.image.load(os.path.join("assets/Other", "Cloud.png"))
GROUND = pyg.image.load(os.path.join("assets/Other", "Track.png"))


global points
class Dinosaur():
    X_Dino = 80
    Y_Dino = 310
    Y_DinoStoop = 340
    Jump_height = 8.5
    hitScale = 0.5
    def __init__(self):
        self.stoop_img = STOOPING_MOTIONS
        self.run_img = RUNNING_MOTIONS
        self.jump_img = JUMPING_MOTION
        self.dino_stoop = False
        self.dino_run = True
        self.dino_jump = False

        self.step_index = 0     # 움직임 인덱스
        self.jump_height = self.Jump_height
        self.image = self.run_img[0]    # 0, 1 인덱스 반복하여 애니메이션 구현
        self.dino_hitbox = self.image.get_rect()    # 공룡 히트박스 설정
        self.dino_hitbox.x = self.X_Dino * self.hitScale
        self.dino_hitbox.y = self.Y_Dino * self.hitScale

    def update(self, Input):
        if self.dino_stoop:
            self.stoop()
        if self.dino_run:
            self.run()
        if self.dino_jump:
            self.jump()

        if self.step_index >= 10:
            self.step_index = 0
        # 공룡 동작

        # 점프
        if Input[pyg.K_UP] and not self.dino_jump:
            self.dino_stoop = False
            self.dino_run = False
            self.dino_jump = True
        # 숙이기
        elif Input[pyg.K_DOWN] and not self.dino_jump:
            self.dino_stoop = True
            self.dino_run = False
            self.dino_jump = False
        # 달리기
        elif not (self.dino_jump or Input[pyg.K_DOWN]):
            self.dino_stoop = False
            self.dino_run = True
            self.dino_jump = False

    def stoop(self):
        self.image = self.stoop_img[self.step_index // 5]
        self.dino_hitbox = self.image.get_rect()
        self.dino_hitbox.x = self.X_Dino
        self.dino_hitbox.y = self.Y_DinoStoop
        self.step_index += 1

    def run(self):
        self.image = self.run_img[self.step_index // 5]  # 5로 해야 속도 맞음
        self.dino_hitbox = self.image.get_rect()
        self.dino_hitbox.x = self.X_Dino
        self.dino_hitbox.y = self.Y_Dino
        self.step_index += 1

    def jump(self):
        self.image = self.jump_img
        if self.dino_jump:
            self.dino_hitbox.y -= self.jump_height * 4
            self.jump_height -= 0.8
        if self.jump_height < - self.Jump_height:
            self.dino_jump = False
            self.jump_height = self.Jump_height

    def draw(self, SCREEN):
        SCREEN.blit(self.image, (self.dino_hitbox.x, self.dino_hitbox.y))

class Cloud():
    def __init__(self):
        self.x = SCREEN_WIDTH + random.randint(800, 1000)
        self.y = random.randint(50, 100)
        self.image = CLOUD
        self.width = self.image.get_width()

    def update(self):
        self.x -= game_speed
        if self.x < - self.width:
            self.x = SCREEN_WIDTH + random.randint(2600, 3000)
            self.y = random.randint(50, 100)

    def draw(self, SCREEN):
        SCREEN.blit(self.image, (self.x, self.y))

class Obstacle():
    def __init__(self, image, type):
        self.image = image
        self.type = type
        self.rect = self.image[self.type].get_rect()
        self.rect.x = SCREEN_WIDTH

    def update(self):
        self.rect.x -= game_speed
        if self.rect.x < - self.rect.width:
            obstacles.pop()

    def draw(self, SCREEN):
        SCREEN.blit(self.image[self.type], self.rect)

class SmallCactus(Obstacle):
    def __init__(self, image):
        self.type = random.randint(0, 2)
        super().__init__(image, self.type)
        self.rect.y = 325

class LargeCactus(Obstacle):
    def __init__(self, image):
        self.type = random.randint(0, 2)
        super().__init__(image, self.type)
        self.rect.y = 300

class Bird(Obstacle):
    def __init__(self, image):
        self.type = 0
        super().__init__(image, self.type)
        self.rect.y = 250
        self.index = 0

    def draw(self, SCREEN):
        if self.index >= 9:
            self.index = 0
        SCREEN.blit(self.image[self.index // 5], self.rect)
        self.index += 1


def main():
    global game_speed, x_ground, y_ground, points, obstacles
    run = True
    clock = pyg.time.Clock()
    cloud = Cloud()
    player = Dinosaur()
    game_speed = 14
    x_ground = 0
    y_ground = 380
    points = 0
    font = pyg.font.Font('freesansbold.ttf', 20)
    obstacles = []
    death_cnt = 0
    def score():
        global points, game_speed
        points += 1
        if points % 100 == 0:
            game_speed += 1

        text = font.render("points: " + str(points), True, (0,0,0))
        text_rect = text.get_rect()
        text_rect.center = (1000, 40)
        SCREEN.blit(text, text_rect)

    def ground():
        global x_ground, y_ground
        image_width = GROUND.get_width()
        SCREEN.blit(GROUND, (x_ground, y_ground))
        SCREEN.blit(GROUND, (image_width + x_ground, y_ground))
        if x_ground <= - image_width:
            SCREEN.blit(GROUND, (image_width + x_ground, y_ground))
            x_ground = 0
        x_ground -= game_speed

    while run:
        for pyEvent in pyg.event.get():
            if pyEvent.type == pyg.QUIT:
                sys.exit()
        SCREEN.fill((255,255,255))
        userInput = pyg.key.get_pressed()
        player.draw(SCREEN)
        player.update(userInput)

        if len(obstacles) == 0:
            if random.randint(0, 2) == 0:
                obstacles.append(SmallCactus(SMALL_CACTUS_IMG))
            elif random.randint(0, 2) == 1:
                obstacles.append(LargeCactus(LARGE_CACTUS_IMG))
            elif random.randint(0, 2) == 2:
                obstacles.append(Bird(BIRD_MOTIONS))

        for ob in obstacles:
            ob.draw(SCREEN)
            ob.update()
            if player.dino_hitbox.colliderect(ob.rect):
                pyg.time.delay(500)
                death_cnt += 1
                menu(death_cnt)

        ground()
        cloud.draw(SCREEN)
        cloud.update()
        score()
        clock.tick(30)
        pyg.display.update()

def menu(death_cnt):
    global points
    run = True
    if death_cnt == 0:
        points = 0
    while run:
        update(points)
        SCREEN.fill((255,255,255))
        font = pyg.font.Font('freesansbold.ttf', 30)    # 폰트 적용 오류......
        if death_cnt == 0:
            text = font.render("Press any key to Start", True, (0,0,0)) # 한글 "시작하기" 로 변경 예정
            text1 = font.render("DinoSaurGame", True, (0,0,0))  # "공룡게임"으로 변경 예정
        elif death_cnt > 0:
            text = font.render("Press any key to Restart", True, (0,0,0))
            score = font.render("Your Score : " + str(points), True, (0,0,0))
            scoreRect = score.get_rect()
            scoreRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50)
            SCREEN.blit(score, scoreRect)
        textRect = text.get_rect()
        textRect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
        SCREEN.blit(text, textRect)
        SCREEN.blit(RUNNING_MOTIONS[0], (SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT // 2 - 140))
        pyg.display.update()
        for pyEvent in pyg.event.get():
            if pyEvent.type == pyg.QUIT:
                sys.exit()
            if pyEvent.type == pyg.KEYDOWN:
                main()

def update(score):
    pass


def game_start(nick):
    pyg.init()
    global SCREEN
    global nickname

    nickname = nick
    SCREEN = pyg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

    menu(death_cnt=0)

When I quit the pygame window, pyqt5 quits too. How can I only quit the pygame window?

Asked By: back2gas

||

Answers:

Do not mix frameworks, mixing frameworks always means some kind of undefined behavior. The frameworks may interact poorly or completely conflict with one another. Getting it to work on your system doesn’t mean it will work on another system or with a different version of any of the frameworks.
If you use Qt, then I suggest to develop the game with Qt as well (see Qt Based Games).

Answered By: Rabbid76
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.