При запуске графического интерфейса автоматически срабатывает кнопка, если в метод, отвечающий за эту кнопку передается аргумент

В графическом интерфейсе есть кнопка "сохранить" для сохранения списка в файл .csv.
Если список объявлен в методе __init__ и при нажатии кнопки передается как аргумент в соответствующий метод, то при запуске программы эта кнопка как-будто нажимается автоматически, потому что сразу открывается диалоговое окно QFileDialog.

Код такого варианта ниже:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
import csv

class Ui_Error(object):
    def setupUi(self, Error):
        Error.setObjectName("Error")
        Error.resize(320, 240)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Error.sizePolicy().hasHeightForWidth())
        Error.setSizePolicy(sizePolicy)
        self.groupBox = QtWidgets.QGroupBox(Error)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 301, 181))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(10, 20, 281, 151))
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        self.label.setFont(font)
        self.label.setText("")
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Error)
        self.pushButton.setEnabled(True)
        self.pushButton.setGeometry(QtCore.QRect(125, 200, 71, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("background-color: rgb(200, 200, 200);\n"
"")
        self.pushButton.setCheckable(False)
        self.pushButton.setObjectName("pushButton")

        self.retranslateUi(Error)
        QtCore.QMetaObject.connectSlotsByName(Error)

    def retranslateUi(self, Error):
        _translate = QtCore.QCoreApplication.translate
        Error.setWindowTitle(_translate("Error", "Dialog"))
        self.groupBox.setTitle(_translate("Error", "Ошибка"))
        self.pushButton.setText(_translate("Error", "Сохранить"))


class UiErrorWindow(QtWidgets.QDialog, Ui_Error):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        list_for_export = [[1, 2, 3], [4, 5, 6]]
        self.pushButton.clicked.connect(self.export_file(list_for_export))

    def export_file(self, list_for_export):
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            'QFileDialog.getSaveFileName()',
            './',
            'Text (*.csv)'
        )
        with open(file_name, 'w') as f:
            writer = csv.writer(f)
            for row in list_for_export:
                writer.writerow(row)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    EW = UiErrorWindow()
    EW.show()
    sys.exit(app.exec_())

Если же я список объявляю в методе, который вызывается при нажатии кнопки (т.е. аргумент в этот метод не передается), то все работает как надо: программа запускается и при нажатии кнопки сохранить открывается диалоговое окно QFileDialog.

Измененный код следующий:

class UiErrorWindow(QtWidgets.QDialog, Ui_Error):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.export_file)

    def export_file(self):
        list_for_export = [[1, 2, 3], [4, 5, 6]]
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            'QFileDialog.getSaveFileName()',
            './',
            'Text (*.csv)'
        )
        with open(file_name, 'w') as f:
            writer = csv.writer(f)
            for row in list_for_export:
                writer.writerow(row)

Подскажите, пожалуйста, как сделать, чтобы программа работала корректно в первом случае, когда в метод передается список для сохранения.
Я полагаю, что кнопка срабатывает при инициализации, но как сделать правильно не смог понять.


Ответы (1 шт):

Автор решения: S. Nick

Как вариант. Мене так кажется, что вы должны список сделать атрибутом класса:

...
    self.list_for_export = [                                  # +++ self.
        [1, 2, 3], 
        [4, 5, 6]
    ]
...

и вам ничего не надо будет передавать в метод export_file().

...
    self.pushButton.clicked.connect(self.export_file) 

def export_file(self):
    ...

        for row in self.list_for_export: 
            ...

И надо вставить проверку:

    ...
    if not file_name:
        return   
    ...

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
import csv

class Ui_Error(object):
    def setupUi(self, Error):
        Error.setObjectName("Error")
        Error.resize(320, 240)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Error.sizePolicy().hasHeightForWidth())
        Error.setSizePolicy(sizePolicy)
        self.groupBox = QtWidgets.QGroupBox(Error)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 301, 181))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(10, 20, 281, 151))
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        self.label.setFont(font)
        self.label.setText("")
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Error)
        self.pushButton.setEnabled(True)
        self.pushButton.setGeometry(QtCore.QRect(125, 200, 85, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("background-color: rgb(200, 200, 200);\n"
"")
        self.pushButton.setCheckable(False)
        self.pushButton.setObjectName("pushButton")

        self.retranslateUi(Error)
        QtCore.QMetaObject.connectSlotsByName(Error)

    def retranslateUi(self, Error):
        _translate = QtCore.QCoreApplication.translate
        Error.setWindowTitle(_translate("Error", "Dialog"))
        self.groupBox.setTitle(_translate("Error", "Ошибка"))
        self.pushButton.setText(_translate("Error", "Сохранить"))


class UiErrorWindow(QtWidgets.QDialog, Ui_Error):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        
#        list_for_export = [[1, 2, 3], [4, 5, 6]]
        self.list_for_export = [                                  # +++ self.
            [1, 2, 3], 
            [4, 5, 6]
        ]
        
#        self.pushButton.clicked.connect(self.export_file(list_for_export))
        self.pushButton.clicked.connect(self.export_file)         # +++ 


    def export_file(self):                                        # +++
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            'QFileDialog.getSaveFileName()',
            './',
            'Text (*.csv)'
        )
        
        if not file_name:                                         # +++
            return                                                # +++
            
        with open(file_name, 'w') as f:
            writer = csv.writer(f)
            for row in self.list_for_export:                      # +++ self.
                writer.writerow(row)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    EW = UiErrorWindow()
    EW.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка