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.
Related
Consider the following example. It creates two instances of QComboBox: one with a stylesheet, and another without. If the first one is clicked (with widget style being Fusion), the menu is sized as expected, although padding of text is inconsistent between hovered and non-hovered items. But if you click on the second one, the padding problem is now fixed, but the menu appears to have huge entries, making the menu fill the whole screen height.
#include <QComboBox>
#include <QApplication>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QComboBox box1, box2;
const QString stylesheetOrig=R"(
QComboBox::item:selected
{
background-color: #0000ff;
}
)";
box1.setStyleSheet(stylesheetOrig);
box2.setStyleSheet(stylesheetOrig+R"(
QComboBox::item
{
padding-left: 27px;
}
)");
box1.addItems({"Hello 1","Goodbye 1"});
box2.addItems({"Hello 2","Goodbye 2"});
box1.show();
box2.show();
return app.exec();
}
If I remove the padding statement, still leaving the QComboBox::item {} part, then nothing strange (and nothing useful) happens. But if I even set the padding to 1px or 0px, the stretching already happens with all its might.
Why does setting horizontal padding result in such a strange change vertically?
Wow OK, that is screwy indeed. Adding any css to a combo box makes it go into some other "retro" mode with showing icons next to the current item. I've never noticed that in many years, but I see a bunch of common threads on the issue. Seems to only affect Fusion style though, I was confused for a while on my Windows box until I figured that out.
The question is if you want the checkbox or not. Here's one way to get rid of it, the only consistent one I found after a bit of playing with it. The main trick is setting the selection colors on the ::item and not on ::item:selected (the latter makes the checkmarks appear).
QComboBox::item {
selection-background-color: #0000ff;
selection-color: palette(highlighted-text);
}
PS. Another reason for confusion and why QComboBox::item and :checked even work is that the QComboBox default item delegate (used to draw the items in the QListView which the combo box uses for the options list) "pretends" it's a QMenu: QComboMenuDelegate::paint()
So another workaround would be to use something more sane/customizable for a delegate, perhaps even a default QStyledItemDelegate.
ADDED: A version keeping the checkbox and ensuring the unchecked items have padding (w/out using padding property which appears to be FUBAR when used in a combo box item with Fusion style). The icon size seems easiest set via iconSize property -- I tried a few ways via css icon/image/element width/height but nothing affected it... probably because the iconSize property overrides it.
QComboBox { qproperty-iconSize: 12px; } /* or QComboBox::setIconSize() */
QComboBox::indicator { color: transparent; } /* to force space for the icon column */
/* Using ::item:selected vs. ::item { selection-*-color: } will apparently make the
checkbox column appear... at least with Fusion as the main style */
QComboBox::item:selected {
color: palette(highlighted-text);
background-color: #0000ff;
}
VERSION 3 (as per comments):
QComboBox { qproperty-iconSize: 12px; } /* or QComboBox::setIconSize() */
QComboBox::indicator:!checked { border: 0; } /* to force space for the icon column */
QComboBox::item { background-color: palette(base); } /* gets rid of icon|text separator */
/* Using ::item:selected vs. ::item { selection-*-color: } will apparently make the
checkbox column appear... at least with Fusion as the main style */
QComboBox::item:selected {
color: palette(highlighted-text);
background-color: #0000ff;
}
There's still a 1px frame line at the top of the unselected icon area, though it's pretty subtle. I have no idea where that comes from... tried some guesses but to no avail.
I use JavaFX2.0 to my java application, then I use .fxml file to build my UI, then I use css to decorate button or label.
Just like:
/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
.lebel{
-fx-alignment: center ;
-fx-pref-width:20% ;
-fx-pref-height: 180 ;
-fx-background-color: transparent ;
-fx-text-fill: white ;
-fx-background-size: stretch;
-fx-padding: 0 0;
-fx-font-size: 20sp;
}
Five labels are placed horizontally, but the property -fx-pref-width:20% doesn't work on the UI. I am trying to use -fx-pref-width:% to design UI for different sizes of stage.
-fx-pref-width is defined by Region. See this.
This is the abstract from it:
Property: -fx-min-width, -fx-pref-width, -fx-max-width
Values: < number >
Default: -1
Comments: Percentage values are not useful since the actual value would be computed from the width and/or height of the Region's parent before the parent is laid out.
So, percentages are not supported. You would need to do it using code via binding perhaps.
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.
I have a two editor classes, say BaseEditor and AdvancedEditor. BaseEditor inherits from QPlaintTextEdit and its standard context menu follows my style sheet properly.
My AdvancedEditor now inherits from BaseEditor and reimplements the method void showContextMenu(const QPoint &point) to generate a custom context menu. In it I basically do the following:
void AdvancedEditor::showContextMenu(const QPoint &point)
{
QMenu* pStandardMenu = createStandardContextMenu();
QMenu* pMenu = new QMenu();
[add various stuff to pMenu]
connect(pSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(onContextMenuSelected(const QString&)));
pMenu->addSeparator();
pMenu->addActions(pStandardMenu->actions());
pMenu->exec(mapToGlobal(point));
delete pMenu;
}
This menu however is rendered in the default OS design despite me having the following part in my QSS style sheet (which is properly used for all other menus):
QMenu {
background-color: white;
border: 1px solid #4495D1;
padding: 1px;
}
I tried adding a custom paintEvent() as described here without any luck: http://qt-project.org/forums/viewthread/25664/#117575. Do I need another PE_* type?
Set pMenu's parent widget to the one which has your stylesheet.
I have a QDockWidget with a transparent background, but I would like to change the background color or background image when it is floating. It doesn't look like the qt style sheets have a pseudo state to tell you whether or not they are floating, so I'd like to know: is this possible to do?
Found the solution. Add the following connection in the code:
connect(knobDock, &QDockWidget::topLevelChanged, [&] (bool isFloating)
{
if (isFloating)
{
setAttribute(Qt::WA_TranslucentBackground, false);
setAttribute(Qt::WA_NoSystemBackground, false);
}
});
This will cause the dock widgetto use whatever background is specified in the stylesheet when the dock is floating, but it will be transparent (i.e. show the mainwindow background) when it's docked.
You can use custom properties to do this.
Thanks #phyatt for link to Dynamic Properties and Stylesheets.
To declare custom property in your custom class you can write in .cpp:
setProperty("customPropertyName", 1);
or in .h (don't forget to define and implement used get/set access methods too):
Q_PROPERTY( int customPropertyName, READ getCustomPropertyName, WRITE setCustomPropertyName);
And in your global stylesheet file you can use the state of your custom property as following:
.YourClass[customPropertyName="1"] {
background-color: transparent;
}
.YourClass[customPropertyName="2"] {
background-color: black;
}
Also it's needed to reload stylesheet of the object instance after your set new property value, because stylesheets are not recalculated automatically:
object->style()->unpolish(tstFrame);
object->style()->polish(tstFrame);
object->update();
or:
object->setStyleSheet("/* */");