Error "bool object has no attribute" python message

Question:

I have a getFile function which will get the address of the csv file and print the filename in the command console. When I run the function in the main window, I keep getting "’bool’ object has no attribute ‘filename’". Why is this happening?

ttreadfile.py

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

def getFile(self):
    """this function will get the address of the sdv file location"""
    self.filename = QFileDialog.getOpenFileName(filter = "csv (*.csv)")[0]
    print("File:",self.filename)

ttool.py

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from Module.ttreadfile import *

class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        """set layout of window"""
        self.main_widget = QWidget(self)

        l = QGridLayout(self.main_widget)
        open_button =QPushButton('Open')
        open_button.clicked.connect(getFile)

        l.addWidget(open_button, 0,0)

if __name__ == '__main__':
    app = QApplication(sys.argv)

    aw = ApplicationWindow()
    aw.setWindowTitle("PyQt5 Matplot Example")
    aw.show()
    #sys.exit(qApp.exec_())
    app.exec_()
Asked By: HoneyWeGOTissues

||

Answers:

The QPushButton widget inherits the clicked signal from QAbstractButton which is the parent class of QCheckBox as well. As such when the clicked signal is emitted it is sent with a default checked Boolean argument that indicates the button’s check state. For QPushButton this argument is always False and is often ignored or omitted in slots connected to the signal.

What is happening in your situation is that the self parameter of your getFile function is being filled with the value of the checked argument which is a boolean and therefore does not have a filename attribute.

Also since getFile is not a method of the ApplicationWindow class it doesn’t receive self as it’s default first argument like it would if you were calling self.getFile.

A work around is to simply assign the clicked signal to and intermediate method that can trigger the getFile function with the appropriate argument.

For example

class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        ...
        open_button.clicked.connect(self.get_file)

    def get_file(self):
        getFile(self)

Or as suggested in the comments you can simply use a lambda to trigger the function:

open_button.clicked.connect(lambda : getFile(self))

I also suggest changing the signature of your getFile function for the sake of clarity and readability.

For example:

def getFile(instance):
    """this function will get the address of the sdv file location"""
    instance.filename = QFileDialog.getOpenFileName(filter = "csv (*.csv)")[0]
    print("File:",instance.filename)
Answered By: Alexander