Set color of tabified QDockWidget tabs - c++

I am creating a QDockWidget, and I want it's tabs(when tabified) or title bar(when not tabified) to flash between two colors.
I am currently doing the following, but only the body flashes between two colors:
//Setup the array of styles for the flash:
std::array<const char*, 2> flashStyles = {
" background-color: lightblue; color: black;",
" background-color: orange; color: black; "
};
//Setup the timer and kick it off:
connect(m_flashTimer, &QTimer::timeout, [=]()
{
//Perform the flash by alternating the background:
setStyleSheet(flashStyles[
m_pass == 0 ? m_pass++ : m_pass--
]);
update();
});
I can't seem to find any properties that would allow me to change the tab color / title bar color. Do I need to set the tab color properties somewhere else?

You need to find out which Widget is used internally by QDockWidget to display tabs. Then use the appropriate styles with the correct selector. Probably you need to select a QTabBar which is a descendant of QDockWidget. This could look like:
QDockWidget QTabBar {}
Maybe these links can also help you:
http://doc.qt.io/archives/qt-4.8/stylesheet-syntax.html
http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qdockwidget
http://doc.qt.io/archives/qt-4.8/stylesheet-reference.html

Related

How to change the background color of the QTableWidget's vertical header?

I would like to change the colors of a QTableWidget. I am almost getting the result I like, but two areas in the vertical header remain white:
Before writing this post I actually managed to color also the upper left corner, but not the other area. Here is the stylesheet I am using:
QTableCornerButton::section {
background-color: #8b8d8e;
}
QHeaderView::section {
color: white;
background-color: #747678;
gridline-color: #747678;
}
Finally found the answer myself:
/*The top-left area is actually a button:*/
QTableCornerButton::section {
background-color: #8b8d8e;
}
/*The lower part of the vertical header:*/
QHeaderView {
background-color: #8b8d8e;
}
The original css I posted (QHeaderView::section) referred only to the header entries, not the header itself.

Change QGroupBox's content background

I want to change the background of a QGroupBox, however I would like to only change the inside background (the darker shade of gray below each QGroupBox's title) as shown here:
What I currently have is
QGroupBox {
background-color: red;
border: 3px dashed black;
}
which changes the background of the entire QGroupBox like this:
Is there a way in Qt to only change the "interior box" background rather than the whole container? Thank you in advance.
I guess there are 2 QGroupBox'es involved here, since that is not really clear from your post. Or is there a group box and some other inner container widget?
In either case you should be able to use stylesheets like following:
QGroupBox {
background-color: red;
margin-top:1em;
}
QGroupBox QGroupBox {
background-color: green;
}
QGroupBox::title {
subcontrol-origin: padding;
subcontrol-position: left top;
background: transparent;
margin-top: -2.5em;
}
This will give you following result:
You can of course replace the inner group box by an arbitrary widget.
You can do it using "setStyleSheet" function of widgets.
Get the inner group box object. And set the background color using "setStyleSheet" function.
Pseudo Code:
QGroupBox *innerGBox = new QGroupBox();
innerGBox->setStyleSheet("background-color: red");
To know more about setting styles programmatic , refer below link.
http://doc.qt.io/qt-4.8/stylesheet-examples.html
You need to tell Qt a little more about the kind of style you want, specifically the margins. Playing around a little with this code should give you the desired results:
QGroupBox {
background-color: red;
border: 3px dashed black;
margin-top: 1ex; /* leave space at the top for the title */
}
QGroupBox::title {
subcontrol-origin: margin;
padding: 0 3px;
}
Take a look at the Stylesheet examples

QTreeWidget border radius toggles visibility during scrolling when set alternating row colors

I am trying to design a QTreeWidget with border-radius. The problem sets in when I assign alternate row colors to it. When I don't, it works fine, and the border-radius around the widget is always visible during scrolling. However, when I scroll with the alternate row colors set, during even numbered rows being at the top and bottom, the border-radius remains as expected, while during odd numbered ones, they are eclipsed, with the look and feel of a widget with no border-radius. Here's what it looks like when the grey colored rows are at the top and bottom:
And after you scroll one unit, or odd number of units, so that the white colored rows are at the ends, this is what it looks like:
How do I fix this? And in Windows, because the scrollbars are differently styled, the right side will always have the border radius eclipsed due to the scroll pane. Is there a way to make it behave just like the Mac scrollbar?
My style sheet is pretty minimal:
#myTreeWidget {background-color: #C2C7CB; border-radius: 8px; }
I set the width of the rows through a delegate:
class ItemDelegate : public QItemDelegate
{
public:
ItemDelegate()
{}
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
return QSize(240,25);
}
};
ItemDelegate *delegate = new ItemDelegate();
myTreeWidget = new QTreeWidget(this);
myTreeWidget->setObjectName(QString::fromUtf8("myTreeWidget"));
myTreeWidget->setAttribute(Qt::WA_MacShowFocusRect,false);
myTreeWidget->setGeometry(QRect(20, 10, 240, 375));
myTreeWidget->headerItem()->setHidden(true);
myTreeWidget->setItemDelegate(delegate);
myTreeWidget->setAlternatingRowColors(true);
I just observed a weird thing. If I remove the background color from the widget, the border radius completely disappears. Not visible under any circumstance!

Qt Custom widget with overlapping subwidgets

