Style QProgressBar when the value is 16 - qt

It is possible to style the QProgressBar using only QSS when the value is 16 example?
ui->progresso->setValue(16);
Using a QSS like this:
QProgressBar {
//Default QSS
...
}
QProgressBar:value(16) {
background-color: #fc0;
}
My goal is:
- When the QProgressBar is 0: It will use background-color: transparent
- When the QProgressBar is greater than 0: show a gray bar and the "chunk" will be blue
- When the QProgressBar is greater than 89: shows the "chunk" in red.
I can do this with QT + C++, but would like to know is it is possible to do this only with QSS?
Like this (this code does not exist, is just one example):
QProgressBar {
background-color: gray;
}
QProgressBar:value(0) {
background-color: transparent;
}
QProgressBar::chunk {
background-color: blue;
}
QProgressBar::chunk:minValue(90) {
background-color: red;
}

I think it is possible with help of Property Selector but only for exect values i.e.:
QProgressBar[value = 16]::chunk{
background-color: red;
}
but you can generate such stilesheet in code for each value
QString styleSheet;
for(int i = 0; i < 101; i++)
{
styleSheet.append(QString("QProgressBar[value = \"%1\"]::chunk{background-color: %2;}").arg(QString::number(i), (i < 17 ? "red" :"blue")));
}
myProgressBar->setStyleSheet(styleSheet);
I don't try it. It's just a theory based on documentation.
Update 1
Warning: If the value of the Qt property changes after the style sheet has been set, it might be necessary to force a style sheet recomputation. One way to achieve this is to unset the style sheet and set it again.

This is not possible.
The only valid extensions are in the documentation and too long to post here.
However you could handle the valueChanged( int ) signal of the QProgressBar
and set the stylesheet accordingly using setStyleSheet( ) but I figure you already know that.

Related

How to setStyleSheet for QLabel in a specific class in Qt

I have a testing sample like this:In class B, which only has a QVector to store some QLabel like this:
class B : public QWidget
{
public:
B(QWidget *parent = 0);
QVector<QLabel*> mLbls;
};
And in class A, I have the following code:
A::A(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mWidget = new QWidget(this);
QHBoxLayout *hLayout = new QHBoxLayout(mWidget);
B testingB;
testingB.mLbls.resize(5);
for(int i = 0; i < 5; i++) {
testingB.mLbls[i] = new QLabel(mWidget);
testingB.mLbls[i]->setText(QString::number(i));
hLayout->addWidget(testingB.mLbls[i]);
}
setStyleSheet("QLabel {background-color: red;}"); //I want to set the QLabel bg color to red
mWidget->setLayout(hLayout);
setCentralWidget(mWidget);
}
So what I am trying to do is set all QLabel that ONLY in Class B to red color. But the problem is, if I use setStyleSheet("QLabel {background-color: red;}");, all the QLabel(even the QLabel in Class A) will be set to red background color.
I do not know how to set all the stylesheet only for CLass B object. And I know I could use this way to implement what I am trying to do:
for(int i = 0; i < 5; i++) {
testingB.mLbls[i] = new QLabel(mWidget);
testingB.mLbls[i]->setText(QString::number(i));
testingB.mLbls[i]->setStyleSheet("QLabel {background-color: red;}"); //new added
hLayout->addWidget(testingB.mLbls[i]);
}
By using that way, I think that so troublesome to set stylesheet for them one by one individually, besides sometimes I may need to set some QLabel stylesheet differently and the rest of them just have the same stylesheet. If I have more objects and set each of them one by one, that may cost a lot of time.So I assume there is a way to set stylesheet for some objects in a class once for all. Hope that I explain my question clearly. To solve that problem, what can I do? Thanks.
Qt CSS syntax allows you to select children for the CSS rules (Qt doc), but it is based on the parentship of QObjects not in which class contains pointers to the QLabel.
This CSS will only apply to QLabel objects which are children or grand children of a YourContainerClassWidget object.
// C++
auto container = new YourContainerClassWidget;
auto label = QLabel(container); // The label is now a child of container
// CSS
YourContainerClassWidget QLabel { // Descendant selector
background-color: red;
}
// You can also apply only to direct children with this syntax
YourContainerClassWidget > QLabel { // Child selector
background-color: red;
}

