QT 自定义ComboBox,实现下拉框文本颜色设置

最近在做项目中遇到需求,在下拉框中,文本需要设置不同的颜色,遂网上了解了一番后,得出以下代码,可以完美实现效果,现分享出来!

1.实现效果

2.自定义类

colorcombobox.h

#ifndef COLORCOMBOBOX_H
#define COLORCOMBOBOX_H

#include <QComboBox>
#include <QWidget>

// 自定义ComboBox类,用于控制当前项颜色
class ColorComboBox : public QComboBox {
    Q_OBJECT
public:
    explicit ColorComboBox(QWidget *parent = nullptr);

    /// 添加带颜色的项
    void addColorItem(const QString &text, const QColor &color = Qt::black);


private slots:
    /// 更新当前项颜色
    void updateCurrentItemColor(int index);


protected:
    // 重写paintEvent以绘制当前项
    void paintEvent(QPaintEvent *e) override;
};

#endif // COLORCOMBOBOX_H

colorcombobox.cpp

#include "colorcombobox.h"
#include "config/appinfo.h"



// 自定义委托类
class CustomColorDelegate : public QStyledItemDelegate {
public:
    CustomColorDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) { }
    ~CustomColorDelegate() override { }

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
        QStyleOptionViewItem opt = option;
        initStyleOption(&opt, index);

        // 获取该项的颜色
        QVariant colorVar = index.data(Qt::UserRole + 1); // 使用UserRole+1存储颜色
        QColor textColor = colorVar.isValid() ? colorVar.value<QColor>() : Qt::black;

        // 检查是否选中
        if (opt.state & QStyle::State_Selected) {
            painter->fillRect(opt.rect, opt.palette.highlight().color());   // 使用高亮颜色填充背景
            painter->setPen(opt.palette.highlightedText().color());         // 设置高亮文本颜色
        } else {
            painter->fillRect(opt.rect, Qt::white); // 使用白色填充背景
            painter->setPen(textColor);             // 设置自定义文本颜色
        }

        // 绘制文本
        painter->drawText(opt.rect.adjusted(5, 0, 0, 0),
                          Qt::AlignVCenter | Qt::AlignLeft,
                          opt.text);
    }
};



ColorComboBox::ColorComboBox(QWidget *parent) : QComboBox(parent) {
    // 设置自定义委托
    setItemDelegate(new CustomColorDelegate(this));

    // 连接信号,当选择变化时更新当前项颜色
    connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ColorComboBox::updateCurrentItemColor);
}



void ColorComboBox::addColorItem(const QString &text, const QColor &color) {
    addItem(text);
    setItemData(count() - 1, color, Qt::UserRole + 1); // 存储颜色
    setItemData(count() - 1, color, Qt::ForegroundRole); // 兼容旧代码

    // 如果这是第一项,设置当前颜色
    if (count() == 1) {
        setCurrentIndex(0);
    }
}



void ColorComboBox::updateCurrentItemColor(int index) {
    if (index < 0) return;

    // 获取当前项的颜色
    QVariant colorVar = itemData(index, Qt::UserRole + 1);
    if (colorVar.isValid()) {
        QColor color = colorVar.value<QColor>();

        // 设置当前项的颜色(通过样式表)
        setStyleSheet(QString(
            "QComboBox {"
            "   color: %1;"
            "   background-color: white;"
            "   border: 1px solid #ccc;"
            "   border-radius: 4px;"
            "   padding: 5px;"
            "}"
            "QComboBox::drop-down {"
            "   border: none;"
            "}"
        ).arg(color.name()));
    }
}


void ColorComboBox::paintEvent(QPaintEvent *e) {
    QComboBox::paintEvent(e);

    // 如果需要,可以在这里添加自定义绘制代码
}

3.使用

// 创建颜色ComboBox
ColorComboBox *colorCombo = new ColorComboBox(this);
colorCombo->addColorItem("", Qt::black);
colorCombo->addColorItem("合格", QColor("#32CD32"));    // 石灰绿色
colorCombo->addColorItem("不合格", Qt::red);            // 红色

// 设置初始选择
colorCombo->setCurrentIndex(0);
好的,下面是用Qt自定义表头实现表头下拉框的步骤: 1.创建一个自定义的表头类,继承自QHeaderView。 2.在自定义表头类的构造函数中,创建一个QComboBox控件,并将其添加到表头中。例如,可以使用以下代码实现: ``` MyHeaderView::MyHeaderView(Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent) { m_comboBox = new QComboBox(this); m_comboBox->setEditable(true); m_comboBox->setMinimumWidth(100); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboBoxIndexChanged(int))); } void MyHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const { painter->save(); QHeaderView::paintSection(painter, rect, logicalIndex); if (logicalIndex == m_index) { QRect comboBoxRect = rect.adjusted(4, 4, -4, -4); m_comboBox->setGeometry(comboBoxRect); } painter->restore(); } ``` 其中,m_comboBoxQComboBox的指针成员变量,m_index是当前列的索引号。在paintSection()函数中,先调用父类的paintSection()函数,绘制表头。然后根据当前列的索引号,调整QComboBox的位置和大小。 3.重写mousePressEvent()函数,用于判断用户是否点击了QComboBox控件。例如,可以使用以下代码实现: ``` void MyHeaderView::mousePressEvent(QMouseEvent *event) { QHeaderView::mousePressEvent(event); int index = logicalIndexAt(event->pos()); if (index == m_index) { QRect comboBoxRect = sectionViewportPosition(index).adjusted(4, 4, -4, -4); if (comboBoxRect.contains(event->pos())) { m_comboBox->setGeometry(comboBoxRect); m_comboBox->showPopup(); } } } ``` 其中,logicalIndexAt()函数用于获取用户点击的列索引号,sectionViewportPosition()函数用于获取该列的可视位置。 4.在自定义表头类中添加一个设置下拉框选项的函数,例如: ``` void MyHeaderView::setComboBoxItems(const QStringList &items) { m_comboBox->clear(); m_comboBox->addItems(items); } ``` 在该函数中,使用QComboBox的clear()函数清空选项,然后使用addItems()函数添加新的选项。 5.在自定义表头类中添加一个槽函数,用于处理QComboBox的currentIndexChanged()信号。例如: ``` void MyHeaderView::onComboBoxIndexChanged(int index) { emit comboBoxIndexChanged(m_index, m_comboBox->currentText()); } ``` 在该函数中,使用emit关键字发送comboBoxIndexChanged()信号,该信号包含当前列的索引号和QComboBox文本内容。 6.在主程序中,创建自定义表头对象,并将其设置QTableView控件的表头。例如: ``` MyHeaderView *headerView = new MyHeaderView(Qt::Horizontal, ui->tableView); headerView->setComboBoxItems(QStringList() << "Option 1" << "Option 2" << "Option 3"); ui->tableView->setHorizontalHeader(headerView); connect(headerView, SIGNAL(comboBoxIndexChanged(int,QString)), this, SLOT(onComboBoxIndexChanged(int,QString))); ``` 其中,创建自定义表头对象,并设置下拉框选项。然后,将自定义表头对象设置QTableView控件的水平表头。最后,将comboBoxIndexChanged()信号连接到主程序中的槽函数,用于处理用户在下拉框中选择的选项。 以上就是使用Qt自定义表头实现表头下拉框的基本步骤,希望能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值