QComboBox的下拉框间隔和多种样式设置浅析

1,197 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

摘要

QComboBox作为QT程序员最为常用的控件,但是针对于同一qss文件设置两种肤色以及下拉框与combobox存在间距的问题,还是比较晦涩的,希望本文可以帮助大家解惑。

背景

UI同事设计出的设计图要求QComboBox的下拉菜单和box之间存在8px的间隔,同时具备深色和浅色两种状态。

设计样式.jpg

## 技术方案 自定义CXYComboxBox,CXYComboxBox继承自QComboBox,同时,将CXYComboxBox Ui文件指定为QComboBox类型,此时CXYComboxBox不仅UI 状态与QComboBox一样,也可以应用QComboBox的所有函数,使用自定义的CXYComboBox与使用QComboBox别无二致,方便且高效, ## 问题 当前的技术方案无法满足: - 控件支持深色、浅色两种样式, - 下拉框与combobox之间存在间距 针对这两个问题,做了些技术思考,将结果总结如下. ## 解决方案 ### 欲解决问题:同一个qss文件支持控件的两种样式 - 前置知识:qss支持针对不同的属性,设置不同的样式,例如依据语言属性给QLabel设置不同的字体颜色,如下 ``` QLabel[language="chinese"]{ color:red; }

QLabel[language="english"]{ color:red; }

- 方案  
1.   自定义控件类,并设置颜色属性    
借鉴属性的方法,为自定义控件CXYComboxBox设置不同的属性,为匹配更多的色系状态,笔者在实现时使用QString类型的属性color,当然,由于目前仅有浅色、神色两种样式,也可以通过bool型属性isBlack来区分深色和浅色。这里贴出笔者的实现方式
```cpp
//头文件中关键部分,无关项未列出
    Q_PROPERTY(QString color READ currentColor WRITE setCurrentColor)
public:
    QString currentColor()const;
    void setCurrentColor(const QString& color);
private:
    QString color{"white"};//默认为白色


//cpp文件,XXXX为自定义控件的类名
QString XXXX::currentColor() const
{
    return color;
}

void XXXX::setCurrentColor(const QString& color)
{
    this->color = color;
}
  1. 在QSS文件中针对控件的不同属性设置不同的样式,以下为示例
CXYComboxBox[color="black"]{
	    background:red;
        padding-left:8px;
        color:red;
}

CXYComboxBox[color="white"]{
	background:green;
        padding-left:8px;
        color:green;
}

与解决问题:combobox和下拉框之间设置8px的间隔

思路:

  • 方案1:通过qss实现,经尝试,没能找到方法(如果有朋友有方法请不吝赐教)
  • 方案2:分析QCombobox的实现方法,在弹出下拉菜单时执行的什么函数,而后将其重写(override)下 最终,笔者在通过方案2实现。具体代码如下:
//头文件
protected:
    virtual void showPopup() override;
    virtual void hidePopup() override;


//.cpp文件
void CXYComboxBox::showPopup()
{
    QComboBox::showPopup();
    QWidget *popup = this->findChild<QFrame*>();
    if(popup != NULL)
    {
        popup->move(popup->pos().x(),popup->pos().y() + m_popup_gap);//m_popup_gap为间距值
        popup->setStyleSheet("QFrame{border:none;}");
    }
}

void CXYComboxBox::hidePopup()
{
    QComboBox::hidePopup();
}