How to center a QProgressBar's chunk?

I have this audio viewer that, for lack of a better widget, uses QProgressBars to display the overall volume and the volume of each RTA bin, in addition to selecting a range of "interesting" bins:
The parent widget has a stylesheet of "background-color: DimGray;"; I don't know if that has anything to do with the problem or not. The progressbars themselves are set up like this:
AudioMeter::AudioMeter(..., QWidget* parent) :
QWidget(parent)
{
...
meter = new QProgressBar(this);
meter->setOrientation(Qt::Vertical);
meter->setFormat("");
meter->setGeometry(...);
meter->setRange(FixedPoint::Zero, FixedPoint::One);
}
and used like this:
void AudioMeter::setValue(int value)
{
meter->setValue(value);
}
The problem is that the chunks (in light blue) seem to be offset to the left by a few pixels and up by one or two, so it just doesn't look right. This is true on Lubuntu 16.04 LTS (pictured) and on Ubuntu 16.04 LTS. How can I center them?
Or if there's a better widget to use (with straightforward code, not a custom thing with 20 re-implemented methods like I've seen in some examples), I'm open to that too.
http://doc.qt.io/qt-4.8/stylesheet-examples.html#customizing-qprogressbar
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar
http://doc.qt.io/qt-5/stylesheet-customizing.html#the-box-model
https://www.w3schools.com/css/css_padding.asp
It looks like the right padding is probably off for some reason.
// try this and see if it helps
meter->setStyleSheet("padding: 0;");
// or just zero out the right padding
meter->setStyleSheet("padding-right: 0;");
If not, you will probably need to do some iterations of stylesheet editing...
Use a stylesheet.css file in the same path as your program:
http://doc.qt.io/qt-5/qapplication.html#QApplication
-stylesheet= stylesheet, sets the application styleSheet. The value must be a path to a file that contains the Style Sheet.
So you run your program with
meters -stylesheet=./stylesheet.css
and fill in stylesheet.css with:
QProgressBar {
/* attempt at fix by removing all padding */
padding: 0;
/* Another style to try out sometime:
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
}
QProgressBar::chunk {
background-color: #05B8CC;
width: 20px;
}*/
}
I've also done prototyping of stylesheets by connecting it's reload to an application wide hotkey or a pushbutton in your program.
QString stylesheet;
QFile f("stylesheet.css");
if (f.open(QFile::ReadOnly | QFile::Text))
{
QTextStream in(&f);
stylesheet = in.readAll();
}
qApp->setStyleSheet(stylesheet);
qApp->style()->unpolish(qApp);
qApp->style()->polish(qApp);
Hope that helps.

Qt QCalendarWidget QSS Styling

