Qt代理
一般代理的实现只需要继承QStyledItemDelegate,重写其中的几个接口,
//自定义代理
class QIntDelegate : public QStyledItemDelegate
{
public:
explicit QIntDelegate(QObject *parent = nullptr);//必须显示构造
QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
};
在view中使用
theModel = new QStandardItemModel(10,FixedColounmCount,this);
theSelection = new QItemSelectionModel(theModel);
ui->tableView->setModel(theModel);
ui->tableView->setSelectionModel(theSelection);
//设置代理
QIntDelegate intSpinDelegate;
ui->tableView->setItemDelegateForColumn(0,&intSpinDelegate);
//设置行数
theModel->setRowCount(fileContent.count()-1);
// 读取表头
QString header = fileContent.at(0);
//分割数据
QStringList headerList=header.split(QRegularExpression("\\s+"),Qt::SkipEmptyParts);
theModel->setHorizontalHeaderLabels(headerList); //设置表头文字
// 设置表格数据
int j;
QStandardItem *item;
for(int i=1;i<fileContent.count();i++){
QString lineText = fileContent.at(i);
QStringList tempList = lineText.split(QRegularExpression("\\s+"),Qt::SkipEmptyParts);
for(j=0;j<FixedColounmCount-1;j++){
item = new QStandardItem(tempList.at(j));
theModel->setItem(i-1,j,item);
}
item = new QStandardItem(headerList.at(j));
if(tempList.at(j) == "1")
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
theModel->setItem(i-1,j,item);
}
代理持久化显示
刚刚实现的代理只有在双击编辑时才会展示出来,但在某些需求下,我们需要代理一直显示;我的实现方法是在添加数据时使用openPersistentEditor实现;
ui->tableView->openPersistentEditor(theModel->index(i,0));//设置代理持续显示
记录一下QTableView中遇到的一些问题和解决方法
QTableView设置表头样式;
ui->fileContent->horizontalHeader()->setStyleSheet("QHeaderView::section {"
"background-color:#f3f3f4;"
"border:none;"
"color:#777777;"
"margin-left:15px;}");//设置水平表头的样式表
设置QTableView为行选不可修改;
ui->fileContent->setEditTriggers(QAbstractItemView::NoEditTriggers);//不可修改
ui->fileContent->setSelectionBehavior(QAbstractItemView::SelectRows);//行选
设置列的宽度调整策略;
ui->fileContent->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//宽度最大化
//设置莫一列的宽度
ui->fileContent->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); //填充剩余宽度
ui->fileContent->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);// 固定宽度模式
ui->fileContent->horizontalHeader()->resizeSection(1, 100); // 设置第一列的宽度为100
当QTableView失去焦距是有一圈白点,影响美观;
setFocusPolicy(Qt::NoFocus);//没有焦点,防止item点击时出现选中的白色边框
在QTableView的页面中设置参数,在代理中使用;
自定义参数类型;
#define FileType Qt::UserRole
#define FileName Qt::UserRole+1
Qt 中的 Qt::EditRole 是一个定义在 QAbstractItemModel 类中的角色(Role)之一。它用于表示对数据进行编辑的角色。
在 QAbstractItemModel 中,数据可以具有多个角色,如 Qt::DisplayRole(用于显示数据)、Qt::UserRole(用户自定义角色)等。每个角色都有不同的含义和用途。
Qt::EditRole 角色用于表示可编辑的数据。当用户想要编辑某个项目时,模型会将数据以 EditRole 的形式提供给编辑器。编辑器可以修改数据并将其更新回模型中。
当你使用 QItemDelegate 或 QStyledItemDelegate 自定义委托时,通常会重写 setEditorData()
和 setModelData()
函数,以处理编辑器和模型之间数据的转换。这两个函数通常使用 EditRole 角色来获取和设置数据。
例如,在 setEditorData()
函数中,你可以使用 index.model()->data(index, Qt::EditRole)
来获取编辑器所需的数据值。在 setModelData()
函数中,你可以使用 model->setData(index, value, Qt::EditRole)
将编辑器中修改的值更新到模型中。
需要注意的是,每个模型可以根据需要定义和使用不同的角色。因此,具体使用 EditRole 还是其他角色取决于模型的实现和需求。
Qt中的ItemDataRole定义如下:
enum ItemDataRole {
DisplayRole = 0,
DecorationRole = 1,
EditRole = 2,
ToolTipRole = 3,
StatusTipRole = 4,
WhatsThisRole = 5,
// Metadata
FontRole = 6,
TextAlignmentRole = 7,
BackgroundRole = 8,
ForegroundRole = 9,
CheckStateRole = 10,
// Accessibility
AccessibleTextRole = 11,
AccessibleDescriptionRole = 12,
// More general purpose
SizeHintRole = 13,
InitialSortOrderRole = 14,
// Internal UiLib roles. Start worrying when public roles go that high.
DisplayPropertyRole = 27,
DecorationPropertyRole = 28,
ToolTipPropertyRole = 29,
StatusTipPropertyRole = 30,
WhatsThisPropertyRole = 31,
// Reserved
UserRole = 0x0100
};
为item设置data,绑定的model中
QStandardItem* item = new QStandardItem();
item->setData(isFile,FileType);
item->setData(filename,FileName);
theModel->setItem(i, 0, item);
ui->fileContent->openPersistentEditor(theModel->index(i,0));//设置代理持续显示
在代理中通过model取出data
void FileDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
bool isFile = index.model()->data(index,FileType).toBool();
QString fileName = index.model()->data(index,FileName).toString();
QToolButton * filetoolButton = static_cast<QToolButton *>(editor);
QIcon fileIcon;
if(isFile){
fileIcon.addFile(":/images/file.svg");
}else{
fileIcon.addFile(":/images/fileDir.svg");
}
filetoolButton->setIcon(fileIcon);
filetoolButton->setIconSize(QSize(16,16));
filetoolButton->setText(fileName);
}
在代理中获取其他单元格的data:
使用了 index.sibling(row, column) 方法来获取同一行中的其他的索引。然后使用 data() 方法获取该索引处的显示数据,并将其转换为字符串类型。
QString filename = index.model()->data(index.sibling(index.row(), 0), Qt::DisplayRole).toString();