识别在 QFileDialog 中按下 return 键时发出的信号

Identify signal emitted when return key is pressed in a QFileDialog

我正在为 QFileDialog 实现一些自定义行为。

reference_dir = r'D:\My Documents\month' 
create_dir_dialog.setDirectory(reference_dir)
create_dir_dialog.setFileMode(create_dir_dialog.Directory)
options = create_dir_dialog.Options(create_dir_dialog.DontUseNativeDialog | create_dir_dialog.ShowDirsOnly)
create_dir_dialog.setOptions(options)
# identify "Choose" button
choose_button = create_dir_dialog.findChild(QtWidgets.QDialogButtonBox).button(
    QtWidgets.QDialogButtonBox.Open)
# disconnect "clicked" signal from this button
choose_button.disconnect()
def check_line_edit(path):
    # this slot handles enablement of the "Choose" button: if the text 
    # corresponds to an already-existing directory the button is disabled.
    # This is because we are trying to create a new directory.
    ...

# get the line edit used for the path
lineEdit = create_dir_dialog.findChild(QtWidgets.QLineEdit)
lineEdit.textChanged.connect(check_line_edit)
def create_dir_and_proj():
    # this function creates a directory based on the text in the QLE
    new_dir = lineEdit.text()
    ...
    create_dir_dialog.close() # programmatically close the dialog
# use the above method as the slot for the clicked signal    
choose_button.clicked.connect(create_dir_and_proj)

dlg_result = create_dir_dialog.exec_()
# thread gets held up here

令我高兴的是,这一切正常。

只有一个美中不足:如果不是用鼠标单击“选择”或使用助记符 Alt-C 来引起单击(两者都会导致 create_dir_and_proj 到 运行 好的),当焦点在对话框上时,我只需按“Return”键,就会发生先前的(标准)行为,即我与“选择”按钮的 click 断开连接的行为(插槽)信号。这会导致出现一个消息框,提示“目录不存在”。但关键是我的新插槽想要创建用户输入的新目录。

我推测这是因为“选择”按钮是对话框的“默认”按钮,并且已经连接了一些东西,所以这个“Return-key-pressed”信号被连接了最多为“选择”按钮通常使用的标准插槽。

如何获取此信号以断开它并连接一个新插槽(即上述 create_dir_and_proj 函数)?

当行编辑获得焦点并且您按下 return/enter 时,该消息框将出现。 line-edit 的 returnPressed 信号连接到 QFileDialog.accept 插槽。由此产生的行为将取决于 FileMode。对于Directory模式,这相当于请求打开指定目录,如果不存在显然会失败。

要覆盖此行为,您只需连接自己的插槽即可:

lineEdit.returnPressed.disconnect()
lineEdit.returnPressed.connect(create_dir_and_proj)

当行编辑没有焦点时,按 return/enter 将激活默认按钮(除非当前焦点小部件有其自身的内置行为:例如导航到选定的目录树视图)。由于您已将自己的插槽连接到此按钮的 clicked 信号,因此默认情况下将调用您的插槽。

更新:

似乎连接到形成对话框闭包的 Python 插槽可能会影响删除对象的顺序。这有时可能会导致行编辑完成器弹出窗口在对话框关闭后没有父窗口,这意味着它不会被删除并且可能在屏幕上保持可见。一些可能的解决方法是显式关闭插槽内的弹出窗口:

def create_dir_and_proj():
    lineEdit.completer().popup().hide()
    dialog.close()

或者在关闭之前断开连接到插槽的所有信号:

def create_dir_and_proj():
    choose_button.clicked.disconnect()
    lineEdit.returnPressed.disconnect()
    dialog.close()

(注意:我只在 Linux 上测试过;不能保证在其他平台上的行为会相同)。