如何在PyQt5中启动文件后表对话框的交互式视图



使用PyQt5,我制作了两个小部件。第一个小部件是一个用户提示,用于选择一个带有确认所选文件路径的警报的文件。BackEnd读取所选择的数据文件并对数据进行处理;为了MWE的目的,dataBackEnd中被定义为二维数组,并且所选择的文件仅用于获得文件路径。第二个小部件加载表的视图供用户查看我不认为我缺少任何.close().exec_()方法,所以我不确定为什么第二个小部件不会加载。这个错误的原因是什么?我该如何避免它?我在以前的尝试中尝试过使用on_clicked()方法,但我不知道如何将其应用于不同类型的小部件/表等,这些小部件/表格等并不相同。

下面的代码用于二维数组的表视图。

import sys
from PyQt5 import QtWidgets, QtGui, QtCore
import numpy as np
class BackEnd():
def __init__(self):
super().__init__()
# ...
nrows, ncols = 50, 10
self.data = np.arange(nrows * ncols).reshape((nrows, ncols)).astype(str)
class TableModel(QtCore.QAbstractTableModel):
"""
An instance of this class is created inside the constructor
of the class 'TableWindow'.
"""
def __init__(self, data):
super(TableModel, self).__init__()
self._data = data
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
# See below for the nested-list data structure.
# .row() indexes into the outer list,
# .column() indexes into the sub-list
return self._data[index.row()][index.column()]
def rowCount(self, index):
# The length of the outer list.
return len(self._data)
def columnCount(self, index):
# The following takes the first sub-list, and returns
# the length (only works if all rows are an equal length)
return len(self._data[0])
class TableWindow(QtWidgets.QMainWindow):
"""
This class is used to view the raw data file via gui.
"""
def __init__(self, data):
super().__init__()
self.table = QtWidgets.QTableView()
self.model = TableModel(data)
self.table.setModel(self.model)
self.setCentralWidget(self.table)
self.setWindowTitle("Select 'row' if each student corresponds to a row; otherwise, select 'column'")

通过运行下面的代码片段,应该能够看到一个显示表视图的弹出窗口(第二个小部件(。

back_end = BackEnd()
## initialize application
app = QtWidgets.QApplication(sys.argv)
## view data file
window = TableWindow(back_end.data.tolist())
window.show()
## exit application
sys.exit(app.exec_())

当尝试组合这两个小部件时,应该注释掉上面的代码片段。下面的代码用于文件选择小部件(第一个小部件(。

class MainWindow(QtWidgets.QMainWindow):

"""
This class contains all GUI methods.
"""
def __init__(self):
self._backend = BackEnd()
self._fpath = None
super().__init__()
self.initialize_ui()
@property
def backend(self):
return self._backend
@property
def fpath(self):
return self._fpath
def initialize_ui(self):
self.select_input_data_file()
self.verify_input_data_file()
# self.close()
self.interact_with_table()
def select_input_data_file(self):
dialog = QtWidgets.QFileDialog(
self,
"Select input file",
"path",
"",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog)
fpath = dialog.getOpenFileName(None, 'Open file', '/home')[0]
self._fpath = fpath
# dialog.close()
# dialog = None
def verify_input_data_file(self):
alert = QtWidgets.QMessageBox()
alert.setText('The input filepath you selected is: n{}'.format(self.fpath))
alert.exec_()
# alert.close()
# alert = None
def interact_with_table(self):
window = TableWindow(self.backend.data.tolist())
window.show()

下面的代码是我尝试让用户使用第一个小部件来选择一个文件(成功(,然后显示数据表(不成功(。

## initialize application
app = QtWidgets.QApplication(sys.argv)
## view data file
window = MainWindow()
window.show()
## exit application
sys.exit(app.exec_())

MainWindow.interact_with_table中,TableWindow小部件被分配给一个局部变量。当interact_with_table返回时,此变量超出范围,TableWindow的引用计数变为零。这将导致TableWindow对象在下一个垃圾收集周期中被删除。一种解决方案是对表窗口进行持久引用,例如将其分配给MainWindow的实例变量,即

def interact_with_table(self):
self.table_window = TableWindow(self.backend.data.tolist())
self.table_window.show()

最新更新