问题
The line self.tableView.setSortingEnabled(True)
sorts a table view when clicking on the header, but it sorts incorrectly. That is, it thinks every column is a string (e.g. it sorts numbers like 1,11,12,2,22,3
, etc). How do I correct this?
My code:
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)
Update 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)
gives the output as:
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>]
everything seems good in console but on the GUI window it does not show the table?
回答1:
You don't show how you are creating the items for the model, but presumably you are doing something like this:
item = QtGui.QStandardItem(str(value))
where value
is a python numeric type.
To get numeric sorting, set the values like this instead:
item = QtGui.QStandardItem()
item.setData(value, QtCore.Qt.DisplayRole)
But note that this will also make the table automatically use spin-boxes for editing cells, which you may not want. So an alternative solution would be:
item = QtGui.QStandardItem(str(value))
item.setData(value, QtCore.Qt.UserRole)
...
model.setSortRole(QtCore.Qt.UserRole)
Finally, for fully customised sorting, you can also subclass QStandardItem
:
class StandardItem(QtGui.QStandardItem):
def __lt__(self, other):
return int(self.text()) < int(other.text())
item = StandardItem(str(value))
UPDATE:
Here is a demo script that reads csv files into a table, automatically converting the fields into the correct data-type for sorting:
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_())
来源:https://stackoverflow.com/questions/40309132/pyqt-how-to-sort-qtableview-columnsstrings-and-numericals