【问题标题】:How to make QComboBox as MultiSelect in QT?如何在 QT 中将 QComboBox 设为 MultiSelect?
【发布时间】:2011-09-24 05:45:06
【问题描述】:

QT中如何将QComboBox设为MultiSelect?

QT的Combox中没有MultiSelect的选项?

任何人都可以建议我一些不同的控件,但外观和感觉应该只像 QCombobox。

【问题讨论】:

    标签: qt


    【解决方案1】:

    //这是名为CheckBoxList.h的文件

    #ifndef CHECKBOXLIST_H
    #define CHECKBOXLIST_H
    
    #include <QtGui>
    
    class CheckBoxList: public QComboBox
    {
        Q_OBJECT;
    
    public:
        CheckBoxList(QWidget *widget = 0);
        virtual ~CheckBoxList();
        bool eventFilter(QObject *object, QEvent *event);
        virtual void paintEvent(QPaintEvent *);
        void SetDisplayText(QString text);
        QString GetDisplayText() const;
    
    private:
        QString m_DisplayText;
    };
    
    #endif // CHECKBOXLIST_H
    

    //这是名为CheckBoxList.cpp的文件

    #include "CheckBoxList.h"
    #include <QtGui>
    
    // internal private delegate
    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);
    //QMessageBox::information(0,"Info",text);
    
        }
    
            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);
    
         }
    
         void updateEditorGeometry(QWidget *editor,
             const QStyleOptionViewItem &option, const QModelIndex &index ) const
         {
    
             editor->setGeometry(option.rect);
    
    
         }
     };     
    //min-width:10em; 
         CheckBoxList::CheckBoxList(QWidget *widget )
         :QComboBox(widget),m_DisplayText(0)
         {
        // set delegate items view 
        view()->setItemDelegate(new CheckBoxListDelegate(this));
        //view()->setStyleSheet("  padding: 15px; ");
        // Enable editing on items view
        view()->setEditTriggers(QAbstractItemView::CurrentChanged);
    
        // set "CheckBoxList::eventFilter" as event filter for items view 
        view()->viewport()->installEventFilter(this);
    
    
        // it just cool to have it as defualt ;)
        view()->setAlternatingRowColors(true);
         }
    
    
    CheckBoxList::~CheckBoxList()
    {
        ;
    }
    bool CheckBoxList::eventFilter(QObject *object, QEvent *event)
    {
        // don't close items view after we release the mouse button
        // by simple eating MouseButtonRelease in viewport of items view
        if(event->type() == QEvent::MouseButtonRelease && object==view()->viewport()) 
        {
            return true;
        }
        return QComboBox::eventFilter(object,event);
    }
    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;
    }
    

    【讨论】:

    • 您如何知道哪些复选框被选中以便生成显示文本?
    • 当视图中只有 1 个复选框时,您的代码似乎有问题。它似乎忽略了鼠标点击并且不检查。我认为这与您的组合框中的 eventFilter 有关。有什么修复吗?
    • QComboBox 派生此类是错误的,因为您无法正确覆盖不再相关的功能,因为有问题的功能不是 virtual
    【解决方案2】:

    另一种方法是为按钮设置带有可检查操作的菜单,正如我所展示的 here.
    或者你可以改变combo的选择模式,控制弹窗的隐藏和显示,如图here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 2020-11-14
      • 2013-09-15
      • 2013-09-17
      • 1970-01-01
      相关资源
      最近更新 更多