Changing QCheckBox text color - c++

I found the same question there:
how to change QCheckBox text label color in Qt?
But unfortunately, none of it work for me on a mac.
On Linux and Windows, by default the text of a QWidget (QLabel, QCheckBox, QRadioButton) is white.
On the mac, it's black. Unfortunately this cause issues in my screen as the text is unreadable (I have black background)..
I have derived the QCheckBox class so in the constructor you get:
class MPUBLIC MythCheckBox: public QCheckBox
{
Q_OBJECT
public:
MythCheckBox(QWidget *parent = 0, const char *name = "MythCheckBox")
: QCheckBox(parent)
{
setObjectName(name);
#ifdef Q_OS_MAC
// setStyleSheet("QCheckBox { color : white; }; QCheckBox::indicator { color:black; }");
QPalette p = palette();
p.setColor(QPalette::WindowText, Qt::white);
setPalette(p);
#endif
};
If I use stylesheets like:
setStyleSheet("QCheckBox { color : white; }; QCheckBox::indicator { color:black; }");
then my text is white as I want, but the checkmark itself becomes invisible...
If I use the 2nd method:
QPalette p = palette();
p.setColor(QPalette::WindowText, Qt::white);
setPalette(p);
The checkbox text does become white, and the checkmark itself is still black, it looks like it works.
But if I ever move the focus to the QCheckBox, the text becomes black again, and it will remain black forever.
I tried also:
QPalette p = palette();
p.setColor(QPalette::Active, QPalette::WindowText, Qt::white);
p.setColor(QPalette::Inactive, QPalette::WindowText, Qt::white);
setPalette(p);
Mind you, I only get this weird behavior on the mac; if I try the same code in Linux (with different colors like red), then everything behaves like I want it to.
Any ideas on how to change the color of a QCheckBox's text, and only the text?

For some widgets you have to disable a native look (appearance). For example QPushButton (http://doc.qt.io/qt-4.8/stylesheet-reference.html). So, for checkbox you can try to set borders. So checkbox's style looks like:
QCheckBox {
border: none;
color: white;
}
Works for me.

Related

Changing Background color of QCheckBox

I want to have a checkbox with the following style:
For that purpose I have created the follow stylesheet:
QCheckBox { background-color : cyan; }
QCheckBox::indicator { width : 20px; height : 20px; }
sadly the result was not was I expected, here is what I get:
But I want to have all background with the color cyan.
I have checked the Qt Documentation About StyleSheet and have also also checked some old questions, but none of the has served me. When I added QCheckBox::indicator{ background-color : cyan; } the button became all cyan (like on the first image on the state unchecked) on checked and unchecked states. Neither adding other proprieties like border helped me.
I also tried to use QPalette instead, but never changed.
Here is my code:
QWidget* w = new QWidget();
QCheckBox* cb = new QCheckBox(w);
cb->setFixedSize(20, 20);
cb->setStyleSheet(QString("QCheckBox { background-color : cyan; }") + '\n' +
"QCheckBox::indicator { width : 20px; height : 20px; border : }");
w->show();
EDIT 28/09/2020
I have recently figured out that the style of the application has influence on it. I was using the Breeze style, changing to Fusion style made it work as expected. The only problem is that it requires change the theme of the application itself. Anyway, here is the code sample in case it helps anyone:
#include <QApplication>
#include <QWidget>
#include <QCheckBox>
int main(int argc, char** argv)
{
QApplication a(argc, argv);
qApp->setStyle(QStyleFactory::create("Fusion"));
QWidget* w = new QWidget();
QCheckBox* cb = new QCheckBox(w);
cb->setFixedSize(20, 20);
cb->setStyleSheet(QString("QCheckBox { background-color : cyan; }") + '\n' +
"QCheckBox::indicator { width : 20px; height : 20px; border : }");
w->show();
}
I did not solve my problem using the stylesheet commands, I actually think that it is not possible SOURCE.
Anyway, I was I able to achieve my goals using one image for the checked state and another one for the unchecked state as follow.
QWidget* w = new QWidget();
QCheckBox* cb = new QCheckBox(w);
cb->setFixedSize(20, 20);
cb->setStyleSheet("QCheckBox::indicator { width : 20; height : 20; }\n"
"QCheckBox::indicator::unchecked { image : url(/path/**/unchecked.png); }\n"
"QCheckBox::indicator::checked { image : url(/path/**/checked.png); }");
w->show();
Probably
QCheckBox::indicator:unchecked {background-color : cyan;});
is what you wanted to see.
Edit: Too late

How to set a custom widget's background color and border width?

I have a custom widget whose parent is yet another custom widget. I am able to set the background color of the parent custom widget using QPalette and it works fine. But I am unable to set the child custom widget's border color using both QPalette and stylesheet.
This is how I set my parent custom widget's background color:
QPalette pal = parentCustomWidget->palette();
QColor color = {226, 208, 208};
pal.setColor (QPalette::Background, color);
parentCustomWidget->setAutoFillBackground (true);
parentCustomWidget->setPalette (pal);
parentCustomWidget->show();
I referred several SO posts/answers for setting background color to custom widget, but I am unable to set it. This is how I set my childCustomWidget's color:
Approach1:
QPalette pal = childCustomWidget->palette();
QColor color = {204, 231, 47};
pal.setColor (QPalette::Background, color);
childCustomWidget->setAutoFillBackground (true);
childCustomWidget->setPalette (pal);
Approach2:
childCustomWidget->setStyleSheet ("*{border-width:" +
BorderThickness +
";border-style:solid;border-color:" +
hexColorCode + " ;color:white;}");
Note: I have commented out the paintEvent virtual function.
I have gone through this link: How to Change the Background Color of QWidget and have incorporated changes like given but im unable to set color to childCustomWidget.
My custom widgets with the above approaches look like this:
Here orange is the parent's BG color which I am able to set. The grey colored one seems to be the default color for the child widget.
Solution
For Approach2 to work, i.e. for your custom widget to respect the stylesheet, the Qt::WA_StyledBackground attribute should be set to true, as it:
Indicates the widget should be drawn using a styled background.
Example
Here is a minimal example I have prepared for you in order to demonstrate a possible implementation of the suggested solution:
class ParentWidget : public QWidget
{
Q_OBJECT
public:
explicit ParentWidget(QWidget *parent = nullptr) : QWidget(parent) {}
};
class ChildWidget : public QWidget
{
Q_OBJECT
public:
explicit ChildWidget(QWidget *parent = nullptr) : QWidget(parent) {}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0) :
QMainWindow(parent)
{
auto *pWidget = new ParentWidget(this);
auto *l = new QVBoxLayout(pWidget);
auto *cWidget = new ChildWidget(pWidget);
QString BorderThickness("2");
QString hexColorCode("#FF00FF");
l->addWidget(cWidget);
l->setContentsMargins(25, 25, 25, 25);
QPalette pal(pWidget->palette());
QColor color(226, 208, 208);
pal.setColor (QPalette::Background, color);
pWidget->setAutoFillBackground (true);
pWidget->setPalette (pal);
cWidget->setAttribute(Qt::WA_StyledBackground, true);
cWidget->setStyleSheet("ChildWidget { border: " + BorderThickness + " solid " +
hexColorCode + ";"
"background-color: rgb(204, 231, 47);"
"color: white; }");
setCentralWidget(pWidget);
resize (400, 400);
}
};
Result
As it is written, this example produces the following result:
Qt docs about palette: Warning: Do not use this function in conjunction with Qt Style Sheets. When using style sheets, the palette of a widget can be customized using the "color", "background-color", "selection-color", "selection-background-color" and "alternate-background-color".
http://doc.qt.io/qt-5/qwidget.html#palette-prop
Qt docs about autoFillBackground: Warning: Use this property with caution in conjunction with Qt Style Sheets. When a widget has a style sheet with a valid background or a border-image, this property is automatically disabled.
http://doc.qt.io/qt-5/qwidget.html#autoFillBackground-prop

