Issue with GUI screen switching in Python QT5 code

I have exhausted all the possible remedies ChatGPT could offer me in resolving my issue.
Basically I cant use a GUI command button on 2 seperate GUI screens to alternate between hiding one screen and showing the other (and vice-versa) without the python console complaining about ‘circular imports’. So ChatGPT came up with a solution to create a python file that will mediate between GUI screen transmission. As stated i Have four files

  • initgui .py - This is the main python file to launch the program
  • junction.py - This is the mediator file between the two bottom python files
  • intro.py - This is the file for the first GUI screen. The python QT5 code to dictate the GUI criteria is outsourced to a file named introgui.py. The screen has a button to load the GUI screen for rftrans.py and a program terminate button
  • rftrans.py this is the other screen. I wont bog you down with the content of it. Too laborious, but it too outsources it python QT5 code from rftransgui.py

Heres the issue

I can switch screens from intro to rftrans.py but for some reason I cant transit from rftrans.py to intro.py GUI screen depite no errors being outputted on python console. I am using pycharm on ubuntu 22.04. I have python3 installed via ubuntu terminal. I shall attach the 4 files. Hopefully someone may have the answer.

initgui.py

import sys
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QFileDialog, QMessageBox, QLineEdit
from PyQt5.QtGui import QColor
from PyQt5.QtCore import QTimer, Qt,  QDir  # Import QTimer
from junction import WindowManager
from intro import IntroWindow
from rftrans import RFTransWindow

def main():
    app = QApplication(sys.argv)
    window_manager = WindowManager()

    intro_window = IntroWindow()
    intro_window.window_manager = window_manager
    window_manager.GUIJunction(intro_window)

    rftrans_window = RFTransWindow()
    rftrans_window.hide()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

junction.py

import sys
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QFileDialog, QMessageBox, QLineEdit
from PyQt5.QtGui import QColor
from PyQt5.QtCore import QTimer, Qt,  QDir  # Import QTimer

class WindowManager:
    def __init__(self):
        self.current_window = None

    def GUIJunction(self, new_window):
        """Switch to a new window."""
        if self.current_window:
            self.current_window.close()  # Close the current window
        new_window.show()  # Show the new window
        self.current_window = new_window  # Update the current window reference

intro.py

import sys
import os
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QFileDialog, QMessageBox, QLineEdit
from PyQt5.QtGui import QColor
from PyQt5.QtCore import QTimer, Qt,  QDir  # Import QTimer
from introgui import Ui_MainWindow
from rftrans import RFTransWindow
from junction import WindowManager