I'm trying to make a custom widget in Qt5 which is sort of like a QProgressBar but with 3 sliders and user movable: (slightly broken JS implementation: codepen, gist)
I'm having issues working out quite how to do this. My attempts have failed to either render all the parts of the widget correctly (making it very difficult to select and move different parts of it) or not working correctly with a VBoxLayout (doesn't expand to fit the horizontal space)
My latest attempt (you should be able to get the general idea from the constructor, nothing else was implemented)
UTrackSlider::UTrackSlider(QWidget *parent) : QWidget(parent)
{
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
// CIRCLE_HEIGHT = 10
// BACKGROUND_HEIGHT = 30
/// #todo css should be in global stylesheet
background = new QLabel(this);
background->setMinimumHeight(this->BACKGROUND_HEIGHT);
background->setStyleSheet("QLabel{ border: 1px solid gray; background-color:white; border-radius:2px}");
background->setAttribute(Qt::WA_DeleteOnClose);
cue = new QLabel(this);
cue->setFixedSize(QSize(this->CIRCLE_HEIGHT, this->CIRCLE_HEIGHT));
cue->setStyleSheet("QLabel:hover{ border: 2px solid #d9534f; border-radius:5px}");
cue->setAttribute(Qt::WA_DeleteOnClose);
duration = new QLabel(this);
duration->setFixedSize(3, this->BACKGROUND_HEIGHT);
duration->setStyleSheet("QLabel{border: 3px solid #2376bb} QLabel:hover{border: 5px solid #2376bb}");
duration->setAttribute(Qt::WA_DeleteOnClose);
intro = new QLabel(this);
intro->setFixedSize(QSize(this->CIRCLE_HEIGHT, this->CIRCLE_HEIGHT));
intro->setStyleSheet("QLabel:hover{ border: 2px solid #5bc85c; border-radius:5px}");
intro->setAttribute(Qt::WA_DeleteOnClose);
QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(cue, 5, 0);
mainLayout->addWidget(background, 0, this->CIRCLE_HEIGHT);
mainLayout->addWidget(duration, 2, this->CIRCLE_HEIGHT);
mainLayout->addWidget(intro, 5, this->CIRCLE_HEIGHT + this->BACKGROUND_HEIGHT);
this->setLayout(mainLayout);
}
Basically, any pointers about how I should structure this composite widget such that it works in all these conditions?
EDIT: After discussing the issue with some people on #qt , i've come to the conclusion that I must override paintEvent. But this also means overriding some other functions to do the onClick and dragging effects, and I've got no idea where to start
You're right, you have to re-implement
1.void paintEvent(QPaintEvent *)
2.void mouseMoveEvent(QMouseEvent *)
3.void mousePressEvent(QMouseEvent *)
4.void mouseReleaseEvent(QMouseEvent *)
of QWidget.
In order to handle the mouse event correctly, you may use QCoreApplication::sendEvent(QObject *, QEvent *) to pass the event to the target widget.
Here's an example:
https://github.com/Serge45/MultiSlider
In this example, I create three widgets(ColorSlider) in a container widget, and then use a linked list to propagate the mouse event correctly.

How to change the color of the text of a QProgressBar with its value?

I don't know how to change the color of the text partially in the progress bar when its value becomes nearly 50%. This effect comes automatically in the fusion style progress bar (picture below). Does anyone know how this is done ?
Too lazy to write working example code, much less making a screenshot. Not even for 50 reps. :-)
However, the question was somewhat interesting. I had no idea how such a two colored text could be done. So I checked:
http://qt.gitorious.org/qt/qtbase/blobs/stable/src/widgets/styles/qfusionstyle.cpp
Line 1450ff (http://qt.gitorious.org/qt/qtbase/blobs/stable/src/widgets/styles/qfusionstyle.cpp#line1450).
QRegion rightRect = rect;
rightRect = rightRect.subtracted(leftRect);
painter->setClipRegion(rightRect);
painter->setPen(flip ? alternateTextColor : textColor);
painter->drawText(rect,
bar->text,
QTextOption(Qt::AlignAbsolute|
Qt::AlignHCenter|
Qt::AlignVCenter));
if (!leftRect.isNull())
{
painter->setPen(flip ? textColor : alternateTextColor);
painter->setClipRect(leftRect);
painter->drawText(rect,
bar->text,
QTextOption(Qt::AlignAbsolute|
Qt::AlignHCenter|
Qt::AlignVCenter));
}
Basically the text is drawn two times into the same rectangle. Each time with an appropriate clipping. Easy if you know how. :-)
From my point of view the best, and probably the easiest, way to do this is to change the pallet for the QProgressBar widget:
QPalette palette = progressBar->palette()
palette.setColor(QPalette::Text, textColor)
palette.setColor(QPalette::HighlightedText, textColor)
progressBar->setPalette(palette)
"The setBackgroundRole method let you use a color role for the background, which means one of the predefined color of the style applied to the widget. So your are basically limited to the style and its colors."
Background solution:
value = 65
self.progressBar.setProperty("value", value)
if value < 50:
self.progressBar.setStyleSheet("QProgressBar::chunk { background-color: black; }")
else:
self.progressBar.setStyleSheet("QProgressBar::chunk { background-color: black; } QProgressBar { color: white; }")
You can use stylesheet on the Container Widget :
myMainWidget.setStyleSheet(QString("QProgressBar {color: red}"));