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 filesinitgui .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.
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()
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
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()
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))
-
Hi and welcome to devnet,
Looks like you are trying to implement QStackedWidget.
-
@greenelephant isn't the goal of your WindowManager class to switch between widgets ? That's exactly what QStackedWidget does, you put all the widgets you want in it and then set the one you want to see.
Basically, you should have one main widget that manages that and your other widgets should just use a signal that the manager should handle to change to another widget. They should know nothing about the manager itself, it's not their role.