I know there's no support for QCalendarWidget QSS styling but does anyone know some workarounds for changing the color of sections 1 and 2 of the QCalendarWidget? (the light blue for section 1 and white for section 2)
Thanks!
I've examined QCalendarWidget source code and found the solution.
QCalendarWidget internally has a model and a view to display days. QCalendarModel has a formatForCell(int, int) function that returns QTextCharFormat for a given cell. Returning format is the result of merging QCalendarView palette data, a format for current day (saturday and sunday are shown in red) and a format for current date, which can be set using QCalendarWidget::setDateTextFormat function.
Actually an item's background is:
format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base));
pal is a QCalendarView's palette;
cg is a color group;
header is true when the current cell is a header cell (section 1 in your example)
So, all you need is to set your custom palette to that internal QCalendarView. In the source code we can find that QCalendarView object has a name "qt_calendar_calendarview" which we can use:
QCalendarWidget *c = new QCalendarWidget;
QTableView *view = c->findChild<QTableView*>("qt_calendar_calendarview");
if (view)
{
QPalette pal = view->palette();
pal.setColor(QPalette::Base, Qt::red);
pal.setColor(QPalette::AlternateBase, Qt::green);
view->setPalette(pal);
}
In my example section 1 will be red and section 2 will be green.
Additionally you can set colors for every color group of you palette to get the widget you like when it's active, inactive etc.
Area "1" customization:
QTextCharFormat format;
format.setForeground(QBrush(Qt::blue));
format.setBackground(QBrush(Qt::red);
ui->calendarWidget->setHeaderTextFormat(format);
Area "2" QSS CSS:
QCalendarWidget QAbstractItemView
{
background-color: rgb(192,192,192); /* цвет фона текущего месяца */
selection-background-color: yellow; /* цвет фона выбранного дня */
selection-color: black; /* цвет текста выбранного дня */
}
or
#qt_calendar_calendarview
{
background-color: rgb(192,192,192); /* цвет фона текущего месяца */
selection-background-color: yellow; /* цвет фона выбранного дня */
selection-color: black; /* цвет текста выбранного дня */
}
, where #qt_calendar_calendarview - object's name from d->m_view->setObjectName(QLatin1String("qt_calendar_calendarview")); in qcalendarwidget.cpp

How do you remove the border from a QPushButton?

I have some QPushButtons in the rows of a QTreeView, and they're showing up with these black borders around them that I can't seem to modify. Currently I can grey out the buttons with this code:
for (int i = 0; i < QPalette::NColorRoles; i++){
QPalette::ColorRole thisRole = static_cast<QPalette::ColorRole>(i);
QColor newColor = commitPalette.color(QPalette::Disabled,thisRole);
int grayColor = qGray(newColor.rgb());
newColor.setRgb(grayColor,grayColor,grayColor,50);
commitPalette.setColor(QPalette::Disabled, thisRole, newColor);
}
But it doesn't do anything to the border. I'd prefer to avoid using stylesheets, as I like the automatic color generation provided by QPalette's constructor
If you are using Qt creator, right click the QPushButton and setStyleSheet as border: none; Thats it.
If you set the QButton property isFlat = true it should disable the border unless it's being clicked.
I suggest using a stylesheet. From the code you can make it to a function:
void setFlatStyle(QPushButton *btn)
{
btn->setStyleSheet(QString("QPushButton {border: 0px;}"));
}
Just pass the button in there and get your result.
button.setStyleSheet("QPushButton { border: none; }")
As said #RajaRaviVarma

Property selectors in QT CSS

I have a tree widget that I'm using for a user/room concept. How can I style the rooms independently from the users in the rooms? I'm assuming it has something to do with QT's property selector in CSS? I would like to be able to do this:
QTreeView::item[isUser="true"] { background: blue; }
QTreeView::item[isRoom="true"] { background: red; }
Since the items in a model are not QObjects (nor QWidgets), you will not be able to add a property to the item, or style them with stylesheets.
I have two suggestions for doing what you want to do :
1) (C++ only) Attach your QTreeView to a QStandardItemModel, and when you add items as QStandardItem objects, you can call QStandardItem::setBackground() with either Qt::blue or Qt::red depending of whether the item is a room or a user.
2) (C++ and CSS) Define a QStyledItemDelegate that you attach to your QTreeView. In your reimplementation of QStyledItemDelegate::paint() method, use a QLabel to display the content of the item, then set a property on that QLabel. You will then be able to use a stylesheet to customize the look of the label :
QLabel[isUser="true"] { background: blue; }
QLabel[isRoom="true"] { background: red; }
I was able to accomplish what I needed by creating a label, using the setProperty method on that label, and then using the setItemWidget function to attach that QLabel to the appropriate QTreeWidgetItem. So I wouldn't be "styling the QTreeWidgetItem", but rather styling the QLabel that was overlayed on top of the QTreeWidgetItem. The following example sets my topLevelItem in the QTreeWidget to be ready to be styled as a room:
QTreeWidgetItem *topItem = ui->treeWidget->topLevelItem(0);
currentLabel = new QLabel;
currentLabel->setProperty("room",true);
currentLabel->setText(QString("Room Lobby"));
ui->treeWidget->setItemWidget(topItem,0,currentLabel);`
I can then select it in the stylesheet with
QLabel[room="true"] { background: red; }

Resources