信息:Qt 4.8,Qt 设计器
我正在努力在组合框下拉菜单上设置文本项的填充。我的理解是整个东西是 QComboBox 小部件,下拉部分是 QListView。但是我不知道使用什么 css 选择器来更改下拉列表中文本项的样式。
我希望悬停项目的背景颜色一直向左延伸,而不是留下 5px 的边距。文本本身排列得很好,只是左边的那个白色间隙让我烦恼。
另外,如果我可以删除突出显示项目周围的虚线边框,我会很棒。
我想我只是没有使用正确的项目选择器。我试过 QListView::item 和 QListViewItem。这是我应用于组合框的 CSS。
QComboBox{
border: none;
background-color: rgb(87, 96, 134);
color: rgb(255, 255, 255);
font-weight: bold;
padding: 5px
}
QComboBox::drop-down{
border: none;
background-color: rgb(87, 96, 134);
color: rgb(255, 255, 255);
font-weight: bold;
padding: 0px;
}
QComboBox::down-arrow{
image: url(:/icons/combobox_down_arrow.png);
padding-right: 5px;
}
QListView{
border: none;
color: rgb(87, 96, 134);
background-color: rgb(255, 255, 255);
font-weight: bold;
selection-background-color: rgb(47, 175, 178);
show-decoration-selected: 1;
margin-left: -10px;
padding-left : 15px;
}
QListView::item:hover{
background-color: rgb(47, 175, 178);
border: none;
}
Run Code Online (Sandbox Code Playgroud)
想法?
可以通过设置未记录的属性仅使用 CSS 来删除点边框outline:
QComboBox QAbstractItemView {
outline: none;
}
Run Code Online (Sandbox Code Playgroud)
QListView也可以用在这个选择器中。QAbstractItemView本例中使用了 ,因为它是 的基类QListView。请注意,此属性不是针对每个项目设置的,而是针对项目的外部容器设置的。
还有其他方法可以使用编码来删除虚线边框,例如QT - CSS:焦点装饰
看起来需要更改代码以在填充方面具有更好的灵活性。使用它自己的基于QComboBox的私有实现。然而,其他控件使用
( vs. )。这就是为什么项目 ( ) 的 CSS 选择器对项目没有影响。QAbstractItemDelegateQItemDelegateQStyledItemDelegateQStyledItemDelegateQItemDelegateQListView::itemQComboBox
源码中有如下注释和解释:
请注意,此类有意不使用
QStyledItemDelegate
Vista 不使用组合框的新主题,并且使用新类可能会产生其他副作用
如果上面的注释没有问题,可以设置QStyledItemDelegate为QComboBox对象:
QComboBox *combobox = new QComboBox;
combobox->setItemDelegate(new QStyledItemDelegate(combobox));
Run Code Online (Sandbox Code Playgroud)
selection-background-color现在,不再需要该财产了。可以定制::item:
QComboBox QAbstractItemView::item {
border: none;
padding-left: 5px;
}
QComboBox QAbstractItemView::item:selected {
background: rgb(47, 175, 178);
padding-left: 5px;
}
Run Code Online (Sandbox Code Playgroud)
请注意,要设置填充,还需要提供例如至少边框或背景属性以及填充。否则,不考虑填充属性。
使用选择器::item:selected代替:hover,因为也可以通过键盘选择项目。
尽管有记录表明可以设置自定义视图,但QComboBox它并不那么简单。QComboBox也可以有分隔项。如果 中没有分隔符项目,上述解决方案可以正常工作QComboBox。为了处理分隔符,项目委托还应该了解它们。
可以QStyledItemDelegate从 的 Qt 私有实现子类化和复制所需的函数QComboBoxDelegate。这个解决方案不太好。对于新的 Qt 版本来说,它可能是不可移植的。Qt5 中的实现QComboBoxDelegate与 Qt4 不兼容。然而,Qt5 可以与 Qt4 实现一起工作,因此这个类可以从 Qt4 中获取。基QItemDelegate类被替换为QStyledItemDelegate:
class ComboBoxDelegateStyled : public QStyledItemDelegate
{
Q_OBJECT
public:
ComboBoxDelegateStyled(QObject *parent, QComboBox *cmb) :
QStyledItemDelegate(parent), mCombo(cmb) {}
static bool isSeparator(const QModelIndex &index) {
return index.data(Qt::AccessibleDescriptionRole).toString() == QLatin1String("separator");
}
protected:
void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
if (isSeparator(index)) {
QRect rect = option.rect;
if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option))
if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(v3->widget))
rect.setWidth(view->viewport()->width());
QStyleOption opt;
opt.rect = rect;
mCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, mCombo);
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const {
if (isSeparator(index)) {
int pm = mCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, mCombo);
return QSize(pm, pm);
}
return QStyledItemDelegate::sizeHint(option, index);
}
private:
QComboBox *mCombo;
};
Run Code Online (Sandbox Code Playgroud)
QComboBox子类化使用是有意义的ComboBoxDelegateStyled:
class ComboBoxStyled : public QComboBox
{
public:
explicit ComboBoxStyled(QWidget *parent = 0) : QComboBox(parent) {
setItemDelegate(new ComboBoxDelegateStyled(this, this));
}
};
Run Code Online (Sandbox Code Playgroud)
现在ComboBoxStyled可以使用该类来代替QComboBox. 它支持组合框分隔符绘制,还支持::item.
自定义分隔符的类似解决方案QComboBox:如何在 QCombobox 中添加分隔符的样式表
pyqt
上述行为对于 PyQt 有效。可以使用删除点边框outline并设置样式项目委托来自定义 CSS ::item:
styledComboBox = QtGui.QComboBox()
delegate = QtGui.QStyledItemDelegate()
styledComboBox.setItemDelegate(delegate)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,组合框分隔符显示为不带文本的常规项目。还可以创建自定义委托来处理分隔符。