user20084690
user20084690

Reputation:

How to open an load uic window as a second window

So @furas I did what you told me. But still it didn't work. The screen freezes when opening the second window. I let the app = ... stay in if main and only made a variable of the second window to call over in the main file. I am reposting some of my code as you suggested for review. Thanks!

In the main.py:

   #pyttsx3 takes command
   elif 'game' in query:
        games_window_open = show_window("games", True)  #Checks if the game window is already running using win32 and returns False if not
    # For the first time games_window_open is False
    if games_window_open == False:
        second_window = UI_Games()

    elif games_window_open:
        self.ai_dialogue_update.emit("A game window is already open")
        speak("A game window is already open")

and in the second file:

from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton
from PyQt5 import uic
from PyQt5.QtCore import QThread
import sys

# Ignore the small classes. They are games that can be run in a thread from the ui second window that is listed below
class Snake(QThread):
    def start_game(self):
        import Games.sanke_game


class Space(QThread):
    def space(self):
        import Games.space_invader


class Target(QThread):
    def target(self):
        import Games.target_practice

#Second window is the UI_Games
class UI_Games(QMainWindow):
    def __init__(self):
        super(UI_Games, self).__init__()

        # Load the ui file
        uic.loadUi("Resources\\UI_files\\game_window_UI.ui", self)

        # Define our widgets
        self.snakeGame = self.findChild(QPushButton, "snakeGame")
        self.targetGame = self.findChild(QPushButton, "targetGame")
        self.guessGame = self.findChild(QPushButton, "guessGame")
        self.spaceGame = self.findChild(QPushButton, "spaceGame")
        self.ticTacToeGame = self.findChild(QPushButton, "ticTacToeGame")

        self.snakeGame.clicked.connect(lambda: self.game_choose("snake"))
        self.targetGame.clicked.connect(lambda: self.game_choose("target"))
        self.guessGame.clicked.connect(lambda: self.game_choose("guess"))
        self.spaceGame.clicked.connect(lambda: self.game_choose("space"))
        self.ticTacToeGame.clicked.connect(lambda: self.game_choose("tic-tac-toe"))

        
        # Show the app
        self.show()

    #Function to start the games
    def game_choose(self, choice):
        if choice == "target":
            self.space_worker = Target()
            self.space_worker.target()
        
        elif choice == "snake":
            self.snake_worker = Snake()
            self.snake_worker.start_game()

        elif choice == "guess":
            pass

        elif choice == "tic-tac-toe":
            pass

        elif choice == "space":
            space_worker = Space()
            space_worker.space()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    UIWindow = UI_Games()
    app.exec_()

Here's an image of the freezed screen: enter image description here

Upvotes: -1

Views: 393

Answers (1)

furas
furas

Reputation: 143097

It is minimal working code - and it doesn't matter if it uses file .ui or not.

It needs only one QApplication and only one exec()

Button runs function on_click() which runs self.second = SecondWindow() and this shows second window.

main.py

from PyQt5 import QtCore, QtWidgets


class FirstWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi()
        self.show()

    def setupUi(self):
        self.setWindowTitle("First")
        
        self.pushButton = QtWidgets.QPushButton("Open Second Window", parent=self)
        self.pushButton.clicked.connect(self.on_click)
        
        self.setCentralWidget(self.pushButton)

    def on_click(self):
        self.second = SecondWindow()


class SecondWindow(QtWidgets.QMainWindow):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi()
        self.show()
        
    def setupUi(self):
        self.setWindowTitle("Second")
        
        self.pushButton = QtWidgets.QPushButton("Close Window", parent=self)
        self.pushButton.clicked.connect(self.on_click)
        
        self.setCentralWidget(self.pushButton)

    def on_click(self):
        self.close()


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    
    first = FirstWindow()
    
    app.exec()

You can put code in two separated file - but still you have to use only one QApplication and only one exec() (or second code has to use if __name__ == '__main__': to run QApplication and exec() only when it is directly executed but not when it is imported

main.py

from PyQt5 import QtCore, QtWidgets
from second import SecondWindow

class FirstWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi()
        self.show()

    def setupUi(self):
        self.setWindowTitle("First")
        
        self.pushButton = QtWidgets.QPushButton("Open Second Window", parent=self)
        self.pushButton.clicked.connect(self.on_click)
        
        self.setCentralWidget(self.pushButton)

    def on_click(self):
        self.second = SecondWindow()
        
if __name__ == "__main__":
    # it will skip this code when it will be imported to other script

    app = QtWidgets.QApplication([])
    
    first = FirstWindow()
    
    app.exec()

second.py

from PyQt5 import QtCore, QtWidgets

class SecondWindow(QtWidgets.QMainWindow):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi()
        self.show()
        
    def setupUi(self):
        self.setWindowTitle("Second")
        
        self.pushButton = QtWidgets.QPushButton("Close Window", parent=self)
        self.pushButton.clicked.connect(self.on_click)
        
        self.setCentralWidget(self.pushButton)

    def on_click(self):
        self.close()

if __name__ == "__main__":
    # it will skip this code when it will be imported to other script

    app = QtWidgets.QApplication([])
    
    second = SecondWindow()
    
    app.exec()

Upvotes: 2

Related Questions