在 QFileDialog 弹出窗口中按下按钮退出应用程序

Pressing button in QFileDialog popup exits application

我完成了从 PyQt4PyQt5 的过渡。我的应用程序(使用 QtDesigner 创建)有一个复选框,可以启用 "Save" 按钮,以防您想要保存文件。在 PyQt4 对话框将打开,我将选择我的文件,按确定,完成。我对主应用程序的 OK 按钮进行了检查,如果路径无效,该按钮会提示错误,例如如果您在 QFileDialog.

中按下取消

如果我以任何方式关闭 QFileDialog PyQt5,我的应用程序将完全退出(确定,取消,X)。我只想关闭 QFileDialog 而不是我的主要 window。我该怎么做呢?感谢您的时间和帮助。

这是我的代码的相关部分:

self.path = self.ui.savepathButton.pressed.connect(lambda: self.file_save())

def file_save(self):
    path = QFileDialog.getSaveFileName(self, "Choose a path and filename", os.getcwd().replace("\", "/") +
                                       "/test.stl", filter="Stereolithography Files (*.stl)")
    self.ui.savepath_label.setText(path) <------ NO ERROR WITHOUT THIS LINE

def OKButton_click(self):
    if os.path.isdir(os.path.split(self.ui.savepath_label.text())[0]) is False:
        # Warning if the filename is invalid.
        file_error = QMessageBox()
        file_error.setIcon(QMessageBox.Warning)
        file_error.setText("Invalid path or filename.")
        file_error.setInformativeText("Please choose a working path and filename.")             file_error.setWindowTitle("File name error")
        file_error.setStandardButtons(QMessageBox.Ok)
        file_error.exec_()
    else:
        self.accept()

编辑:

我知道我的错误在哪里,但我仍然无法修复它。我在代码中标记了这一行。为什么 self.ui.savepath_label.setText(path) 终止我的申请?

我终于找到了(非常小的)错误:

虽然 PyQt4 显然会像 string 一样自动写入路径,但 PyQt5 不会。

我变了

self.ui.savepath_label.setText(path)

进入

self.ui.savepath_label.setText(str(path))

现在一切都很好。

PyQt4提供了两种不同的APIs:

  • API v1 使用对象的 Qt 类型,所以你必须将 QString 之类的东西传递给 setText 方法
  • API v2 改为使用 python 类型,Qt 对象的方法会自动将这些 python 类型转换为其 Qt 变体,因此您必须传递一个 python str给他们。

this page about PyQt4. PyQt5 only supports version 2 of the API中提到了这一点(该页面还提到了其他差异)。

另请注意,根据问题 pyqt5 - finding documentationPyQt5 方法 getSaveFileName 实际上 return 是一对 (filename, filter) 因此它实际上等同于 PyQt4 的 getSaveFileNameAndFilter 方法,这意味着您可以简单地使用:

self.ui.savepath_label.setText(path[0])

设置文字。最小的完整示例:

from PyQt5.QtWidgets import  QFileDialog, QWidget, QApplication, QHBoxLayout, QPushButton


class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__(None)
        layout = QHBoxLayout()
        self.button = QPushButton('click')
        layout.addWidget(self.button)
        self.setLayout(layout)
        self.button.clicked.connect(self.ask_filename)
    def ask_filename(self):
        fname = QFileDialog.getSaveFileName(self, 'title')
        print(fname)
        self.button.setText(fname[0])


app = QApplication([])
window = Window()
window.show()
app.exec_()

顺便说一句,如果您将 fname[0] 更改为 fname 并尝试从终端启动此应用程序,您会收到以下 有用的 错误消息:

Traceback (most recent call last):
  File "test_qt.py", line 15, in ask_filename
    self.button.setText(fname)
TypeError: QAbstractButton.setText(str): argument 1 has unexpected type 'tuple'

它告诉您 getSaveFileName 的 return 类型是元组而不是 str