QCheckBox in QComboBox



  • Hello.
    I bumped into a problem of adding an item QCheckBox into QComboBox. What Ive found is the code for creating ItemDelegate for QComboBox, but it makes all of items in QComboBox as QCheckBox. My task is to add just one check box into the list of common comboboxs items...
    Here is a code I found:
    @class CheckBoxList: public QComboBox
    {
    Q_OBJECT;

    public:
    CheckBoxList(QWidget *widget = 0);
    virtual ~CheckBoxList();
    virtual void paintEvent(QPaintEvent *);
    void SetDisplayText(QString text);
    QString GetDisplayText() const;

    private:
    QString m_DisplayText;
    };@

    @class CheckBoxListDelegate : public QItemDelegate
    {
    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 & option ,
    const QModelIndex & index ) 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);
    }
    };

    CheckBoxList::CheckBoxList(QWidget *widget )
    :QComboBox(widget),m_DisplayText("")
    {
    // set delegate items view
    view()->setItemDelegate(new CheckBoxListDelegate(this));

    // Enable editing on items view
    view()->setEditTriggers(QAbstractItemView::CurrentChanged);
    }

    CheckBoxList::~CheckBoxList()
    {
    ;
    }

    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 text)
    {
    m_DisplayText = text;
    }

    QString CheckBoxList::GetDisplayText() const
    {
    return m_DisplayText;
    }@

    Is anyone have thoughts how to improve this code to get possibility for adding into QComboBox 2 types of items: QCheckBox and common QComboBox items?
    Or there is some other ways to achieve such behaviour?



  • you have to seperate inside the itemd elegate, which item to draw. You install it as item delegate for the whole list --> all items look the same. If you have a switch inside your delegate, you can also draw as standard items by calling the base implemenbation.



  • Youre right. And furthermore, Ive done this.
    For my task I had to put only one check box and it was supposed to be last item in the combo box.
    So, now code for ItemDelegate looks like that:
    @class CheckBoxListDelegate : public QItemDelegate
    {
    public:
    CheckBoxListDelegate(QObject *parent) : QItemDelegate(parent)
    {
    }

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const
    {
        //Get item data
        int row_count = index.model()->rowCount(index.parent());
        if(index.row() == --row_count)
        {
            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);
            return;
        }
    
        return QItemDelegate::paint(painter,option,index);
    }
    
    QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem & option ,
                          const QModelIndex & index ) const
    {
        int row_count = index.model()->rowCount(index.parent());
            // create check box as our editor
        if(index.row() == --row_count)
        {
                 QCheckBox *editor = new QCheckBox(parent);
                 return editor;
        }
    
        return 0;
    }
    
     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);
     } 
    

    }; @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.