我需要在表格视图单元格中显示带有标签的复选框,用当前代码它显示复选框状态而不是标签。我已经创建了自定义委托和模型。下面是完成的代码。
The result I got look like this
表格视图委托.h
#include <QObject>
#include <QStyledItemDelegate>
#include "QSpinBox"
#include "QDoubleSpinBox"
#include "QCheckBox"
#include "QApplication"
#include "QStyle"
class table_view_delegate : public QStyledItemDelegate
{
Q_OBJECT
public:
table_view_delegate(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;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
signals:
};
表格视图委托.cpp
#include "table_view_delegate.h"
#include "QMouseEvent"
#include "QAbstractItemModel"
#include "QCheckBox"
#include "QSpinBox"
table_view_delegate::table_view_delegate(QObject *parent) : QStyledItemDelegate{parent}
{
}
QWidget *table_view_delegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex & index ) const
{
int c= index.column();
if(c == 0 ){
QCheckBox* check = new QCheckBox("Lable",parent);
return check;
}
else if(c == 1 ){
QSpinBox *editor = new QSpinBox(parent);
return editor;
}
else {
return NULL;
}
}
void table_view_delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
int c= index.column();
if(c == 0 ){
int value = index.model()->data(index, Qt::CheckStateRole).toInt();
QCheckBox* check = static_cast<QCheckBox*>(editor);
if(value==0)
check->setChecked(false);
else
check->setChecked(true);
check->setText("test");
}
else if(c==1){
QString val_str = index.model()->data(index, Qt::EditRole).toString();
float value = val_str.toFloat();
QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
spinBox->setValue(value);
}
}
void table_view_delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
int c= index.column();
if(c == 0 ){
QCheckBox* check = static_cast<QCheckBox*>(editor);
check->setText("test");
QString value =QString::number(check->isChecked());//check->isChecked();
model->setData(index, value, Qt::EditRole);
}
else if(c ==1){
QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
spinBox->interpretText();
QString value = QString::number(spinBox->value(), 'f', 2);
model->setData(index, value, Qt::EditRole);
}
}
void table_view_delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
void table_view_delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter, option, index);
}
表格视图模型.h
#include <QObject>
#include <QAbstractTableModel>
class table_view_model : public QAbstractTableModel
{
Q_OBJECT
public:
explicit table_view_model(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void setDataList(QList <QStringList> alog_data_list);
QVariant headerData(int section, Qt::Orientation , int role) const override;
private:
QList <QStringList> model_data_list;
int col_count = 3;
QStringList header={"CheckBox","SpinBox","String"};
signals:
};
表格视图模型.cpp
#include "table_view_model.h"
table_view_model::table_view_model(QObject *parent) : QAbstractTableModel{parent}
{
}
int table_view_model::rowCount(const QModelIndex & /*parent*/) const
{
return model_data_list.length();
}
int table_view_model::columnCount(const QModelIndex & /*parent*/) const
{
return col_count;
}
QVariant table_view_model::data(const QModelIndex &index, int role) const
{
int r = index.row();
int c = index.column();
if(model_data_list.length()==0)
return QVariant();
if (!index.isValid())
return QVariant();
if( c==0){
if (role == Qt::CheckStateRole&& c==0 ){
int checked = model_data_list[r][c].toInt();
if (checked)
return Qt::Checked;
else
return Qt::Unchecked;
}
else if(role == Qt::EditRole){
return model_data_list[r][c];
}
else if (role == Qt::DisplayRole)
return model_data_list[r][c];
}
else{
if (role == Qt::DisplayRole)
return model_data_list[r][c];
}
return QVariant();
}
bool table_view_model::setData(const QModelIndex &index, const QVariant &value, int role)
{
int c=index.column();
if( c==1){
if (role == Qt::EditRole) {
if (!checkIndex(index))
return false;
return true;
}
}
else if (role == Qt::CheckStateRole&&c==0)
{
model_data_list[index.row()][index.column()] = value.toString();
if ((Qt::CheckState)value.toInt() == Qt::Checked)
{
//user has checked item
return true;
}
else
{
//user has unchecked item
return true;
}
}
return false;
}
void table_view_model::setDataList(QList <QStringList> model_data_listTmp){
table_view_model::beginResetModel();
model_data_list.clear();
for(int i=0;i<model_data_listTmp.length();i++){
model_data_list.push_back(model_data_listTmp[i]);
}
table_view_model::endResetModel();
}
Qt::ItemFlags table_view_model::flags(const QModelIndex &index) const
{
int c=index.column();
//Editable column
if(c==1)
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
else if(c==0)
return Qt::ItemIsUserCheckable | QAbstractTableModel::flags(index);
else
return QAbstractTableModel::flags(index);
}
QVariant table_view_model::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole){
return QVariant();
}
if (orientation == Qt::Horizontal)
return header.at(section);
else
return QString::number(section);
}
在MainWindow.cpp中,我初始化表格视图,如下所示。
table_view_model *model = new table_view_model();
//QSqlQueryModel *algo_model = db_conn->getAlgoTableData();
ui->tableView->setModel(model);
ui->tableView->horizontalHeader()->setStretchLastSection(true);
table_view_delegate *delgate = new table_view_delegate() ;
ui->tableView->setItemDelegate(delgate);
QList <QStringList> data_list;
QStringList r1;
r1.append("0");
r1.append("100");
r1.append("Str1");
data_list.append(r1);
QStringList r2;
r2.append("1");
r2.append("200");
r2.append("Str2");
data_list.append(r2);
model->setDataList(data_list);
1条答案
按热度按时间s6fujrry1#
你对角色有很多困惑。
你的模型似乎需要3个角色。用我的话简单描述一下。一定要检查文档中我没有描述的角色。
Qt::DisplayRole
:屏幕上显示的内容,例如带千位分隔符的格式化数字(实际类型QString
)。Qt::EditRole
:显示的底层数据,例如模型的实际编号。这是您希望在代理编辑器中使用的数据。但是,在许多情况下,Qt::EditRole
的数据与Qt::DisplayRole
的数据相同。同样,你可以选择实现一个接受在
Qt::EditRole
和Qt::DisplayRole
中被编辑的模型,区别实际上是关于屏幕显示的格式。Qt::CheckStateRole
:索引处的Checkstate(类型Qt::CheckState
)。默认情况下,它为空值QVariant
,表示视图将不显示复选框。但是,您可以实现一个在所有情况下都显示复选框的委托(或者相反,让一个委托不显示复选框,即使应该有一个复选框)
在您的模型中,所有内容都存储在
QList <QStringList> model_data_list;
中data
方法中的样品:那么你不应该对显示的文本和检查状态相同感到惊讶。你必须在角色之间创建超级清晰的边界,以免遇到这种混乱。
一个简单的解决方案是在类中添加一个新成员来存储检查状态,然后在
data
和setData
方法中使用它,当你使用它时,改变另一个成员的类型,没有必要在QString
和QVariant
之间不断地转换。在标题中:
经过一些认真的重构,源文件变成了:
我不打算向代表发表讲话,因为这不是导致您的显示问题的原因,在我在评论中指出这一点之后,我假设您已经更正了
setModelData
,但我重申,您应该认真考虑为视图的每一列使用不同的委托。这将删除所有if (c == 0)
,并允许在视图/中使用委托。column 0
中没有复选框的型号。