PyQt:如何对 QTableView 列(字符串和数字)进行排序
PyQt: How to sort QTableView columns(strings and numericals)
当单击 header 时,行 self.tableView.setSortingEnabled(True)
对 table 视图进行排序,但排序不正确。也就是说,它认为每一列都是一个字符串(例如,它对 1,11,12,2,22,3
等数字进行排序)。我该如何纠正?
我的代码:
self.model = QtGui.QStandardItemModel()
with open(file_name_temp, "rt") as fileInput:
i = 1
for row in csv.reader(fileInput):
item = QtGui.QStandardItem()
for field in row:
items = [
item.setData(field, QtCore.Qt.UserRole)
]
print(items)
self.model.appendRow(items)
tab_table_view = QtGui.QWidget()
self.Tab.insertTab(0, tab_table_view, self.File_Name)
self.tableView = QtGui.QTableView(tab_table_view)
self.tableView.setGeometry(QtCore.QRect(0, 0, 721, 571))
self.model = QtGui.QStandardItemModel(self)
self.tableView.setModel(self.model)
colll = self.Datas.dtypes.index
col_names = np.array(colll)
col_names = np.insert(col_names, 0, self.Datas.index.name)
self.model.setHorizontalHeaderLabels(col_names)
self.tableView.hideRow(0)
self.model.setSortRole(QtCore.Qt.UserRole)
更新 1:
if (".csv" or ".txt") in self.File_Name:
with open(file_name_temp, "rt") as fileInput:
i = 1
reader = csv.reader(fileInput)
next(reader, None)
for row in reader:
for x in range(0,Num_col+1):
try:
int(row[x])
row[x]=int(row[x])
except ValueError:
print('Not Int')
items = []
for field in row:
item = QtGui.QStandardItem(field)
if type(field)==int:
print('yyy')
data = int(field)
else:
data = field
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
print(items)
self.model.appendRow(items)
输出为:
yyy
yyy
yyy
yyy
yyy
yyy
yyy
yyy
yyy
[<PyQt4.QtGui.QStandardItem object at 0x0000000006DF3948>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF38B8>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3828>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3798>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3678>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3EE8>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3F78>, <PyQt4.QtGui.QStandardItem object at 0x00000000095D4048>, <PyQt4.QtGui.QStandardItem object at 0x00000000095D40D8>]
在控制台中一切似乎都很好,但在 GUI 上 window 它不显示 table?
你没有展示你是如何为模型创建项目的,但大概你正在做这样的事情:
item = QtGui.QStandardItem(str(value))
其中 value
是 python 数值类型。
要进行数字排序,请改为像这样设置值:
item = QtGui.QStandardItem()
item.setData(value, QtCore.Qt.DisplayRole)
但请注意,这也会使 table 自动使用旋转框来编辑单元格,这可能是您不想要的。因此,另一种解决方案是:
item = QtGui.QStandardItem(str(value))
item.setData(value, QtCore.Qt.UserRole)
...
model.setSortRole(QtCore.Qt.UserRole)
最后,对于完全自定义的排序,您还可以继承 QStandardItem
:
class StandardItem(QtGui.QStandardItem):
def __lt__(self, other):
return int(self.text()) < int(other.text())
item = StandardItem(str(value))
更新:
这是一个演示脚本,可将 csv 文件读入 table,自动将字段转换为正确的数据类型以进行排序:
import sys, csv
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.model = QtGui.QStandardItemModel(self)
self.model.setSortRole(QtCore.Qt.UserRole)
self.tableView = QtGui.QTableView()
self.tableView.setSortingEnabled(True)
self.tableView.setModel(self.model)
self.button = QtGui.QPushButton('Open CSV', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.tableView)
layout.addWidget(self.button)
def handleButton(self):
path = QtGui.QFileDialog.getOpenFileName(
self, 'Open CSV', '', 'CSV files (*.csv *.txt)')
if path:
self.model.setRowCount(0)
with open(path) as stream:
reader = csv.reader(stream)
next(reader, None)
for row in reader:
items = []
for field in row:
item = QtGui.QStandardItem(field)
for numtype in (int, float):
try:
data = numtype(field)
break
except (ValueError, OverflowError):
pass
else:
print('Not a number: %r' % field)
data = field
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
self.model.appendRow(items)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 150, 600, 400)
window.show()
sys.exit(app.exec_())
当单击 header 时,行 self.tableView.setSortingEnabled(True)
对 table 视图进行排序,但排序不正确。也就是说,它认为每一列都是一个字符串(例如,它对 1,11,12,2,22,3
等数字进行排序)。我该如何纠正?
我的代码:
self.model = QtGui.QStandardItemModel()
with open(file_name_temp, "rt") as fileInput:
i = 1
for row in csv.reader(fileInput):
item = QtGui.QStandardItem()
for field in row:
items = [
item.setData(field, QtCore.Qt.UserRole)
]
print(items)
self.model.appendRow(items)
tab_table_view = QtGui.QWidget()
self.Tab.insertTab(0, tab_table_view, self.File_Name)
self.tableView = QtGui.QTableView(tab_table_view)
self.tableView.setGeometry(QtCore.QRect(0, 0, 721, 571))
self.model = QtGui.QStandardItemModel(self)
self.tableView.setModel(self.model)
colll = self.Datas.dtypes.index
col_names = np.array(colll)
col_names = np.insert(col_names, 0, self.Datas.index.name)
self.model.setHorizontalHeaderLabels(col_names)
self.tableView.hideRow(0)
self.model.setSortRole(QtCore.Qt.UserRole)
更新 1:
if (".csv" or ".txt") in self.File_Name:
with open(file_name_temp, "rt") as fileInput:
i = 1
reader = csv.reader(fileInput)
next(reader, None)
for row in reader:
for x in range(0,Num_col+1):
try:
int(row[x])
row[x]=int(row[x])
except ValueError:
print('Not Int')
items = []
for field in row:
item = QtGui.QStandardItem(field)
if type(field)==int:
print('yyy')
data = int(field)
else:
data = field
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
print(items)
self.model.appendRow(items)
输出为:
yyy
yyy
yyy
yyy
yyy
yyy
yyy
yyy
yyy
[<PyQt4.QtGui.QStandardItem object at 0x0000000006DF3948>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF38B8>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3828>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3798>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3678>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3EE8>, <PyQt4.QtGui.QStandardItem object at 0x0000000006DF3F78>, <PyQt4.QtGui.QStandardItem object at 0x00000000095D4048>, <PyQt4.QtGui.QStandardItem object at 0x00000000095D40D8>]
在控制台中一切似乎都很好,但在 GUI 上 window 它不显示 table?
你没有展示你是如何为模型创建项目的,但大概你正在做这样的事情:
item = QtGui.QStandardItem(str(value))
其中 value
是 python 数值类型。
要进行数字排序,请改为像这样设置值:
item = QtGui.QStandardItem()
item.setData(value, QtCore.Qt.DisplayRole)
但请注意,这也会使 table 自动使用旋转框来编辑单元格,这可能是您不想要的。因此,另一种解决方案是:
item = QtGui.QStandardItem(str(value))
item.setData(value, QtCore.Qt.UserRole)
...
model.setSortRole(QtCore.Qt.UserRole)
最后,对于完全自定义的排序,您还可以继承 QStandardItem
:
class StandardItem(QtGui.QStandardItem):
def __lt__(self, other):
return int(self.text()) < int(other.text())
item = StandardItem(str(value))
更新:
这是一个演示脚本,可将 csv 文件读入 table,自动将字段转换为正确的数据类型以进行排序:
import sys, csv
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.model = QtGui.QStandardItemModel(self)
self.model.setSortRole(QtCore.Qt.UserRole)
self.tableView = QtGui.QTableView()
self.tableView.setSortingEnabled(True)
self.tableView.setModel(self.model)
self.button = QtGui.QPushButton('Open CSV', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.tableView)
layout.addWidget(self.button)
def handleButton(self):
path = QtGui.QFileDialog.getOpenFileName(
self, 'Open CSV', '', 'CSV files (*.csv *.txt)')
if path:
self.model.setRowCount(0)
with open(path) as stream:
reader = csv.reader(stream)
next(reader, None)
for row in reader:
items = []
for field in row:
item = QtGui.QStandardItem(field)
for numtype in (int, float):
try:
data = numtype(field)
break
except (ValueError, OverflowError):
pass
else:
print('Not a number: %r' % field)
data = field
item.setData(data, QtCore.Qt.UserRole)
items.append(item)
self.model.appendRow(items)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 150, 600, 400)
window.show()
sys.exit(app.exec_())