QT - CSS: decoration on focus
The highlighted rectangle may be the QStyle::PE_FrameFocusRect
styling. The only way to get rid of it is by implementing a custom style. Fortunately, Qt provides a way to implement just a proxy, which uses another style in the general case. For the focus rectangle you'd implement:
class Style_tweaks : public QProxyStyle
{
public:
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const
{
/* do not draw focus rectangles - this permits modern styling */
if (element == QStyle::PE_FrameFocusRect)
return;
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
};
qApp->setStyle(new Style_tweaks);
How to change the Focus color(Highlight color) in Qt pushbuttons?
Use stylesheets:
QPushButton:focus:pressed{ background-color: some_colour; }
QPushButton:focus{ background-color: some_other_colour; }
You can either use the Qt Creator to add the styles to your button or load them inside your code by calling setStyleSheet("...")
on your button.
Qt4 Stylesheets and Focus Rect
The focus rect around the QTreeView widget itself turns out to be a Mac styling feature. This turns it off per widget:
tree.setAttribute(Qt.WA_MacShowFocusRect, 0)
Style QtComboBox, QListViewItem - Set text padding
It is possible to remove the dotter border using only CSS by setting undocumented property outline
:
QComboBox QAbstractItemView {
outline: none;
}
QListView
also can be used in this selector. QAbstractItemView
is used in this example, since it is a base class of QListView
. Note that this property is set not per item but for the external container of items.
There are other ways to remove the dotted border using coding, for example QT - CSS: decoration on focus
It looks that it is needed to change the code to have better flexibility with padding. QComboBox
uses its own private implementation of QAbstractItemDelegate
based on QItemDelegate
. However, other controls use QStyledItemDelegate
(QStyledItemDelegate
vs. QItemDelegate
). That is why CSS selectors for items (QListView::item
) does not have an effect on QComboBox
items.
There is the following comment with explanation in the source code:
Note that this class is intentionally not using
QStyledItemDelegate
Vista does not use the new theme for combo boxes and there might be
other side effects from using the new class
If the above comment is not a problem, it is possible to set QStyledItemDelegate
to QComboBox
objects:
QComboBox *combobox = new QComboBox;
combobox->setItemDelegate(new QStyledItemDelegate(combobox));
Now, the property selection-background-color
is not needed anymore. It is possible to customize ::item
:
QComboBox QAbstractItemView::item {
border: none;
padding-left: 5px;
}
QComboBox QAbstractItemView::item:selected {
background: rgb(47, 175, 178);
padding-left: 5px;
}
Note that to set padding it is also needed to provide, for example, at least border or background property together with padding. Otherwise the padding property is not taken into account.
The selector ::item:selected
is used instead of :hover
, since items can be also selected by keyboard.
Although it is documented that it is possible to set custom view for QComboBox
it is not so simple. QComboBox
can also have separator items. The above solution works fine if there are no separator items in QComboBox
. To handle separators the item delegate should also know about them.
It is possible to subclass QStyledItemDelegate
and copy required functions from Qt private implementation of QComboBoxDelegate
. That solution is not very nice. It may be non-portable with new Qt versions. The implementation of QComboBoxDelegate
in Qt5 is not compatible with Qt4. However, Qt5 can work with Qt4 implementation, so this class can be taken from Qt4. The QItemDelegate
base class is replaced by 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;
};
It makes sense to subclass QComboBox
to use ComboBoxDelegateStyled
:
class ComboBoxStyled : public QComboBox
{
public:
explicit ComboBoxStyled(QWidget *parent = 0) : QComboBox(parent) {
setItemDelegate(new ComboBoxDelegateStyled(this, this));
}
};
Now the class ComboBoxStyled
can be used instead of QComboBox
. It supports combo box separator drawing and also it supports CSS for ::item
.
Similar solution for customizing QComboBox
separator: how to add stylesheet for separator in QCombobox
PyQt
The above behavior is valid for PyQt. It is possible to remove dotted border using outline
and to set styled item delegate to customize CSS ::item
:
styledComboBox = QtGui.QComboBox()
delegate = QtGui.QStyledItemDelegate()
styledComboBox.setItemDelegate(delegate)
In such case the combo box separator is displayed as a regular item without text.
It is also possible to create custom delegate to handle separators.
QPushButton visual issue
Found the solution. It turned out to be very simple.
The issue was indeed caused by the button receiving focus. All I needed to do is set the button's focusPolicy
attribute to NoFocus
. It can be done either in QtDesigner:
or in the code:
ui.okButton->setFocusPolicy(Qt::NoFocus);
After it's done, the clicks on the button will not cause it to get focus, and the appearance will not change.
Related Topics
How to Write a Media Query for Gmail
Why Doesn't Inset Box-Shadow Work Over Images
Background Color of Tabs in Shiny Tabpanel
Which Are the Most Important Media Queries to Use in Creating Mobile Responsive Design
Why Is Backface-Visibility Hidden Not Working in Ie10 When Perspective Is Applied to Parent Elements
Vertically and Horizontally Centering Text in Circle in CSS (Like iPhone Notification Badge)
In CSS, Differencebetween Cascading and Inheritance
Allowed Characters for CSS Identifiers
Stacking Order of Elements Affected by Opacity
How to Vertically Center an Image Inside of a Div Element in HTML Using CSS
How to Create the Masonry Effects with Just Bootstrap 3 Grid System and CSS
Django Forms and Bootstrap - CSS Classes and <Divs>
Add Ellipses to Overflowing Text in Svg