c++ - QCombobox 自定义行为与模型
问题描述
我有一个返回 DisplayRole 字符串的模型。我为我的 QCombobox 做了 setModel。但我需要放置“setSeparator”而不是一些值。所以不必显示元素本身,它必须用作放置分隔符的标记。这是因为我不能对我的 QCombobox 使用 setSeparator 函数,使用 setmodel 时它没有效果。
我怎样才能用行为覆盖?
解决方案
首先,您需要从模型中返回一个分隔符。对我来说,最好使用特殊角色作为分隔符,但也可以使用字符串标记。
class SeparatorModel : public QAbstractItemModel
{
Q_OBJECT
public:
static const int SeparatorRole = Qt::UserRole + 5;
explicit SeparatorModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
private:
QStringList m_strings;
};
data
在方法中返回您的分隔符
QVariant SeparatorModel::data(const QModelIndex &index, int role) const
{
if (SeparatorRole == role)
{
if (index.row() == 3) //separator at row 3
{
return true;
}
else
{
return false;
}
}
if (Qt::DisplayRole == role)
{
return m_strings.at(index.row());
}
return QVariant();
}
为了防止分隔符选择也重新实现flags
方法
Qt::ItemFlags SeparatorModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags;
flags = Qt::ItemIsSelectable;
if (index.row() == 3) //separator at row 3
{
//no enabled for separator
}
else
{
flags = flags | Qt::ItemIsEnabled;
}
return flags;
}
然后您需要创建自定义项目委托
class SeparatorDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit SeparatorDelegate(QObject *parent = 0);
/*
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
*/
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
如果设置分隔符角色的数据,则在paint
方法中画线
void SeparatorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.data(SeparatorModel::SeparatorRole).toBool())
{
painter->drawLine(option.rect.left(), option.rect.center().y(),
option.rect.right(), option.rect.center().y());
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
并在sizeHint
方法中定义分隔符的大小
QSize SeparatorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.data(SeparatorModel::SeparatorRole).toBool())
{
return QSize(0, 2);
}
return QStyledItemDelegate::sizeHint( option, index );
}
毕竟只需设置模型并委托给您的组合框
ui->comboBox->setModel(&m_model);
SeparatorDelegate *delegate = new SeparatorDelegate(this);
ui->comboBox->setItemDelegate(delegate);
推荐阅读
- python - scipy odeint,使用状态变量达到某个阈值后需要更改的参数求解 ODE
- angular - 在 IE11 中运行 Angular 6 站点时未处理的承诺拒绝
- python - 如何在 R/Python 的求解器目标中设置等于函数?
- sql - ODBC 源不接收动态变量值
- reactjs - 如何根据媒体查询使列表每行显示多个项目
- r - 什么时候应该使用 describe() 和 test_that()?
- javascript - Safari 和 Chrome 上 this.toSource() 的等价物是什么
- python - 如何将两个定义的功能重复 5 次?Python
- mysql - 获取两个日期时间段之间的数据库搜索结果
- excel - 使用未识别的 laravel 标题导入 Excel 文件