如何使QComboBox的文本加粗,而不是列表项?

时间:2018-01-30 16:30:09

标签: c++ qt qcombobox qtstylesheets

我们在UI中有一个长期惯例,即项目在更改后以粗体显示但尚未提交更改。奇怪的是,到目前为止我们还没有使用任何组合框,但我现在有一个用途,需要实现这种行为。因此,我需要以编程方式以粗体显示(以及稍后以非粗体显示)由关闭的组合框显示的文本。但是,我不想在弹出窗口中加粗整个项目列表。如果这更容易,我可以接受列表中所选项目的加粗。

我已经看到了很多答案,但通常会尝试修改列表项而不是按钮。我尝试过大多数变体;不幸的是,我没有记录我的尝试。对于它的价值,我的代码目前看起来像:

myCombo->setStyleSheet(
    "QComboBox {font-weight: bold;} "
    "QComboBox QAbstractItemView::item {font-weight: normal;}"
);

这会将按钮变为粗体,但也会显示列表项。当我将正常权重仅应用于QAbstractItemView而没有::item时,以及当我尝试基于:open:closed的不同技术时,会出现相同的行为{1}}。

我会说我对Qt来说还不够新鲜。我在Fedora 26上使用Qt5,但将部署到CentOS 7。

1 个答案:

答案 0 :(得分:1)

似乎在QComboBox中设置字体样式会覆盖视图(并且它不应该恕我直言)。

但是,当我尝试通过这种方式明确地将视图设置为组合框时:

  view = new QListView();
  myCombo->setView(view);
OP发布的样式表突然起作用了。

顺便说一句,新视图与原始视图不同(例如有白色背景等),我猜OP对此并不满意。当然,人们可以继续设计风格,但人们宁愿选择一个随时可用的视图,而且风格一致。

检查默认QComboBox视图:

QComboBox * combo = new QComboBox();
qDebug() << combo->view();

yelds this:

QComboBoxListView(0x2091880)

所以,有一个特定的QComboBoxListView类,它在文档中找不到,并且在 qcombobox_p.h 中定义,而不是一个可以包含的文件,真的,但是在至少我们可以在viewOptions重写方法中了解问题的来源:

    QStyleOptionViewItem option = QListView::viewOptions();
    option.showDecorationSelected = true;
    if (combo)
        option.font = combo->font(); // <--- here
    return option;

combo是指向QComboBox的私有指针,在构造中初始化:

    QComboBoxListView(QComboBox *cmb = 0) : combo(cmb) {}

将始终使用自己的视图选项字体覆盖。

让我们拥有QComboBoxListView课程的副本,进行编辑和重命名:

<强> comboitemview.h

#ifndef COMBOITEMVIEW_H
#define COMBOITEMVIEW_H

#include <QListView>
#include <QComboBox>

class ComboItemView : public QListView
{
    Q_OBJECT

    QComboBox * _box;
public:
    ComboItemView(QComboBox *box);
protected:
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
    QStyleOptionViewItem viewOptions() const;
};

#endif // COMBOITEMVIEW_H

<强> comboitemview.cpp

#include "comboitemview.h"

#include <QPaintEvent>
#include <QPainter>

ComboItemView::ComboItemView(QComboBox * box = 0) : _box(box){}

void ComboItemView::paintEvent(QPaintEvent *event)
{
    if (_box)
    {
        QStyleOptionComboBox opt;
        opt.initFrom(_box);
        opt.editable = _box->isEditable();
        if (_box->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, _box))
        {
            QStyleOptionMenuItem menuOpt;
            menuOpt.initFrom(this);
            menuOpt.palette = palette();
            menuOpt.state = QStyle::State_None;
            menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
            menuOpt.menuRect = event->rect();
            menuOpt.maxIconWidth = 0;
            menuOpt.tabWidth = 0;
            QPainter p(viewport());
            _box->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
        }
    }
    QListView::paintEvent(event);
}

void ComboItemView::resizeEvent(QResizeEvent *event)
{
    resizeContents(viewport()->width(), contentsSize().height());
    QListView::resizeEvent(event);
}

QStyleOptionViewItem ComboItemView::viewOptions() const
{
    QStyleOptionViewItem option = QListView::viewOptions();
    option.showDecorationSelected = true;
    return option;
}

最后用它来设置视图字体的样式:

    myCombo->setView(new ComboItemView(myCombo));
    myCombo->setStyleSheet(
                "QComboBox {font-weight: bold;} "
                "QComboBox QAbstractItemView {font-weight: normal;}"
    );