为什么 PyQt5 显示我的第一个文件对话框而不是我的第二个?
Why is PyQt5 showing me my first file dialog but not my second one?
我正在尝试使用 PyQt5 为 python 项目制作基本的前端图形用户界面。具体来说,我想从两件事开始。首先,我想提示用户 select 输入数据文件。然后,我想提示用户select一个可以保存文件的目录。
可以在下面找到代码的工作示例。 我的问题是为什么代码中有两个提示给用户(首先是输入文件,然后是保存目录)时用户只收到一个提示。代码没有抛出一个错误;注释掉输入文件例程(Interface
的 __init__
方法中的 self.select_save_directory()
)将允许保存目录例程到 运行.
首先,所有进口。
import sys
from PyQt5 import QtWidgets # QtGui, QtCore
然后,提示用户 select 输入 .csv 文件的小部件。
class FileSelectionWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Click here and select the data file you want to read")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
self._fpath = None
@property
def fpath(self):
return self._fpath
def on_clicked(self):
dialog = QtWidgets.QFileDialog(
self,
"Select input file",
"path",
"*.csv",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog)
fpath = dialog.getOpenFileName(None, 'Open file', '/home')[0]
self._fpath = fpath
self.close()
print(self.fpath) # verify
然后,提示用户 select 保存目录的小部件。
class DirectorySelectionWidget(QtWidgets.QWidget):
"""
This class allows the user to select the directory
to save files into via gui.
"""
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Click here and select the directory \nin which you would like to save files")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
self._savedir = None
@property
def savedir(self):
return self._savedir
def on_clicked(self):
dialog = QtWidgets.QFileDialog()
savedir = dialog.getExistingDirectory(None, "Select directory")
self._savedir = savedir
self.close()
print(self.savedir) # verify
我打算添加我现有的后端。
class BackEnd():
def __init__(self):
super().__init__()
# data processing functions
最后是继承后台方法的接口,可以call/instantiate上面的UI方法
class Interface(BackEnd):
def __init__(self):
"""
"""
super().__init__()
self.select_data_file()
self.select_save_directory()
... # more back-end things
def select_data_file(self):
app = QtWidgets.QApplication(sys.argv)
file_selection_widget = FileSelectionWidget()
file_selection_widget.show()
sys.exit(app.exec_())
def select_save_directory(self):
app = QtWidgets.QApplication(sys.argv)
directory_selection_widget = DirectorySelectionWidget()
directory_selection_widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
interface = Interface()
sys.exit([arg])
:
Exit from Python.
这与PyQt无关。问题是 select_data_file
和 select_save_directory
都以 sys.exit
结尾,导致您的程序 立即 退出,无论之后调用什么函数。
除此之外,如果您要重用对话框(或在程序的生命周期内显示其他内容),通常最好避免重新创建 QApplication。
你可以做的是在你的 main
中启动一个 single QApplication,然后将你的 类 更改为 QDialog 而不是 QWidget 并使用exec_()
而不是 show()
。这允许保持与您现在相同的“阻塞”效果(使用 app.exec_()
),一旦对话框关闭就会被清除,然后您可以在需要时显示其他 windows。
请注意,为防止程序进一步退出,您应该使用 setQuitOnLastWindowClosed(False)
,然后在您真正想要退出时手动调用 QApplication.quit()
。
最后,请注意getOpenFileName
和getExistingDirectory
都是QFileDialog的static方法。他们 return 一个 new 预构建的文件对话框实例,因此在此之前创建一个实例是没有意义的。
您需要将参数添加到静态函数本身。
def on_clicked(self):
fpath, _ = QtWidgets.QFileDialog.getOpenFileName(
None, 'Select input file', '/home', '*.csv',
options=QtWidgets.QFileDialog.DontUseNativeDialog)
if fpath:
self._fpath = fpath
self.close()
我正在尝试使用 PyQt5 为 python 项目制作基本的前端图形用户界面。具体来说,我想从两件事开始。首先,我想提示用户 select 输入数据文件。然后,我想提示用户select一个可以保存文件的目录。
可以在下面找到代码的工作示例。 我的问题是为什么代码中有两个提示给用户(首先是输入文件,然后是保存目录)时用户只收到一个提示。代码没有抛出一个错误;注释掉输入文件例程(Interface
的 __init__
方法中的 self.select_save_directory()
)将允许保存目录例程到 运行.
首先,所有进口。
import sys
from PyQt5 import QtWidgets # QtGui, QtCore
然后,提示用户 select 输入 .csv 文件的小部件。
class FileSelectionWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Click here and select the data file you want to read")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
self._fpath = None
@property
def fpath(self):
return self._fpath
def on_clicked(self):
dialog = QtWidgets.QFileDialog(
self,
"Select input file",
"path",
"*.csv",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog)
fpath = dialog.getOpenFileName(None, 'Open file', '/home')[0]
self._fpath = fpath
self.close()
print(self.fpath) # verify
然后,提示用户 select 保存目录的小部件。
class DirectorySelectionWidget(QtWidgets.QWidget):
"""
This class allows the user to select the directory
to save files into via gui.
"""
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Click here and select the directory \nin which you would like to save files")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
self._savedir = None
@property
def savedir(self):
return self._savedir
def on_clicked(self):
dialog = QtWidgets.QFileDialog()
savedir = dialog.getExistingDirectory(None, "Select directory")
self._savedir = savedir
self.close()
print(self.savedir) # verify
我打算添加我现有的后端。
class BackEnd():
def __init__(self):
super().__init__()
# data processing functions
最后是继承后台方法的接口,可以call/instantiate上面的UI方法
class Interface(BackEnd):
def __init__(self):
"""
"""
super().__init__()
self.select_data_file()
self.select_save_directory()
... # more back-end things
def select_data_file(self):
app = QtWidgets.QApplication(sys.argv)
file_selection_widget = FileSelectionWidget()
file_selection_widget.show()
sys.exit(app.exec_())
def select_save_directory(self):
app = QtWidgets.QApplication(sys.argv)
directory_selection_widget = DirectorySelectionWidget()
directory_selection_widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
interface = Interface()
sys.exit([arg])
:
Exit from Python.
这与PyQt无关。问题是 select_data_file
和 select_save_directory
都以 sys.exit
结尾,导致您的程序 立即 退出,无论之后调用什么函数。
除此之外,如果您要重用对话框(或在程序的生命周期内显示其他内容),通常最好避免重新创建 QApplication。
你可以做的是在你的 main
中启动一个 single QApplication,然后将你的 类 更改为 QDialog 而不是 QWidget 并使用exec_()
而不是 show()
。这允许保持与您现在相同的“阻塞”效果(使用 app.exec_()
),一旦对话框关闭就会被清除,然后您可以在需要时显示其他 windows。
请注意,为防止程序进一步退出,您应该使用 setQuitOnLastWindowClosed(False)
,然后在您真正想要退出时手动调用 QApplication.quit()
。
最后,请注意getOpenFileName
和getExistingDirectory
都是QFileDialog的static方法。他们 return 一个 new 预构建的文件对话框实例,因此在此之前创建一个实例是没有意义的。
您需要将参数添加到静态函数本身。
def on_clicked(self):
fpath, _ = QtWidgets.QFileDialog.getOpenFileName(
None, 'Select input file', '/home', '*.csv',
options=QtWidgets.QFileDialog.DontUseNativeDialog)
if fpath:
self._fpath = fpath
self.close()