I want to set some style properties via setStylesheet, e.g. a border
label.setStylesheet("border: 1px solid white;");
After that my label has a white border but all font properties set in the parent widget (QDesigner) are ignored!
qDebug() << label->font().family();
qDebug() << label->font().rawName();
both print the right font family but this is not applied after the setStylesheet function was called.
Same thing with colors. Colors set via QPlatte in the Designer are not used if I set some other properties via setStylesheet().
I don't know but it seems that we should not mix both technologies or I am doing something wrong here.
Unfortunately, setting one property in the style sheet of a widget usually results in all styles properties needing to be set, as well as breaking inheritance for any of those properties. I couldn't reproduce the font inheritance issue in my own environment (what version of Qt are you using?), but the following code should get you around this issue.
// Get the color of the label's parent (this).
QColor color = this->palette().windowText().color();
QString colorString = "rgb(" +
QString::number( color.red() ) + "," +
QString::number( color.green() ) + "," +
QString::number( color.blue() ) + ")";
// Get the Font of the label's parent (this).
QFont font = this->font();
// Set the Font and Color.
label->setFont( font );
label->setStyleSheet( "color: " + colorString + "; border: 1px solid white;" );
Personally, I try to keep all of my styling in either the form editor for specific form object styles, or in a style sheet that is loaded in at the top level, much like CSS for a web page.
Related
I've created a small text editor window that allows the user to change some basic properties of a text area included within the screen. Two of the options available to change the properties of the textArea are font color and font color fill, which are both handled by separate color pickers.
I ran into an issue when testing these buttons using the setStyle method that only one property could be saved at a time. Example, if text color was set to BLUE, and afterwards fill color was set to YELLOW, text color would not remain blue, but instead revert back to its default defined in the stylesheet (black).
To fix this problem, I have created the following method;
private void updateTheSyle()
{
this.textArea.setStyle("-fx-control-inner-background: " + toRgbString(this.colorPickerFill.getValue()) +
"; -fx-text-fill: " + toRgbString(this.colorPickerFont.getValue()) + ";");
}
The toRgbString() method is also called, this is simply passing the user input from the color picker into a string such that the setStyle method can pass the correct parameters to the stylesheet.
This solution does work, as it enables me to change both the fill and the font color without reverting back to default upon selection. However, my program includes more than just fill and font color, which will contribute to a far longer setStyle statement as these options are added.
TLDR: Is there a way to edit a single style included in a CSS stylesheet without affecting the other styles in a given class?
For your first question (longer setStyle statement), If we take into account that the style is defined by a String, and it takes a whole set of details to provide for a single Style, so why not use a List<String> :
List<String> example = new ArrayList<>();
String style = "";
//For example if you use 2 textField to get the (value) and (type):
example.add("-fx-"+textFieldType+":"+textFieldValue + "; ");
//To gather all the properties in a single string
for(String property: example){
style += example;
}
yourNode.setStyle(style);
I do not know if there is a better approach but it works, good luck !
Edit :
I think this tip answers your second question:
private void Update(String type,String newValue){
for(int i = 0; i < example.size(); i++){
if(example.get(i).contains(type)){
example.set(i, "-fx-"+type+":"+newValue + "; ");
//Here you add a (break;) to not alter the other similar styles !
}
}
//Here you use a loop to update the new elements changed
}
I hope this will help you solve your problem !
When input comes in on a tab that is not active, the text for the tab changes to a purple color. What CSS selectors do I need to use to change this?
I am using a custom stylesheet in Konsole to change how the tabs look, but can't figure out how to change this one value. This page makes no mention of it.
I'm using Konsole 2.13.2(KDE 4.13.3) on Xubuntu 14.04(XFCE).
As of today, this tab-activity color appears to be set by
void TabbedViewContainer::setTabActivity(int index , bool activity)
{
const QPalette& palette = _tabBar->palette();
KColorScheme colorScheme(palette.currentColorGroup());
const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color();
const QColor normalColor = palette.text().color();
const QColor activityColor = KColorUtils::mix(normalColor, colorSchemeActive);
QColor color = activity ? activityColor : QColor();
if (color != _tabBar->tabTextColor(index))
_tabBar->setTabTextColor(index, color);
}
in konsole's src/ViewContainer.cpp and is therefore probably beyond the reach of a custom stylesheet configured in Konsole.
Note how KColorScheme::ActiveText is mixed with normalColor. You can have some influence over the color by changing the "Active Text" color in KDE System Settings -> Color -> Colors tab -> Active Text. Konsole has to restarted for the changes to take effect.
I want to change the QGroupBox's title to be bold and others keep unchanged. How to change the font of a QGroupBox's title only?
Font properties are inherited from parent to child, if not explicitly set. You can change the font of the QGroupBox through its setFont() method, but you then need to break the inheritance by explicitly resetting the font on its children. If you do not want to set this on each individual child (e.g. on each QRadioButton) separately, you can add an intermediate widget, e.g. something like
QGroupBox *groupBox = new QGroupBox("Bold title", parent);
// set new title font
QFont font;
font.setBold(true);
groupBox->setFont(font);
// intermediate widget to break font inheritance
QVBoxLayout* verticalLayout = new QVBoxLayout(groupBox);
QWidget* widget = new QWidget(groupBox);
QFont oldFont;
oldFont.setBold(false);
widget->setFont(oldFont);
// add the child components to the intermediate widget, using the original font
QVBoxLayout* verticalLayout_2 = new QVBoxLayout(widget);
QRadioButton *radioButton = new QRadioButton("Radio 1", widget);
verticalLayout_2->addWidget(radioButton);
QRadioButton *radioButton_2 = new QRadioButton("Radio 2", widget);
verticalLayout_2->addWidget(radioButton_2);
verticalLayout->addWidget(widget);
Note also, when assigning a new font to a widget, "the properties from this font are combined with the widget's default font to form the widget's final font".
An even easier approach is to use style sheets - unlike with CSS, and unlike the normal font and color inheritance, properties from style sheets are not inherited:
groupBox->setStyleSheet("QGroupBox { font-weight: bold; } ");
The answer above is correct.
Here are a couple extra details which may be helpful:
1) I learned in
Set QGroupBox title font size with style sheets
that the QGroupBox::title doesn't support font properties, so you CAN'T set the title font that way. You need to do it as above.
2) I find the setStyleSheet() method to be a bit more "streamlined" than using QFont. That is, you can also do the following:
groupBox->setStyleSheet("font-weight: bold;");
widget->setStyleSheet("font-weight: normal;");
I searched for this question coming from PyQt5 not Qt directly, so here is my answer in python hoping that it will help others in the same situation as me.
# Set the QGroupBox's font to bold. Unfortunately it transfers to children widgets.
font = group_box.font()
font.setBold(True)
group_box.setFont(font)
# Restore the font of each children to regular.
font.setBold(False)
for child in group_box.children():
child.setFont(font)
At least with Qt 4.8, setting the font to 'bold' with style sheets didn't work for me.
A somewhat simpler version to set all children widgets to normal font which works also when you are using the Qt designer (ui files):
QFont fntBold = font();
fntBold.setBold( true );
ui->m_pGroup1->setFont( fntBold );
auto lstWidgets = ui->m_pGroup1->findChildren< QWidget* >();
for( QWidget* pWidget : lstWidgets )
pWidget->setFont( font() );
I am trying to make a QListWidget with QListWidgetItems.
I want the QListWidgetItems to have a border and a background e.g. Green.
The selected item should have another background e.g. Red.
I tried to create the border with a stylesheet. This works fine.
But I an not able to set the individual background color of the items anymore.
Below piece of code I am using
QListWidget *listWidget = new QListWidget();
QListWidgetItem *wi = new QListWidgetItem;
wi->setText("greenbg");
wi->setBackgroundColor(Qt::green);
listWidget->addItem(wi);
listWidget->setStyleSheet( "QListWidget::item {border-style: solid; border-width:1px; border-color:black;}");
QListWidgetItem *wi2 = new QListWidgetItem;
wi2->setText("redbg");
wi2->setBackgroundColor(Qt::red);
listWidget->addItem(wi2);
listWidget->show;
This shows the list transparent. When the setStyleSheet line is removed the items are green and red.
What am I doing wrong or is it not possible and should I use a custom Widget?
CSS is overriding the values you set there. Try to set the background color also in CSS:
listWidget->setStyleSheet(
"QListWidget::item {"
"border-style: solid;"
"border-width:1px;"
"border-color:black;"
"background-color: green;"
"}"
"QListWidget::item:selected {"
"background-color: red;"
"}");
Notice that you can specify different style for different states (ie. that item is selected).
Example and other information here.
I have a widget class 'BlockWidget' subclass of QLabel, in the ctor I set its qss qss_1, and I want animated effect that when the mouse move on it, it will change its background-color, so I set its qss qss_2, but it seems not working... My code like this:
BlockWidget::BlockWidget(const QString &objname)
{
this->setObjectName(objname);
setAlignment(Qt::AlignCenter);
setStyleSheet(tr("BlockWidget#%1{color:white; background-color: gray; font-size:18px;"
"font-family:'Consolas';}").arg(objectName()));
}
void BlockWidget::mouseMoveEvent(QMouseEvent *ev)
{
setStyleSheet(tr("BlockWidget#%1{color:white; background-color: blue; font-size:18px;"
"font-family:'Consolas';}").arg(objectName()));
repaint();
}
And I have a mainwindow, I instantiated 81 instances of BlockWidget. when my mouse move to one of them, nothing happened. but if I click on it some times, it do change its qss style(its background turns blue)
As stated by the documentation, mouse move events are only sent when you click, drag or release the buttons, if mouse tracking isn't enabled for the widget.
You can detect the mouse entering and leaving the labels by redefining QWidget::enterEvent and QWidget::leaveEvent in your BlockWidget class.
Or you can simply use the :hover QSS pseudo-state without having to redefine any mouse related function:
setStyleSheet("BlockWidget {"
" color:white;"
" background-color: gray;"
" font-size:18px;"
" font-family:'Consolas';"
"}"
"BlockWidget:hover {"
" background-color: blue;"
"}");
PS:
According to Qt style sheet documentation, QLabel doesn't support the :hover pseudo-state, however changing the background or the borders seems to be working fine.
Since your BlockWidget widgets don't have themselves BlockWidget children, and because you set the stylesheet individually to all of them, it should be safe to omit the object name from the QSS selector.
You must enable mouse tracking for your widget http://qt-project.org/doc/qt-4.8/qwidget.html#mouseTracking-prop