微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

识别在 QFileDialog

如何解决识别在 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 运行正常),我只是当焦点在对话框上时按“返回”键,会发生之前的(标准)行为,即我与“选择”按钮的 click 信号断开连接的行为(插槽)。这会导致出现一个消息框,说“目录不存在”。但重点是我的新插槽想要创建用户输入的新目录。

我推测这是因为“选择”按钮是对话框的“认”按钮,而且事情已经连接起来,所以这个“按下回车键”信号连接到标准插槽作为通常由“选择”按钮使用。

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

解决方法

当行编辑具有焦点并按回车/回车键时,将出现该消息框。行编辑的 returnPressed 信号连接到 QFileDialog.accept 槽。结果行为将取决于 FileMode。对于 Directory 模式,这相当于请求打开指定目录,如果该目录不存在,显然会失败。

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

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

当行编辑没有焦点时,按回车/回车将激活默认按钮(除非当前焦点小部件具有自己的内置行为:例如导航到树视图中的选定目录)。由于您已将自己的插槽连接到此按钮的 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 上测试过这个;不能保证在其他平台上的行为会相同)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。