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() );
Related
In my QListWidget, there are some items that have non-default background color, I set them like so inside the custom QListWidget class:
item->setBackgroundColor(qcolor); // item is of type QListWidgetItem*
Those non-default colors that I set are distorted by the QListWidget's selection color. See an example:
Items three and four are supposed to be the same color, but they are not since the item four is selected, and thus the result color is a summation of original color and QListWidget's selection (active item?) color.
My question is how to edit or remove that selection color?
I tried inside my QListWidget (in special slot when I want to change the item's background color):
QPalette pal = this->palette();
pal.setColor(QPalette::Highlight, QColor(255,255,255,0));
this->setPalette(pal); // updated
But it did not produce any effect. what am I doing wrong? Is it a correct variable to set? Do I set it up inside QListWidget or inside its delegate?
Update: I tried using stylesheets as pointed by comment/answer, however, it will not be possible to use them for my application, because the items in my rows have 3 states (so I would need to use three colors). E.g., 3 states that correspond to three colors: pink for active, green for inactive and gray for the rest. When using stylesheets, I cannot set the custom property (let's say QListWidget::item[Inactive="true"]) to a single QListWidgetItem, but for the full QListWidget, and therefore it colors all the rows the same color.
Stylesheets were tried for similar problem here, and didn't work, therefore I make conclusion using stylesheets is not the way to go.
The background change method that I used originally works fine for my purpose, but I cannot figure out how to get rid of the default selection color (transparent light blue) which adds to the background color and produces the mixed color.
I think you'd be better served using the style sheets to do this. Here's an example
QListWidget::item
{
background: rgb(255,255,255);
}
QListWidget::item:selected
{
background: rgb(128,128,255);
}
::item indicates the individual items within the QListWidget, while :selected indicates the QListWidgetItems which are currently selected.
To then get the custom background on specific widgets, you could use custom style sheet properties. In your code, call something like this on the widget you want to apply a custom style on:
myList->setProperty( "Custom", "true" );
// Updates the style.
style->unpolish( myList );
style->polish( myList );
Then in your style sheet, define the style for your custom property like so.
QListWidget::item[Custom="true"]
{
background: rgb(128,255,128);
}
I found a suitable solution by using a delegate. So, there is no need to use QPalette; and for my problem the stylesheets will not work. This solution will also work when different rows (QListWidget or QTreeWidget) are needed to be colored in different colors, depending on some state.
The background color is set as described on the question:
item->setBackgroundColor(qcolor); // change color slot inside QListWidget class
In order to define rules how the widget is painted, I re-define the delegate:
class Delegate : public QStyledItemDelegate {};
Then I re-define Delegate's method paint(). There I define how to draw each row of my widget. More specifically, I only call custom drawing when the mouse hovering over an item, or that item is in selected state (those are the conditions when the row is selected by the light blue color which I want to avoid). The code looks like this:
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if((option.state & QStyle::State_Selected) || (option.state & QStyle::State_MouseOver))
{
// get the color to paint with
QVariant var = index.model()->data(index, Qt::BackgroundRole);
// draw the row and its content
painter->fillRect(option.rect, var.value<QColor>());
painter->drawText(option.rect, index.model()->data(index, Qt::DisplayRole).toString());
}
else
QStyledItemDelegate::paint(painter, option, index);
// ...
}
Of course, do not forget to associate the QListWidget with Delegate:
listWidget->setItemDelegate(new Delegate());
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.
I was trying to build a simple application with a QComboBox and a QPushButton. The idea is to populate the QComboBox with a list of all available fonts in the system. When the user selects a font and presses the QPushButton then a QMessageBox appears with the font selected. Now how to do it?
The solution is using the setFont() method of the QMessageBox
QMessageBox *msg = new QMessageBox(QMessageBox::Information, "Message with font",
"This message is in font: " + ui->comboBox->currentText(),
QMessageBox::Ok | QMessageBox::Cancel, this);
QFont font = QFont(ui->comboBox->currentText());
msg->setFont(font);
msg->exec();
Where combobox is QComboBox used.
You can use basic HTML markups when setting the text to your message box label. The markup supported by QLabel includes <font>.This method also allows more versatile formatting.
As before suggested you could use styles in your Html blocks (in my example add style to the paragraphs):
QMessageBox.about(
self,
"About",
"<font>"
"<p style='font-family: Terminal'>An simple app.</p>"
"<p style='font-family: Georgia, 'Times New Roman'>- PyQt</p>"
"<p>- Qt Designer</p>"
"<p>- Python3</p>",
)
Results in:
QMessageBox
I have a QListView containing QStandardItems . How to set stylesheet for a single item in the Qlistview based on the QModelIndex acquired?
If you use QListWidget instead of QListView, you can call QListWidget::setItemWidget() and you can customize how individual items look by applying a stylesheet to the items that you add. You need to make sure that your item widget class inherits from QWidget and you can apply styles to the widget using QSS like so in your constructor:
setStyleSheet("WidgetItem:pressed { background-color: #444444; }");
Here's a reference to QSS: http://qt-project.org/doc/qt-4.8/stylesheet-examples.html
I still see the Widget-classes documented in Qt Documentation for Qt 5.7 -
Qt Widgets Widgets Classes.
Reference: http://doc.qt.io/qt-5/widget-classes.html
There seems to be no way to set a stylesheet in the Model-View conecpt. But what exist is the FontRole. If you want to make an entry bold or italic or change the size then the FontRole can do that. If you want to change the color then you have to find some other solution.
Here is an example to make certain entries bold in python:
def data(self, index, role=QtCore.Qt.DisplayRole):
# use parent class to get unaltered result
res = super().data(index, role=role)
if role == QtCore.Qt.FontRole:
# modify FontRole
if index.row() = 3:
# row number 3 should be bold
if res is None:
# parent class didn't return a QFont so make one
res = QtGui.QFont()
# set bold attribute in font
res.setBold(True)
return res
The above data() method sets the 4th row bold (rows are counted from 0). I leave translating to C++ to the reader.
Here is a small snippet of my code, I don't know why but Qt is ignoring the css.
QTextDocument *mTextDocument = new QTextDocument(0);
QTextEdit *textEdit = new QTextEdit(0);
mTextDocument->setDefaultStyleSheet(QString::fromUtf8("body{background-color: rgb(0,111,200);}"));
QTextCursor *_cursor = new QTextCursor(mTextDocument);
textEdit->setDocument(mTextDocument);
_cursor->insertBlock();
_cursor->insertHtml("<html><body><p>Hello world</p></body></html>");
textEdit->show();
I'm using Qt 4.8.
Your document already has html and body tags, so they are simply ignored when they are found in insertHtml.
If you were using QTextEdit::setHtml, they would be new elements and the default stylesheet would be applied to them.