【问题标题】:QCombobox custom behaviour with modelQCombobox 自定义行为与模型
【发布时间】:2019-06-28 14:18:55
【问题描述】:

我有一个返回 DisplayRole 字符串的模型。我为我的 QCombobox 做了 setModel。但我需要放置“setSeparator”而不是一些值。所以不必显示元素本身,它必须用作放置分隔符的标记。 这是因为我不能对我的 QCombobox 使用 setSeparator 函数,使用 setmodel 时它没有效果。

如何用行为覆盖?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    首先,您需要从模型中返回一个分隔符。对我来说最好使用特殊角色作为分隔符,但也可以使用字符串标记。

    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);
    

    【讨论】:

    • 非常感谢。我几乎像您一样得出了解决方案,但仍然很少有误解。所以你的帖子解决了一天)))
    猜你喜欢
    • 2018-10-28
    • 2014-11-02
    • 2021-12-09
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多