It's OK to just show the image
# L.append([QIcon(r"favicon.ico"), "file", "absolute_path", "modifytime"])
But can't show images and text
# L.append([QTableWidgetItem(QIcon(r"favicon.ico"), "file"), "file", "absolute_path", "modifytime"])
This is my model,I am using qtableview.
I'm using the setmodel method, and I want to add data dynamically.
class FileModel(QAbstractTableModel):
def __init__(self, data, header, *args, **kwargs):
super(FileModel, self).__init__()
self.datalist = data
self.header = header
def rowCount(self, parent=None, *args, **kwargs):
return len(self.datalist)
def columnCount(self, parent=None, *args, **kwargs):
return len(self.header)
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
if role == Qt.DisplayRole or role == Qt.DecorationRole:
return self.datalist[index.row()][index.column()]
else:
return None
def headerData(self, col, orientation, role=None):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.header[col]
return None
def append_data(self, x):
self.datalist.append(x)
self.layoutChanged.emit()
def remove_row(self, row):
self.datalist.pop(row)
self.layoutChanged.emit()
def remove_all(self):
self.datalist.clear()
self.layoutChanged.emit()
help me,can show images and text
The problem is with how you are storing your data and accessing it in your data
method. I am having a difficult time trying to describe it so instead I am just going to show examples.
If you want a cell to contain both a icon and text then you need to return the icon when the role is the decoration role and the text when it is the display roll.
For example:
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
row = index.row()
if role == Qt.DisplayRole:
return 'some text here'
elif role == Qt.DecorationRole:
return QIcon('path/to/icon')
return None
Since it appears that you are storing your data in a 2dim list this is a problem because you want every index to store the data for it's own cell.
So one possible solution is to store tuples at each index. So your dataList would have to look like this:
[(text, QIcon()), (text, QIcon), (text,)]
In which case your data method would do:
...
if role == Qt.DecorationRole:
return self.dataList[index.row()][index.column()][1]
elif role == Qt.DisplayRole:
return self.dataList[index.row()][index.column()][0]
...
or you could create your own item class that would work like the QTableWidgetItem.
class TableItem:
def __init__(self, text, icon=None):
self.icon = icon
self.text = text
...
then your data method would look like this:
...
item = self.dataList[index.row()][index.column()]
if role == Qt.DecorationRole:
return item.icon
elif role == Qt.DisplayRole:
return item.text
...
and you would need to construct the dataList like this:
dataList.append([TableItem('text', QIcon('/patth')), TableItem('text'), TableItem('Text')])
Hopefully those examples will help make up for my terrible explanation.
musicmante cleverly suggested using a dictionary where the keys are the different data roles in the comments.
For example:
Your data list rows would look like:
[{Qt.DisplayRole: 'text', Qt.DecorationRole: QIcon('/path')},
{Qt.DisplayRole: 'other text', Qt.DecorationRole: None},
{Qt.DisplayRole: 'more text', 'Qt.DecorationRole': None},....]
and the data method would do something like this.
...
item = self.dataList[index.row()][index.column()]
if role in [Qt.DisplayRole, Qt.DecorationRole]:
return item[role]
...