Название: QComboBox + CheckBox Delegate
Отправлено: INZER от Июнь 04, 2022, 00:32
Есть выпадающий комбобокс с реализованным делегатом (итемы - чекбоксы) 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. Однако константность убрать невозмоно так как сигнал эмитится констатнтным методом Подскажите пожалуйста как сделать красиво.
Название: Re: QComboBox + CheckBox Delegate
Отправлено: sergek от Июнь 05, 2022, 14:40
А как с этой... этим комбобоксом работать? Есть минимальный проект?
Название: Re: QComboBox + CheckBox Delegate
Отправлено: INZER от Июнь 06, 2022, 18:39
Да, конечно
https://disk.yandex.ru/i/J_cX-kWAehPGSQ (https://disk.yandex.ru/i/J_cX-kWAehPGSQ)
Название: Re: QComboBox + CheckBox Delegate
Отправлено: INZER от Июнь 07, 2022, 10:04
А как с этой... этим комбобоксом работать? Есть минимальный проект?
Почему то подумал что вы просите видео работы его ) Сегодня наткнулся на ответ и понял что Вы просите проект )) Прикрепил, спасибо. Меня смущают строки 33 и 45 filterDialog.h Как избежать этого ворнинга https://github.com/KDE/clazy/blob/1.10/docs/checks/README-const-signal-or-slot.md Ну и вобще кажется что сам подход реализации неверен. Проект доступен по ссылке: https://disk.yandex.ru/d/Q5z-owgKKAguVg (https://disk.yandex.ru/d/Q5z-owgKKAguVg) Так же получая сигнал об изменении модели из метода делегата setModelData я оповещаю вью о всех изменениях элементов (в том числе об активации отдельных ячеек). Хотелось бы узнавать только об изменении состояния чекбокса.
Название: Re: QComboBox + CheckBox Delegate
Отправлено: INZER от Июнь 07, 2022, 16:57
Я впринципе разобрался, может кому будет полезно. Сигнал об изменении (в моем случае выбор чекбокса в выпадающем списке) получаю не от делегата а из модели. void QStandardItemModel::itemChanged(QStandardItem *item)
|