Есть выпадающий комбобокс с реализованным делегатом (итемы - чекбоксы)
class CheckBoxListDelegate;
class CheckBoxList: public QComboBox
{
Q_OBJECT
public:
CheckBoxList(QString text, QWidget *widget = 0);
virtual ~CheckBoxList();
virtual void paintEvent(QPaintEvent *);
public slots:
void SetDisplayText(QString strr);
QString GetDisplayText() const;
private:
CheckBoxListDelegate * delegate;
QString m_DisplayText;
private slots:
void act ();
};
CheckBoxList::CheckBoxList(QString text, QWidget *widget )
:QComboBox(widget),m_DisplayText(text)
{
delegate = new CheckBoxListDelegate(this);
view()->setItemDelegate(delegate);
view()->setEditTriggers(QAbstractItemView::CurrentChanged);
connect(delegate,SIGNAL(dataChanged()),this,SLOT(act()));
}
CheckBoxList::~CheckBoxList()
{
}
void CheckBoxList::act()
{
emit activated(0);
}
void CheckBoxList::paintEvent(QPaintEvent *)
{
QStylePainter painter(this);
painter.setPen(palette().color(QPalette::Text));
// draw the combobox frame, focusrect and selected etc.
QStyleOptionComboBox opt;
initStyleOption(&opt);
// if no display text been set , use "..." as default
if(m_DisplayText.isNull())
opt.currentText = "...";
else
opt.currentText = m_DisplayText;
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
// draw the icon and text
painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
}
void CheckBoxList::SetDisplayText(QString strr)
{
m_DisplayText = strr;
}
QString CheckBoxList::GetDisplayText() const
{
return m_DisplayText;
}
Делегат:
class CheckBoxListDelegate : public QItemDelegate
{
Q_OBJECT
signals:
void dataChanged () const;
public slots:
void dCH ()
{
emit dataChanged();
}
public:
CheckBoxListDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
//Get item data
bool value = index.data(Qt::UserRole).toBool();
QString text = index.data(Qt::DisplayRole).toString();
// fill style options with item data
const QStyle *style = QApplication::style();
QStyleOptionButton opt;
opt.state |= value ? QStyle::State_On : QStyle::State_Off;
opt.state |= QStyle::State_Enabled;
opt.text = text;
opt.rect = option.rect;
// draw item data as CheckBox
style->drawControl(QStyle::CE_CheckBox,&opt,painter);
}
QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &) const
{
// create check box as our editor
QCheckBox *editor = new QCheckBox(parent);
return editor;
}
void setEditorData(QWidget *editor,
const QModelIndex &index) const
{
//set editor data
QCheckBox *myEditor = static_cast<QCheckBox*>(editor);
myEditor->setText(index.data(Qt::DisplayRole).toString());
myEditor->setChecked(index.data(Qt::UserRole).toBool());
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
//get the value from the editor (CheckBox)
QCheckBox *myEditor = static_cast<QCheckBox*>(editor);
bool value = myEditor->isChecked();
//set model data
QMap<int,QVariant> data;
data.insert(Qt::DisplayRole,myEditor->text());
data.insert(Qt::UserRole,value);
model->setItemData(index,data);
emit dataChanged();
}
};
Использование во вью:
QHBoxLayout * labLay = new QHBoxLayout (ui->gbLabel);
cblLabel = new CheckBoxList (QString::fromLocal8Bit("Выберите метку ..."), ui->gbLabel);
labLay->addWidget(cblLabel);
connect(cblLabel,SIGNAL(activated(int)),this,SLOT(changedLabelSettings()));
ну и в конце концов данные в выпадающий список предостаялются моделью
cblLabel->setModel(metkaModel);
То есть изменение "отмеченности" чекбокса прокитдывается из делегата.
Код писался давно и по какому то примеру, точно уже не вспомню. Однако сомнения закрались в коректности такого подхода, прочетом статей, но без примеров как правильно уведомить вью об изменении данных
А так же коспилятор рисуте ворнинги напротив константных сигналов делегата и слота класса CheckBoxList. Однако константность убрать невозмоно так как сигнал эмитится констатнтным методом
Подскажите пожалуйста как сделать красиво.