Can't set style sheet for a derived class from QWidget in qt [duplicate]

This question already has answers here:
Qt Stylesheet for custom widget
(6 answers)
Closed 4 years ago.
I have a derived class from QWidget, let's call it DerivedWidget. And I set the DerivedWidget in MainWindow class as central widget. I want to change the background color for the DerivedWidget, I tried many ways, it just will not work.
DerivedWidget::DerivedWidget(QWidget *parent) : QWidget(parent)
{
mBtn = new QPushButton(this); //if I have some other widgets on this, like a QPushButton
mBtn->setStyleSheet("QPushButton { background-color: red; }"); //it works for the QPushButton on this widget
//tried three ways below to set the widget bgcolor, none of them works
//first
this->setStyleSheet("QWidget { background-color: yellow; }"); //it is not working
//second
this->setObjectName("#DerivedWidget");
this->setStyleSheet("QWidget#DerivedWidget { background-color: yellow; }"); //still not working
//third
this->setStyleSheet("DerivedWidget { background-color: yellow; }"); //not working either
}
So as you can see, I can change the style sheet for the widgets on the DerivedWidget, but just can not change its background color.
I've also tried to change the DerivedWidget bgcolor in MainWindow class. Of course, I tried more than those three ways I provied, but the results are still the same. None of those methods worked. If I just create a QWidget and set it as central widget in MainWindow class, I can easily set bgcolor for that. But why can't I set bgcolor for the derived class?
Why would this happen and how can I solve this problem?
Ok, I solved this problem by re-implementing the paintEvent(QPaintEvent *) function` like:
void CustomWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
More details are here: Qt Doc and a helpful answer.

QLineEdit change text weight on activation

I want to make QLineEdit looks like QLabel with bold text if it's inactive and like QLineEdit with normal weight if active. In my understanding "active" = when text cursor shown and user can enter a text.
I tried to apply this css:
QLineEdit {
font-weight: normal;
border: 1px solid black;
}
QLineEdit:!focus {
font-weight: bold;
border: none;
}
Border works as expected, but font-weight is always bold.
I was thinking of creating my class to handle activation event, but can't found anything related with it.
I will be very thankful if somebody can help me.
You need to get your custom slot for the focusChanged event. There you can change the font like this:
QFont font = ui->lineEdit_search->font();
font.setWeight(QFont::Bold); // or
font.setWeight(QFont::Normal);
ui->lineEdit_search->setFont(font);
An example where I handled a LineEdit search box is here, but you have to customize it with the bold text.
void MainWindow::focusChanged(QWidget* old, QWidget* now)
{
if(now != NULL &&
now->objectName() == "lineEdit_search")
{
if(ui->lineEdit_search->text() == tr("Search..."))
{
ui->lineEdit_search->clear();
QPalette *palette = new QPalette();
palette->setColor(QPalette::Text,Qt::black);
ui->lineEdit_search->setPalette(*palette);
delete palette;
}
}
else if(old != NULL &&
old->objectName() == "lineEdit_search")
{
if(ui->lineEdit_search->text().isEmpty())
{
ui->lineEdit_search->setText(tr("Search..."));
QPalette *palette = new QPalette();
palette->setColor(QPalette::Text,Qt::gray);
ui->lineEdit_search->setPalette(*palette);
delete palette;
}
}
}
When you turn your line edit to inactive,
//Set your line edit to read only
yourLineEdit->setReadOnly(true);
//Get your widget background color
const QColor clr = this->palette().color(QWidget::backgroundRole());
//Set the widget background color to both the line edit background and its border
QString backGroundstyle = "background-color: rgb(%1, %2, %3);";
QString borderStyle = "border: 1px solid rgb(%1, %2, %3);";
yourLineEdit->setStyleSheet(backGroundstyle.arg(clr.red()).arg(clr.green()).arg(clr.blue()) + borderStyle.arg(clr.red()).arg(clr.green()).arg(clr.blue()));
When you turn line edit to active
//Make your line edit read-write
yourLineEdit->setReadOnly(false);
//Bring back your styles.
QString backGroundstyle_active = "background-color: white;";
QString borderStyle_active = "border: 1px solid black;";
yourLineEdit->setStyleSheet(backGroundstyle_active + borderStyle_active);

How to create a QPushButton with the text displayed over the icon?

I am trying to create a QPushButton in my project such that the text shows on top of the custom button image or icon.
I tried the below methods:
imagePath = path;
QPixmap pixmap(imagePath);
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
button->setGeometry(0,0,height,width);
button->setStyleSheet(
"background-color: gray;"
"border: 1px solid black;"
"border-radius: "+QString::number(radius)+"px;"
"color: lightGray; "
"font-size: 25px;"
);
When I try to use the setText here, it shows the icon first and text on its right. I want the text to appear on top of the icon.
I also tried the below method I found online:
imagePath = path;
button->setGeometry(0,0,height,width);
button->setStyleSheet("background-image: url(:/images/images/2adjacentTracksButton.png));"
"background-position: center center");
This one is not accepting my url path, hence is not displaying the image I need on the button.
How can I solve this?
When it comes to manipulate button, you may want to do your own class, which will implement QAbstractButton. Something like this:
class MyButton : public QAbstractButton
{
Q_OBJECT
public:
static MyButton* createButton(QIcon icon, QWidget *parent);
~MyButton();
void setText(QString);
void setIcon(eIcon);
void setOrientation(Qt::Orientation);
protected :
MyButton(QWidget *parent);
// here, you can reimplement event like mousePressEvent or paintEvent
private :
QBoxLayout* m_ButtonLayout;
QLabel* m_IconLabel;
QIcon m_Icon;
QLabel* m_TextLabel;
}
In the .cpp :
MyButton::MyButton(QWidget *parent)
: QAbstractButton(parent)
{
m_ButtonLayout = new QBoxLayout(QBoxLayout::LeftToRight, this);
m_ButtonLayout->setAlignment(Qt::AlignCenter);
m_ButtonLayout->setContentsMargins(0, 0, 0, 0);
m_ButtonLayout->setSpacing(1);
m_IconLabel = new QLabel(this);
m_IconLabel->setAlignment(Qt::AlignCenter);
m_ButtonLayout->addWidget(m_IconLabel);
m_TextLabel = new QLabel(this);
m_TextLabel->setAlignment(Qt::AlignCenter);
m_ButtonLayout->addWidget(m_TextLabel);
//m_TextLabel->hide();
}
MyButton* MyButton::createButton(QIcon icon, QWidget *parent)
{
MyButton* pButton = new MyButton(parent);
pButton->setIcon(icon);
return pButton;
}
void MyButton::setText(QString text)
{
m_TextLabel->setVisible(!text.isEmpty());
m_TextLabel->setText(text);
QAbstractButton::setText(text);
}
void MyButton::setIcon(QIcon icon)
{
m_Icon = icon;
m_IconLabel->setVisible(true);
}
void MyButton::setOrientation(Qt::Orientation orientation)
{
if (orientation == Qt::Horizontal)
m_ButtonLayout->setDirection(QBoxLayout::LeftToRight);
else
m_ButtonLayout->setDirection(QBoxLayout::TopToBottom);
}
And now you can create your button with your icon by calling the static method:
MyButton* button = MyButton::createButton(myButtonIcon, this);
It is just a basic example I gave you, and I am not sure it will work (this is a thing I did some time ago) but you can give it a shot. Hope that helps !