PyQt5跨类传递BankAccount对象数据及类顺序疑问咨询
Hey there! Let's break down your problems and fix them step by step—getting that BankAccount balance into the ViewBalance window, and clearing up how class definition order affects your code.
1. Passing the BankAccount Instance to ViewBalance
Right now, your x BankAccount instance is a local variable inside Window.btnclicked(), so no other class can access it. We'll fix this by making the account a shared instance and passing it to ViewBalance when we open that window. Also, there's a small bug in your BankAccount class we need to squash first.
Step 1: Fix the BankAccount Recursion Bug
Your balance() method has a recursive loop (it calls itself indefinitely). Let's rename it to avoid conflicting with the self.balance attribute:
class BankAccount(): def __init__(self, name, acct): self.full_name = name self.acctNum = acct self.balance = 0 def withdraw(self, w): w = float(w) # Convert first to avoid type errors self.balance -= w return self.balance def deposit(self, d): d = float(d) self.balance += d return self.balance def get_balance(self): # Renamed to prevent recursion return self.balance
Step 2: Update ViewBalance to Accept an Account Instance
Modify ViewBalance to take a BankAccount object when it's created, so it can display the balance directly:
class ViewBalance(QtWidgets.QWidget): def __init__(self, account, parent=None): super(ViewBalance, self).__init__(parent) self.account = account # Store the account reference self.button1 = QtWidgets.QPushButton("Close") self.label1 = QtWidgets.QLabel("Your balance is: ") # Format the balance as currency for better UX self.label2 = QtWidgets.QLabel(f"${self.account.get_balance():.2f}") vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.label1) vbox.addWidget(self.label2) vbox.addWidget(self.button1) self.setLayout(vbox) # Add close functionality to the button self.button1.clicked.connect(self.close)
Step 3: Share the Account Instance Between Windows
Update your Window class to store the account as an instance attribute, then pass it to the secondwindow. We'll also adjust the secondwindow to open ViewBalance with the account:
Updated Window Class:
class Window(QtWidgets.QWidget): def btnclicked(self): search_name = self.lineedit.text() # Use the lineedit input instead of sender text if search_name in namecheck: with open('C:/Users/rbell/PycharmProjects/SDEV140/Final_project/users.txt') as fhand: for line in fhand: if search_name in line: line = line.rstrip('\n') array = line.split(",") stringtofloat = float(array[2]) # Store account as an instance attribute (not local variable) self.account = BankAccount(array[0], array[1]) self.account.balance = stringtofloat print(self.account.full_name, self.account.acctNum, self.account.balance) # Pass the account to the second window when opening it self.secwin = secondwindow(self.account) self.secwin.show() break # Exit loop once we find the matching account else: print('\nError: Account not found\n') def __init__(self, parent=None): super(Window, self).__init__(parent) self.left = 440 self.top = 260 self.width = 640 self.height = 480 self.lineedit = QtWidgets.QLineEdit(""); self.button1 = QtWidgets.QPushButton("OK"); self.label1 = QtWidgets.QLabel("Welcome to Reese's Bank!\nEnter account number:") vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.label1) vbox.addWidget(self.lineedit) vbox.addWidget(self.button1) self.setLayout(vbox) self.setGeometry(self.top, self.left, self.width, self.height) self.setWindowTitle("first window") self.show() self.lineedit.editingFinished.connect(self.btnclicked)
Updated secondwindow Class:
class secondwindow(QtWidgets.QMainWindow): def __init__(self, account, parent=None): super(secondwindow, self).__init__(parent) self.account = account # Store the account reference # Add a "View Balance" button (adjust this to match your existing UI) self.view_balance_btn = QtWidgets.QPushButton("View Balance") self.setCentralWidget(self.view_balance_btn) self.view_balance_btn.clicked.connect(self.open_view_balance) def open_view_balance(self): # Open ViewBalance and pass the account instance self.balance_window = ViewBalance(self.account) self.balance_window.show()
Now when you open the ViewBalance window, it will receive the BankAccount instance and display the correct balance in label2.
2. Does Class Definition Order Matter?
Short answer: Only if you reference a class before it's defined in the class body (not in methods).
In Python:
- If you define a class that directly uses another class in its class-level code (like a class attribute), you need to define the referenced class first. For example:
# This will throw a NameError because ClassB isn't defined yet class ClassA: my_b = ClassB() class ClassB: pass - If you only reference other classes inside instance methods (like
__init__orbtnclicked), the order doesn't matter—as long as the class exists when the method is called.
Looking at your code, your class order (BankAccount → ViewBalance → DepositMoney → WithdrawMoney → secondwindow → Window) is totally fine. All class references happen inside methods that run after all classes are defined, so you won't hit any order-related errors.
内容的提问来源于stack exchange,提问作者Reese_E

