Python Forum
[PyQt] I get a name Name Error: when calling a method inside a class
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] I get a name Name Error: when calling a method inside a class
#1
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:

Error:
Traceback (most recent call last): File "C:/Users/hp/PycharmProjects/PythonLearning/Test_UI_two_buttons.py", line 78, in <module> input_list = UiMainWindow().button_clicked() File "C:/Users/hp/PycharmProjects/PythonLearning/Test_UI_two_buttons.py", line 16, in __init__ self.main_window = main_window NameError: name 'main_window' is not defined
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/5690...on-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!
Reply
#2
I see a few problems

class UiMainWindow(object):
    def __init__(self):
        self.clicked_button = []
        self.main_window = main_window
This 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 below

class UiMainWindow(object):
    def __init__(self, main_window):
        self.clicked_button = []
        self.main_window = main_window
once 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
Error:
QWidget: Must construct a QApplication before a QWidget
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
Reply
#3
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!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Kivy] Acces atributes from a button defined in a class inside the .kv Tomli 2 2,052 Jun-10-2021, 01:05 AM
Last Post: Tomli
  [Tkinter] Redirecting all print statements from all functions inside a class to Tkinter Anan 1 2,599 Apr-24-2021, 08:57 AM
Last Post: ndc85430
  [Tkinter] Creation of Buttons with Shared Command Inside Class MulliganAgain 1 1,683 Jul-08-2020, 06:22 PM
Last Post: Yoriz
  [Tkinter] Issue with calling a Class/Method in GUI File Fre3k 3 2,946 Mar-08-2020, 12:35 PM
Last Post: Fre3k
  [Kivy] How do I reference a method in another class? Exsul1 3 4,219 Mar-02-2020, 07:32 PM
Last Post: Exsul1
  [Tkinter] Call a class method from another (Tk GUI) class? Marbelous 3 6,134 Jan-15-2020, 06:55 PM
Last Post: Marbelous
  [Tkinter] Class with text widget method AeranicusCascadia 3 7,738 Nov-14-2017, 11:33 PM
Last Post: AeranicusCascadia
  How to define a method in a class 1885 2 4,617 Oct-29-2017, 02:00 AM
Last Post: wavic
  [PyQt] How to put class method into new module? California 0 2,883 Jan-18-2017, 04:05 PM
Last Post: California

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020