[PyQt] I get a name Name Error: when calling a method inside a class - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: [PyQt] I get a name Name Error: when calling a method inside a class (/thread-27576.html) |
I get a name Name Error: when calling a method inside a class - radoo - Jun-11-2020 Hello, I have a problem that I cannot resolve by myself. I am learning Python and Qt and I am trying to get the values of the buttons I push in the interface into a list, but I get a name Error message when reading the output of the method outside of the class. Here is the code: # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'C:\Users\hp\Desktop\PythonLearning\PyQt\Hang\Test_UI_two_buttons.ui' # # Created by: PyQt5 UI code generator 5.14.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class UiMainWindow(object): def __init__(self): self.clicked_button = [] self.main_window = main_window self.centralwidget = QtWidgets.QWidget(main_window) self.A_Button = QtWidgets.QPushButton(self.centralwidget) self.B_Button = QtWidgets.QPushButton(self.centralwidget) self.menubar = QtWidgets.QMenuBar(main_window) self.statusbar = QtWidgets.QStatusBar(main_window) def setupUi(self, _main__window_): _main__window_.setObjectName("MainWindow") _main__window_.setEnabled(True) _main__window_.resize(863, 600) font = QtGui.QFont() font.setFamily("MS Sans Serif") _main__window_.setFont(font) _main__window_.setWindowOpacity(1) self.centralwidget.setObjectName("centralwidget") self.A_Button.setGeometry(QtCore.QRect(143, 210, 251, 111)) font = QtGui.QFont() font.setFamily("Modern") font.setPointSize(10) font.setBold(True) font.setItalic(True) font.setWeight(75) self.A_Button.setFont(font) self.A_Button.setAutoFillBackground(False) self.A_Button.setCheckable(False) self.A_Button.setObjectName("A_Button") self.B_Button.setGeometry(QtCore.QRect(400, 210, 251, 111)) font = QtGui.QFont() font.setFamily("Modern") font.setPointSize(10) font.setBold(True) font.setItalic(True) font.setWeight(75) self.B_Button.setFont(font) self.B_Button.setObjectName("B_Button") _main__window_.setCentralWidget(self.centralwidget) self.menubar.setGeometry(QtCore.QRect(0, 0, 863, 21)) self.menubar.setObjectName("menubar") _main__window_.setMenuBar(self.menubar) self.statusbar.setObjectName("statusbar") _main__window_.setStatusBar(self.statusbar) self.retranslateUi(_main__window_) QtCore.QMetaObject.connectSlotsByName(_main__window_) def retranslateUi(self, main_window_): _translate = QtCore.QCoreApplication.translate main_window_.setWindowTitle(_translate("MainWindow", "MainWindow")) self.A_Button.setText(_translate("MainWindow", "A")) self.A_Button.setShortcut(_translate("MainWindow", "A")) self.B_Button.setText(_translate("MainWindow", "B")) self.B_Button.setShortcut(_translate("MainWindow", "B")) self.A_Button.clicked.connect(self.button_clicked) self.B_Button.clicked.connect(self.button_clicked) def button_clicked(self): button_ = main_window.sender().text() self.clicked_button.append(button_) return self.clicked_button input_list = UiMainWindow().button_clicked() print(input_list) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main_window = QtWidgets.QMainWindow() ui = UiMainWindow() ui.setupUi(main_window) main_window.show() sys.exit(app.exec_()) Error message: If I replace the button_clicked method with the following, and remove the method call outside (line 78-79, the code works as expected, but it is inside the class and I want the value returned outside. Here is the code:def button_clicked(self): button_ = self.main_window.sender().text() self.clicked_button.append(button_) print(self.clicked_button) I was pointed out to this thread https://stackoverflow.com/questions/5690888/variable-scopes-in-python-classes What I learned from it, is the different types of variable assignment inside a class and I understand that somewhere I did a mistake, but I can't spot it by myself. I'm trying to solve this seemingly trivial problem since hours and I'm confused. Here is an example I wrote, that works: class Exercises(): def __init__(self): self.string_variable = "" def example_method(self): self.string_variable = input("Whatever") return self.string_variable output = Exercises().example_method() print(output) I simply don't get why the last code works and the first does not. Help much appreciated! RE: I get a name Name Error: when calling a method inside a class - Yoriz - Jun-11-2020 I see a few problems class UiMainWindow(object): def __init__(self): self.clicked_button = [] self.main_window = main_windowThis is where error you posted is NameError: name 'main_window' is not defined main_window has not been defined, I think that you mean for main_window to be an attribute passed to the _init__ as shown belowclass UiMainWindow(object): def __init__(self, main_window): self.clicked_button = [] self.main_window = main_windowonce changing that in the following if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main_window = QtWidgets.QMainWindow() ui = UiMainWindow() ui.setupUi(main_window) main_window.show() sys.exit(app.exec_()) ui = UiMainWindow() would need to be passing main_window as ui = UiMainWindow(main_window) In the method def button_clicked(self): button_ = main_window.sender().text() self.clicked_button.append(button_) return self.clicked_button button_ = main_window.sender().text() is missing self before main_window Your code outside input_list = UiMainWindow().button_clicked() print(input_list)would need to pass in a main_window and would not work because This would also not be the same instance of the window created in the if __name__ == "__main__": and at the time you called it there would be no button clicks An event handler is not meant to return anything, the button click is what calls the method def button_clicked(self): so there is nowhere to return to.I think what you are trying is when a button is clicked use some code outside of the class/instance you can make a function def on_button_clicked(input_list): print(input_list)and call it at the end of the button click handler def button_clicked(self): button_ = self.main_window.sender().text() self.clicked_button.append(button_) on_button_clicked(self.clicked_button) Here is the full code with the above changes made # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'C:\Users\hp\Desktop\PythonLearning\PyQt\Hang\Test_UI_two_buttons.ui' # # Created by: PyQt5 UI code generator 5.14.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class UiMainWindow(object): def __init__(self, main_window): self.clicked_button = [] self.main_window = main_window self.centralwidget = QtWidgets.QWidget(main_window) self.A_Button = QtWidgets.QPushButton(self.centralwidget) self.B_Button = QtWidgets.QPushButton(self.centralwidget) self.menubar = QtWidgets.QMenuBar(main_window) self.statusbar = QtWidgets.QStatusBar(main_window) def setupUi(self, _main__window_): _main__window_.setObjectName("MainWindow") _main__window_.setEnabled(True) _main__window_.resize(863, 600) font = QtGui.QFont() font.setFamily("MS Sans Serif") _main__window_.setFont(font) _main__window_.setWindowOpacity(1) self.centralwidget.setObjectName("centralwidget") self.A_Button.setGeometry(QtCore.QRect(143, 210, 251, 111)) font = QtGui.QFont() font.setFamily("Modern") font.setPointSize(10) font.setBold(True) font.setItalic(True) font.setWeight(75) self.A_Button.setFont(font) self.A_Button.setAutoFillBackground(False) self.A_Button.setCheckable(False) self.A_Button.setObjectName("A_Button") self.B_Button.setGeometry(QtCore.QRect(400, 210, 251, 111)) font = QtGui.QFont() font.setFamily("Modern") font.setPointSize(10) font.setBold(True) font.setItalic(True) font.setWeight(75) self.B_Button.setFont(font) self.B_Button.setObjectName("B_Button") _main__window_.setCentralWidget(self.centralwidget) self.menubar.setGeometry(QtCore.QRect(0, 0, 863, 21)) self.menubar.setObjectName("menubar") _main__window_.setMenuBar(self.menubar) self.statusbar.setObjectName("statusbar") _main__window_.setStatusBar(self.statusbar) self.retranslateUi(_main__window_) QtCore.QMetaObject.connectSlotsByName(_main__window_) def retranslateUi(self, main_window_): _translate = QtCore.QCoreApplication.translate main_window_.setWindowTitle(_translate("MainWindow", "MainWindow")) self.A_Button.setText(_translate("MainWindow", "A")) self.A_Button.setShortcut(_translate("MainWindow", "A")) self.B_Button.setText(_translate("MainWindow", "B")) self.B_Button.setShortcut(_translate("MainWindow", "B")) self.A_Button.clicked.connect(self.button_clicked) self.B_Button.clicked.connect(self.button_clicked) def button_clicked(self): button_ = self.main_window.sender().text() self.clicked_button.append(button_) on_button_clicked(self.clicked_button) def on_button_clicked(input_list): print(input_list) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) main_window = QtWidgets.QMainWindow() ui = UiMainWindow(main_window) ui.setupUi(main_window) main_window.show() sys.exit(app.exec_())Hopefully, I'm somewhere on track with what you are looking for RE: I get a name Name Error: when calling a method inside a class - radoo - Jun-11-2020 Oh wow Yoriz, thank you! Yes, that is precisely what I was trying to do! I didn't understand everything you explained (yet) - I am very a couple of days new to programming- but I will dig into it! Great! |