class IntroWindow(QMainWindow):
    def __init__(self):
        super(IntroWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Assign functionality to GUI objects
        self.ui.cmdRFRecep.clicked.connect(self.RFReception)
        self.ui.cmdRFTrans.clicked.connect(self.RFTransmission)
        self.ui.cmdRSAKeyGen.clicked.connect(self.RSAKeyGeneration)
        self.ui.cmdFileEn.clicked.connect(self.FileEncryption)
        self.ui.cmdExit.clicked.connect(self.exitApplication)

    def RFReception(self):
        self.close()
    def RFTransmission(self):
        self.rftrans_window = RFTransWindow()
        self.rftrans_window.show()
        self.close()
    def RSAKeyGeneration(self):
        self.close()
    def FileEncryption(self):
        self.close()
    def exitApplication(self):
        # Code to exit the application goes here
        print("Exiting application...")
        sys.exit()

rftrans.py

import sys
import os
import time
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import bluetooth  # Import the bluetooth module
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QFileDialog, QMessageBox, QLineEdit
from PyQt5.QtGui import QColor
from PyQt5.QtCore import QTimer, Qt,  QDir  # Import QTimer
from rftransgui import GUIRFTransWindow
from junction import WindowManager

class RFTransWindow(QMainWindow):
    def __init__(self, intro_window=None, window_manager=None):
        super().__init__()
        self.ui = GUIRFTransWindow()
        self.ui.setupUi(self)
        self.intro_window = intro_window
        self.window_manager = window_manager

        # Assign functionality to GUI objects
        self.ui.cmdScanBlue.clicked.connect(self.scanBluetoothDevices)
        self.ui.cmdConnectBlue.clicked.connect(self.connectToDevice)
        self.ui.cmdStartTrans.clicked.connect(self.startTransmission)
        self.ui.cmdStopTrans.clicked.connect(self.stopTransmission)
        self.ui.cmdExit.clicked.connect(self.exitApplication)
        self.ui.cboSBlueAddr.setHidden(True)
        self.ui.cmdSlctIFile.clicked.connect(self.openFile)
        self.ui.cmdSlctPubKey.clicked.connect(self.openRSAFile)
        self.ui.sldrFreq.valueChanged.connect(self.updateFrequencyLabel)
        self.ui.chkRSATrans.stateChanged.connect(self.toggleRSATransmission)  # Connect checkbox to method
        self.ui.chkShowRSA.clicked.connect(self.toggleRSAEchoMode)
        self.ui.chkSwIFile.clicked.connect(self.toggleIFileEchoMode)
        self.ui.cmdClrIFile.clicked.connect(self.ClearInput)
        self.ui.cmdClrRSA.clicked.connect(self.ClearRSA)
        # Add more connections as needed

    def TSawtooth(self):
        #if self.ui.chkSwIFile.isChecked():
        if self.ui.chkSawtooth.isChecked():
            self.ui.chkSine.setChecked(False)
            self.ui.chkSquare.setChecked(False)
            self.ui.chkTriangle.setChecked(False)

    def TSine(self):
        if self.ui.chkSine.isChecked():
            self.ui.chkSawtooth.setChecked(False)
            self.ui.chkSquare.setChecked(False)
            self.ui.chkTriangle.setChecked(False)
    def TSquare(self):
        if self.ui.chkSquare.isChecked():
            self.ui.chkSawtooth.setChecked(False)
            self.ui.chkSine.setChecked(False)
            self.ui.chkTriangle.setChecked(False)
    def TTriangle(self):
        if self.ui.chkTriangle.isChecked():
            self.ui.chkSawtooth.setChecked(False)
            self.ui.chkSine.setChecked(False)
            self.ui.chkSquare.setChecked(False)
    def ClearInput(self):
        self.ui.txtSlctIFile.clear()
    def ClearRSA(self):
        self.ui.txtSlctPubKey.clear()
    def toggleRSAEchoMode(self):
        # Toggle echo mode of txtSlctPubKey based on chkShowRSA checkbox state
        if self.ui.chkShowRSA.isChecked():
            self.ui.txtSlctPubKey.setEchoMode(QtWidgets.QLineEdit.Normal)
        else:
            self.ui.txtSlctPubKey.setEchoMode(QtWidgets.QLineEdit.Password)

    def toggleIFileEchoMode(self):
        # Toggle echo mode of txtSlctPubKey based on chkShowRSA checkbox state
        if self.ui.chkSwIFile.isChecked():
            self.ui.txtSlctIFile.setEchoMode(QtWidgets.QLineEdit.Normal)
        else:
            self.ui.txtSlctIFile.setEchoMode(QtWidgets.QLineEdit.Password)


    def toggleRSATransmission(self, state):
        # Method to enable/disable RSA transmission based on checkbox state
        if state == Qt.Checked:  # Use Qt.Checked directly without QtCore prefix
            self.ui.chkShowRSA.setVisible(True)
            self.ui.txtSlctPubKey.setVisible(True)
            self.ui.cmdSlctPubKey.setVisible(True)
            self.ui.cmdClrRSA.setVisible(True)
        else:
            self.ui.chkShowRSA.setVisible(False)
            self.ui.txtSlctPubKey.setVisible(False)
            self.ui.cmdSlctPubKey.setVisible(False)
            self.ui.cmdClrRSA.setVisible(False)
    def openFile(self):
        # Open file dialog
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(self, "Select Input File", QDir.homePath(),
                                                  "All Files (*);;Text Files (*.txt)", options=options)

        if fileName:
            # Set selected file path in txtSlctIFile text box
            self.ui.txtSlctIFile.setText(fileName)
            self.input_file = fileName

    def openRSAFile(self):
        # Open file dialog
        options = QFileDialog.Options()
        RSAfileName, _ = QFileDialog.getOpenFileName(self, "Select Input File", QDir.homePath(),
                                                  "All Files (*);;Text Files (*.txt)", options=options)

        if RSAfileName:
            # Set selected file path in txtSlctIFile text box
            self.ui.txtSlctPubKey.setText(RSAfileName)
            #self.input_file = RSAfileName

    def scanBluetoothDevices(self):
        # Change lblBStatus text and background color
        self.ui.lblBStatus.setText("Scanning for nearby devices...")
        self.ui.lblBStatus.setStyleSheet("background-color: rgb(255, 0, 0);")
        self.ui.cboListBDev.clear()
        self.ui.cboSBlueAddr.clear()

        # Code to scan Bluetooth devices goes here
        nearby_devices = bluetooth.discover_devices(lookup_names=True)
        print("SCANNING!!!!...")
        for addr, name in nearby_devices:
            # Add each device name to the combo box
            self.ui.cboListBDev.addItem(name)
            # Store the device address in a variable
            self.ui.cboSBlueAddr.addItem(addr)
        self.ui.lblBStatus.setText("Bluetooth Status")
        self.ui.lblBStatus.setStyleSheet("background-color: rgb(143, 240, 164);")  # Reset style to default
        print("STOP SCANNING!!!!...")

    def connectToDevice(self):
        # Get the selected item text from cboListBDev
        selected_device = self.ui.cboListBDev.currentText()

        # Get the index of the selected item in cboListBDev
        selected_index = self.ui.cboListBDev.currentIndex()

        # Use the selected index to retrieve the corresponding Bluetooth address from cboSBlueAddr
        if selected_index != -1:  # Ensure an item is selected
            device_address = self.ui.cboSBlueAddr.itemText(selected_index)

        # Try to connect/pair with the selected Bluetooth device
        try:
            # Code to connect/pair with the Bluetooth device using its address
            # Example: bluetooth.connect(device_address)
            print(f"Connecting to Bluetooth device: {device_address}")
        except Exception as e:
            # Display error message if connection/pairing fails
            QMessageBox.warning(self, "Connection Error", f"Failed to connect to the selected device: {e}")

    def updateFrequencyLabel(self, value):
        # Update the label text with the current value of the slider
        self.ui.lblDFreq.setText(str(value) + " (KHz)")

    def startTransmission(self):

        input_file_path = self.ui.txtSlctIFile.text()
        rsa_key_path = self.ui.txtSlctPubKey.text()

        if self.ui.chkRSATrans.isChecked():
            # Load RSA public key
            with open(rsa_key_path, 'rb') as key_file:
                rsa_key = RSA.import_key(key_file.read())

            # Create a cipher object for encryption
            cipher = PKCS1_OAEP.new(rsa_key)

            # Prepare output file path
            output_file_path = os.path.splitext(input_file_path)[0] + "_RSACONV"

            try:
                # Open input and output files
                with open(input_file_path, 'rb') as input_file, open(output_file_path, 'wb') as output_file:
                    # Read and encrypt file chunk by chunk
                    chunk_size = 85
                    while True:
                        chunk = input_file.read(chunk_size)
                        if not chunk:
                            break  # End of file
                        encrypted_chunk = cipher.encrypt(chunk)
                        output_file.write(encrypted_chunk)

                QMessageBox.information(self, "Success", "File encrypted successfully.")
            except Exception as e:
                QMessageBox.warning(self, "Encryption Error", f"Failed to encrypt file: {e}")

        else:
            if self.input_file:
                try:
                        self.transmitData(file)
                except Exception as e:
                    QMessageBox.warning(self, "Transmission Error", f"Failed to transmit data: {e}")
                else:
                    QMessageBox.warning(self, "File Error", "Please select an input file.")

    def transmitData(self, data):
        # Transmit data via Bluetooth
        # Replace this with your actual Bluetooth transmission code
        print(f"Transmitting data: {data}")

    def stopTransmission(self):
        # Code to stop transmission goes here
        print("Stopping transmission...")

    def exitApplication(self):
        # Code to exit the application goes here
        print("Exiting application...")
        if self.window_manager:
            self.window_manager.GUIJunction(IntroWindow(window_manager=self.window_manager))